【问题标题】:Javascript caching issue with railsRails 的 Javascript 缓存问题
【发布时间】:2016-09-01 23:48:03
【问题描述】:

我已经安装了gem 'auto-session-timeout' 来自动让用户退出非活动会话。我想在会话超时前给用户一个 2 分钟的警告

我在 application.html.erb 中添加了以下内容

 <%= javascript_tag do %>
       var d = new Date('<%= session[:auto_session_expires_at] %>');
       setInterval(function(){
                     var d = new Date('<%= session[:auto_session_expires_at] %>');
                    var e = new Date();
                    var f = e.getTime();
                    var diff = d - f ;
                    alert(d + " |  " + diff);

      if (diff <  120000) {
        //  alert("Your session is about to timeout in less than 2 minutes " + diff);
                        }
          }, 10000);

  <% end %>

我的目标是使用 if (diff &lt; 120000) 语句在注销 2 分钟后显示警报。

上面的代码通过自动会话超时获取会话变量,然后从当前日期(来自 js 的 getTime())中减去它并得出一个差异。

它几乎可以正常工作。如果与应用程序交互,计数器将被重置。但是,旧计数器似乎仍在运行。

换句话说,如果我查看未标记的警报语句的结果,我可以看到会话变量中的日期时间和计算出的差异。下面我只显示为简单起见显示的会议记录和会话。

25:22 168134 - 第一个警告框 - 显示会话变量的内容,还显示计算的差异或剩余毫秒数。

25:22 143249 -- 第二个警报框 -- 一切都如预期的那样。

25:22 120816 -- 因此,它使用会话变量中的正确信息正确倒计时

现在,如果我与应用交互,自动会话超时会重置会话变量 auto_session_expires_at。

26:13 158345 - 好的 - 正是我所期望的。 Javascript 正在获取新的会话变量并重新计算差异。

25:22 86327 -- 但现在我看到前一个会话变量并且差异计算器仍在运行

然后上面的循环将在“好”和“旧”会话变量和差异之间不断重复。我认为正在进行某种缓存,但我无法确定它。

这种行为对我来说是可重复的

================================================ ======== 我第一次打开应用程序时的 HTML

