[研究][JavaScript] 用 idle-timer.js ( jQuery Idle Timer Plugin v1.1.1 2020-06-25 版) 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗
2020-11-17
環境 Visual Studio 2019 v16.8.1 版 + C# + ASP.NET + WebForm
NuGet 要安裝數個套件,jQuery, BootStrap, popper, moment,不確定是否可缺。
敝人測試用 BootStrap 3.5.1 或 4.x 都可以用。
jQuery Idle Timer Plugin 要手動下載,把 idle-timer.js 拿過來用 ( 一個檔案就好)
https://github.com/thorst/jquery-idletimer
Download
Compressed ~3kb
https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js
Uncompressed ~11kb
https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.js
不要下載 src 目錄下的 idle-timer.js,那個不是。
根據下面網址,jQuery Idle Timer Plugin 目前為 v1.1.1 2020-06-25 版
https://raw.githubusercontent.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication9.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <%--相依性可能影響順序先後,但這個順序可用--%> <script src="Scripts/jquery-3.5.1.js"></script> <script src="Scripts/idle-timer.js"></script> <link href="Content/bootstrap.css" rel="stylesheet" /> <script src="Scripts/popper.js"></script> <script src="Scripts/bootstrap.js"></script> <script src="Scripts/moment.js"></script> </head> <body> <form id="form1" runat="server"> <div class="container"> <h2>Concept</h2> <p> Wait 10 seconds, you will see a expiring warning. Wait 10 more seconds and you will see that you have been logged out. </p> </div> <div class="modal fade" id="mdlExpirationWarning" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Session Expiration Warning</h5> </div> <div class="modal-body"> <p>You've been inactive for a while. For your security, we'll log you out automatically. Click "Stay Online" to continue your session. </p> <p> Your session will expire in <span class="bold" id="sessionSecondsRemaining">120</span> seconds. </p> </div> <div class="modal-footer"> <button id="extendSession" type="button" class="btn btn-primary" data-dismiss="modal"> Stay Online</button> <button id="logoutSession" type="button" class="btn btn-secondary">Logout</button> </div> </div> </div> </div> <div class="modal fade" id="mdlLoggedOut" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">You have been logged out</h5> </div> <div class="modal-body"> <p>Your session has expired.</p> </div> </div> </div> </div> </form> <script> // You could pull this out to its own file very easily window.app = window.app || {}; app.session = { //Settings warningTimeout: 10000, //(ms) The time we give them to say they want to stay signed in inactiveTimeout: 20000, //(ms) The time until we display a warning message minWarning: 5000, //(ms) If they come back to page (on mobile), The minumum amount, before we just log them out timerSyncId: "SomethingUnique", //The key idleTimer will use to write to localStorage logoutUrl: "/logout", //Your url to log out, if you want you could build the url to pass a referal param keepAliveUrl: "api/user/KeepAlive", // The url for the keepalive api keepaliveInterval: 5000, //(ms) the interval to call keep alive url //From here down you shouldnt have to alter anything warningStart: null, //Date time the warning was started warningTimer: null, //Timer running every second to countdown to logout keepaliveTimer: null, //Timer for independent ping to keep session alive logout: function () { //Write to storage to tell other tab its time to sign out if (typeof (localStorage) !== "undefined") { localStorage.setItem(app.session.timerSyncId, 0); } //Send this page to the logout url, that will destroy session and forward to login //window.location = app.session.logoutUrl; //To simulate logout we are just showing the logout dialog and locking the screen $("#mdlExpirationWarning").modal("hide"); $("#mdlLoggedOut").modal("show"); }, keepAlive: function () { //Hide logout modal $("#mdlExpirationWarning").modal("hide"); //Clear the timer clearTimeout(app.session.warningTimer); app.session.warningTimer = null; //Restart the idleTimer $(document).idleTimer("reset"); }, startKeepAliveTimer: function () { // Basically I just poll the server half way through the session life // to make sure the servers session stays valid clearTimeout(app.session.keepaliveTimer); app.session.keepaliveTimer = setInterval(function () { app.session.sendKeepAlive(); }, (app.session.inactiveTimeout / 2)); }, sendKeepAlive: function () { // Write a new date to storage so any other tabs are informed that this tab // sent the keepalive if (typeof (localStorage) !== "undefined") { localStorage.setItem(app.session.timerSyncId + "_keepalive", +new Date()); } // The actual call to the keep alive api //$.post(app.session.keepAliveUrl).fail(function (jqXHR) { // if (jqXHR.status == 500 || jqXHR.status == 0) { // app.session.logout(); // } //}); }, showWarning: function (obj) { //Get time when user was last active var diff = (+new Date()) - obj.lastActive - obj.timeout, warning = (+new Date()) - diff; // Destroy idleTimer so users are forced to click the extend button $(document).idleTimer("pause"); //On mobile js is paused, so see if this was triggered while we were sleeping if (diff >= app.session.warningTimeout || warning <= app.session.minWarning) { app.session.logout(); } else { //Show dialog, and note the time $('#sessionSecondsRemaining').html(Math.round((app.session.warningTimeout - diff) / 1000)); $("#mdlExpirationWarning").modal("show"); app.session.warningStart = (+new Date()) - diff; //Update counter downer every second app.session.warningTimer = setInterval(function () { var remaining = Math.round((app.session.warningTimeout / 1000) - (((+new Date()) - app.session.warningStart) / 1000)); if (remaining >= 0) { $('#sessionSecondsRemaining').html(remaining); } else { app.session.logout(); } }, 1000) } }, localWrite: function (e) { if (typeof (localStorage) !== "undefined" && e.originalEvent.key == app.session.timerSyncId && app.session.warningTimer != null) { // If another tab has written to cache then if (e.originalEvent.newValue == 0) { // If they wrote a 0 that means they chose to logout when prompted app.session.logout(); } else { // They chose to stay online, so hide the dialog app.session.keepAlive(); } } else if (typeof (localStorage) !== "undefined" && e.originalEvent.key == app.session.timerSyncId + "_keepalive") { // If the other tab sent a keepAlive poll to the server, reset the time here so we dont send two updates // This isnt really needed per se but it will save some server load app.session.startKeepAliveTimer(); } } }; $(function () { //This will fire at X after page load, to show an inactive warning $(document).on("idle.idleTimer", function (event, elem, obj) { app.session.showWarning(obj); }); //Create a timer to keep server session alive, independent of idleTimer app.session.startKeepAliveTimer(); //User clicked ok to extend session $("#extendSession").click(function () { app.session.keepAlive(); //Remove the warning dialog etc }); //User clicked logout $("#logoutSession").click(function () { app.session.logout(); }); //Set up the idleTimer, if inactive for X seconds log them out $(document).idleTimer({ timeout: app.session.inactiveTimeout - app.session.warningTimeout, timerSyncId: app.session.timerSyncId }); // Monitor writes by other tabs $(window).bind("storage", app.session.localWrite); }); </script> </body> </html> |
Default.aspx.cs (不用特別去修改)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication1 { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } } } |
Web.Config (預設 20 分鐘,可以不用特別去設定)
<configuration> <system.web> <sessionState timeout="20"></sessionState> </system.web> </configuration> |
(下圖)執行結果,等10秒就會出現
「Stay Online」按鈕按下去,會再多 10 秒可用。
(完)
相關
[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-timeout-dialogjs-session.html
[研究][C#][ASP.NET][WebForm] Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-sessionn-time-out.html
[研究][C#][ASP.NET][WebForm] Master Page 的 Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-master-page-sessionn.html
沒有留言:
張貼留言