セッションがタイムアウト(10分と言います)に達したときにポップアップ/レイヤー/アラートを発生させる必要があるasp.netサイトがあります。ポップアップには、非アクティブのためにアカウントセッションが期限切れになることが示され、セッションを続行するためのボタンまたはログアウトするためのボタンがあります。
これをオンラインで行うにはさまざまな方法がありますが、これを処理するための最良/適切な方法は何ですか?ポップアップが長すぎる場合、追加のタイムアウトを設定する必要がありますか?
この記事を確認してください。これには、要件に必要なものがすべて含まれています
<script language="javascript" type="text/javascript">
var sessionTimeoutWarning =
"<%= System.Configuration.ConfigurationSettings.AppSettings
["SessionWarning"].ToString()%>";
var sessionTimeout = "<%= Session.Timeout %>";
var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
setTimeout('SessionWarning()', sTimeout);
function SessionWarning() {
var message = "Your session will expire in another " +
(parseInt(sessionTimeout) - parseInt(sessionTimeoutWarning)) +
" mins! Please Save the data before the session expires";
alert(message);
}
</script>
これは以前に対処されています。 ASP.NET-web.configのsessionState timeOutに基づくJavaScript timeOut警告
しかし、私の知る限り、これを行うための完全に信頼できる方法はありません。
私は Pranay Rana の post の記事を見に行きましたが、私は一般的な考えが好きですが、コードはいくつかの合理化を使用できます。これが私のバージョンです。タブレット/モバイルの問題については、以下をご覧ください:
<script language="javascript" type="text/javascript">
var minutesForWarning = 4;
var sessionTimeout = parseInt("@Session.Timeout"); // razor syntax, otherwise use <%= Session.Timeout %>
var showWarning = true;
function SessionWarning() {
showWarning = false;
alert("Your session will expire in " + minutesForWarning + " mins! Please refresh page to continue working.");
// leave a second for redirection fct to be called if expired in the meantime
setTimeout(function () { showWarning = true; }, 1000);
}
function RedirectToWelcomePage() {
if (showWarning)
alert("Session expired. You will be redirected to welcome page.");
document.getElementById('logoutForm').submit();
// window.location = "../Welcome.aspx"; // alternatively use window.location to change page
}
setTimeout('SessionWarning()', (sessionTimeout - minutesForWarning) * 60 * 1000);
setTimeout('RedirectToWelcomePage()', sessionTimeout * 60 * 1000);
</script>
まあ、タブレットや携帯電話では、デバイスがロックされているかブラウザがアクティブでないときにJavaScriptの実行が一時停止されるため、setTimeoutを期待することはできません。代わりに、私は定期的なチェックを行っています(私の場合、10秒ごとに十分であると考えています)。
<script language="javascript" type="text/javascript">
function addMinutes(date, minutes) {
return new Date(date.getTime() + minutes * 60 * 1000);
}
function remainingMinutes(date) {
return Math.round((date - (new Date()).getTime()) / 60 / 1000);
}
var minutesForWarning = 5;
var sessionTimeout = parseInt("@Session.Timeout");
var showWarning = true;
var showRedirect = true;
var timeToWarn = addMinutes(new Date(), sessionTimeout - minutesForWarning);
var timeToEnd = addMinutes(new Date(), sessionTimeout);
function CheckTime() {
if (showWarning && new Date() > timeToWarn && new Date() < timeToEnd) {
showRedirect = false;
showWarning = false;
alert("Your session will expire in " + remainingMinutes(timeToEnd)) + " mins! Please refresh page to continue working.");
}
if (new Date() > timeToEnd) {
if (showRedirect)
alert("Session expired. You will be redirected to welcome page ");
document.getElementById('logoutForm').submit();
// window.location = "../Welcome.aspx"; // alternatively use window.location to change page
}
if (showRedirect == false)
showRedirect = true;
}
setInterval(CheckTime, 10000);
</script>
以下は、ASP.NETフォーム認証のタイムアウトについてユーザーに警告し、タイムアウトに達した場合にログインページにリダイレクトするjQueryを含むJavaScriptの一部です。それは改善され、セッションタイムアウトにも適合します。また、ユーザーがクリック、入力、またはサイズ変更してページを操作するたびに、サーバーに「ping」することで認証タイムアウトをリセットします。
これは、クリック、キープレス、サイズ変更のたびにpingを実行することによってサーバーに負荷を追加しますが、それはごくわずかです。それでも、多くのユーザーが入力している場合は、影響を評価する必要があります。タイムアウトが発生しているため、サーバーが関与する必要があるため、これを行う別の方法は考えられませんでした。
また、JSではタイムアウトがハードコードされていないことにも注意してください。サーバーからのタイムアウトを取得するので、Web.configの1つの場所でそれを維持するだけで済みます。
(function ($, undefined) {
if (!window.session) {
window.session = {
monitorAuthenticationTimeout: function (redirectUrl, pingUrl, warningDuration, cushion) {
// If params not specified, use defaults.
redirectUrl = redirectUrl || "~/Account/Login";
pingUrl = pingUrl || "~/Account/Ping";
warningDuration = warningDuration || 45000;
cushion = cushion || 4000;
var timeoutStartTime,
timeout,
timer,
popup,
countdown,
pinging;
var updateCountDown = function () {
var secondsRemaining = Math.floor((timeout - ((new Date()).getTime() - timeoutStartTime)) / 1000),
min = Math.floor(secondsRemaining / 60),
sec = secondsRemaining % 60;
countdown.text((min > 0 ? min + ":" : "") + (sec < 10 ? "0" + sec : sec));
// If timeout hasn't expired, continue countdown.
if (secondsRemaining > 0) {
timer = window.setTimeout(updateCountDown, 1000);
}
// Else redirect to login.
else {
window.location = redirectUrl;
}
};
var showWarning = function () {
if (!popup) {
popup = $(
"<div style=\"text-align:center; padding:2em; color: black; font-color: black; background-color:white; border:2px solid red; position:absolute; left: 50%; top:50%; width:300px; height:120px; margin-left:-150px; margin-top:-90px\">" +
"<span style=\"font-size:1.4em; font-weight:bold;\">INACTIVITY ALERT!</span><br/><br/>" +
"You will be automatically logged off.<br/><br/>" +
"<span style=\"font-size:1.4em; font-weight:bold;\" id=\"countDown\"></span><br/><br/>" +
"Click anywhere on the page to continue working." +
"</div>")
.appendTo($("body"));
countdown = popup.find("#countDown");
}
popup.show();
updateCountDown();
};
var resetTimeout = function () {
// Reset timeout by "pinging" server.
if (!pinging) {
pinging = true;
var pingTime = (new Date()).getTime();
$.ajax({
type: "GET",
dataType: "json",
url: pingUrl,
}).success(function (result) {
// Stop countdown.
window.clearTimeout(timer);
if (popup) {
popup.hide();
}
// Subract time it took to do the ping from
// the returned timeout and a little bit of
// cushion so that client will be logged out
// just before timeout has expired.
timeoutStartTime = (new Date()).getTime();
timeout = result.timeout - (timeoutStartTime - pingTime) - cushion;
// Start warning timer.
timer = window.setTimeout(showWarning, timeout - warningDuration);
pinging = false;
});
}
};
// If user interacts with browser, reset timeout.
$(document).on("mousedown mouseup keydown keyup", "", resetTimeout);
$(window).resize(resetTimeout);
// Start fresh by reseting timeout.
resetTimeout();
},
};
}
})(jQuery);
ページがロードされたら、上記を1回呼び出すだけです。
window.session.monitorAuthenticationTimeout(
"/Account/Login", // You could also use "@FormsAuthentication.LoginUrl" in Razor.
"/Account/Ping");
サーバーでは、残り時間を返すアクションが必要です。さらに情報を追加することもできます。
public JsonResult Ping()
{
return Json(new {
timeout = FormsAuthentication.Timeout.TotalMilliseconds
},
JsonRequestBehavior.AllowGet);
}
ここではクライアントサイドテクノロジーを使用する必要があります(JavaScript)。たとえば、JavaScriptタイムアウト機能を使用して警告を表示します。ユーザーが[OK]をクリックした場合、セッションを維持するために何かを行う必要がある場合があります。私はjquery.ajaxメソッドを使用してサーバーに呼び出しを行うことをお勧めします-セッションを生き続けるためだけにダミーの呼び出しにすることができます。
スライド式の有効期限を使用している場合は、jqueryとsetinterval関数を使用してAjaxポストをバックグラウンドで実行し、タイムアウトを更新するか、セッションの開始時間を記録して有効期限から減算することで、残り時間の値を取得できます。
あなたができることは、メッセージを発するためにいくつかのJavaScriptを使用することです。タイマーを使用して、特定の期間(アプリケーションでセッションタイムアウトに設定された期間-数分)の後に起動します。
その期間が過ぎたら、セッションがタイムアウトすることをユーザーに確認ダイアログを表示します。ユーザーがセッションを維持するためにクリックした場合。セッションが失われないように、ページにダミーのポストバックを作成します。また、AJAXを呼び出して、ユーザーがページの再読み込みを確認せず、入力データを失うようにすることもできます。