/<![CDATA[


      var d = new Date('2016-05-06 15:58:19 -0400');

      setInterval(function(){

                    var d = new Date('2016-05-06 15:58:19 -0400');
                    var e = new Date();
                    var f = e.getTime();
                    var diff = d - f ;
                   alert(d + " |  " + diff);


      if (diff <  120000) {
        //  alert("Your session is about to timeout in less than 2 minutes " + diff);
                        }
          }, 10000);




//]]>

点击导航项后的 HTML。可以看到从会话变量中抓取的日期发生了变化

/<![CDATA[


      var d = new Date('2016-05-06 15:58:48 -0400');

      setInterval(function(){

                    var d = new Date('2016-05-06 15:58:48 -0400');
                    var e = new Date();
                    var f = e.getTime();
                    var diff = d - f ;
                   alert(d + " |  " + diff);


      if (diff <  120000) {
        //  alert("Your session is about to timeout in less than 2 minutes " + diff);
                        }
          }, 10000);




//]]>
</script>

【问题讨论】:

  • 当您说会话在您与站点交互后被重置时,您是否被重定向?我问这个是因为查看生成的 HTML 代码会很有用。
  • 对不起,我可能有点模糊。我正在做的是从导航菜单中选择一些东西,因为它会加载一个新页面。
  • 好的,可以把生成的HTML贴出来看看javascript函数吗?
  • 另一个问题,您说:this behavior is repeatable for me,您是否收到 2 个提醒,一个带有旧日期,另一个带有新日期?
  • 那么你应该保存原始setTimeInterval的引用,然后调用clearInterval确保它在你与页面交互后不会继续运行。

标签: javascript ruby-on-rails session


【解决方案1】:

@SanF 关于 clearInterval 是正确的。这是修改后的代码。这和我开始的时候有很大不同。

<% if current_user  %>

  <%= javascript_tag do %>


      // --------------------------------------------------------------------------------------------------------
      // This script enhances the functionality of the auto_session_timeout gem
      //
      // this script will give the user a warning at a specified time before they will be automatically logged out
      // from their session.
      //
      // The polling interval is set in var myVar = setInterval(myTimer, 10000); where 10000 = 10 seconds
      // That should be set to about 1000 so that the login screen appears as soon as possible when
      // the user comes to a screen from a timed out session.
      //
      // The time before logout for the warning is set in  if (diff <  120000)  120000 = 120 seconds
      //
      //  The timeout itself is contrlled by the auto_session_timeout gem and the setting in the application
      //  controller ' auto_session_timeout 4.minutes' . Make sure that the time set there is LONGER than the
      // time set below for the warning
      // ---------------------------------------------------------------------------------------------------------

              clearTimer();                                                       // clear the warning timer if it has been set previously
              var diff = 0;                                                       // Initialize the difference calculation
              var b = new Date();
              var f = new Date();
              var e = new Date();
              var current_time = e.getTime();                                     // get the current time from the system
              expires = new Date('<%= session[:auto_session_expires_at] %>');     // get the expiration time set by auto session expires.
              var myVar = setInterval(myTimer, 5000);                             // this calls myTimer and runs it at intervals specified. 1000 = 1 second


      // ------------------------------------ myTimer --------------------------------------------------
      // This function is called with a setInterval so that it runs at a set interval depending on the number
      // passed to var myVar = setInterval(myTimer, 1000); above. It gets the session variable
      // containing the expires at date/time and also the current time. If the difference is less than the value set
      // a warning is shown via an alert box and then the function is cleared.
      // ------------------------------------------------------------------------------------------------

          function myTimer() {
                   var diff = 0;                                                              // Initialize the difference between expires date/time and current date/time
                   var expires_raw = '<%= session[:auto_session_expires_at] %>'               // Get the raw session variable from rails
                                                                                              // we need to parse the date above to be like var d = new Date('2016-05-10T13:50:12-04:00');
                   var exp_date = expires_raw.slice(0,10);                                    // grab the date
                   var exp_time = expires_raw.slice(11,19);                                   // grab the time  H M S
                   var exp_tzh = expires_raw.slice(20,23);                                    // grab the hour part of the timezone with the -
                   var exp_tzm = expires_raw.slice(23,25);                                    // grab the minute part of the timezone which should be 00
                   var expires_parsed = exp_date + "T" + exp_time + exp_tzh + ":" + exp_tzm;  // Parse it all together. Date plus a constant 'T' , time, time zone hour, colon, timezone min
                   var expires_parsed_time = new Date(expires_parsed);                        // take expires_parsed and create a date/time from it
                   var expires_parsed_time_iso = expires_parsed_time.toISOString();           // Convert expires_parsed_time to an ISO string - This step is KEY to making this
                                                                                                 // work with IE 11 and firefox. They need the date from a strict ISO format
                   var expires_final = new Date(expires_parsed_time)                          // create a date from the expires_parsed_time
                   var expires_parsed_final = new Date(expires_parsed_time)                   // This is the final date that is fed to the diff variable


                  var e = new Date();                                                         // set up a new date for the current time
                  current_time = e.getTime();                                                 // get the current time from the system
                  diff = expires_parsed_final - current_time ;                                // calculate the difference between the expires and current times.

            // The following commented alert can be uncommented as a debugging tool

//                                    alert("\n raw date        " + '<%= session[:auto_session_expires_at] %>' +
//                                    "\n exp parsed      " + expires_parsed +
//                                    "\n diff            " + diff +
//                                    "\n current_time    " + current_time +
//                                    "\n exp raw         " + expires_raw +
//                                    "\n exp date        " + exp_date +
//                                    "\n exp time        " + exp_time +
//                                    "\n exp tzh         " + exp_tzh +
//                                    "\n exp tzm         " + exp_tzm +
//                                    "\n exp par time    " + expires_parsed_time +
//                                    "\n exp par tm iso  " + expires_parsed_time_iso +
//                                    "\n exp par final   " + expires_parsed_final);

      if (diff <  180000) {
            alert("\n Your Internal complaints session is about to timeout \n in less than 3 minutes  \n \n " +
                  "Please save your work  \n" +
                  "Navigating to any page will reset the timeout timer");
                  clearInterval(myVar);                                                     // this clears the current warning timer since the message has already been shown to the user.
            }
      }


      //   ------------------------------------ clearTimer ------------------------------------------
      //   When called, this function will stop the setInterval for myTimer so that we don't have
      //   multiple timers running
      //   ------------------------------------------------------------------------------------------

            function clearTimer() {
            clearInterval(myVar);
            }


            function myTest() {
            alert("test inside the test");
            }

  <% end %>

我遇到的另一个问题是 Firefox 和 IE 对日期的 ISO 标准使用了严格的解释。在尝试在 IE/FF 中计算日期之前,这需要一些额外的步骤来使用 ISO 8601 格式的日期。

这仍然需要一些工作,但也许它可以帮助尝试执行类似“超时前”警告的人。

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 2013-11-27
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多