在现代网络浏览器中,假设我做了setTimeout
10 分钟(12:00),5 分钟后让计算机进入睡眠状态,当系统再次唤醒时会发生什么?如果它在 10 分钟之前(12:09)或更晚(16:00)醒来会发生什么?
我问的原因是因为我想每 10 分钟请求一个新的身份验证令牌,而且我不确定浏览器是否会做正确的事情并在很长时间后唤醒时立即请求一个新令牌时间。
说明:我不想使用 cookie - 我正在尝试在这里构建 Web 服务;是的,服务器将拒绝旧的和无效的令牌。
在现代网络浏览器中,假设我做了setTimeout
10 分钟(12:00),5 分钟后让计算机进入睡眠状态,当系统再次唤醒时会发生什么?如果它在 10 分钟之前(12:09)或更晚(16:00)醒来会发生什么?
我问的原因是因为我想每 10 分钟请求一个新的身份验证令牌,而且我不确定浏览器是否会做正确的事情并在很长时间后唤醒时立即请求一个新令牌时间。
说明:我不想使用 cookie - 我正在尝试在这里构建 Web 服务;是的,服务器将拒绝旧的和无效的令牌。
据我测试,它只是在计算机唤醒后停止并恢复。我想这意味着会话取决于setTimeout/Interval
从计算机入睡时开始的计数器滴答声。
我认为你不应该依赖于setTimeout/Interval
时间关键的东西的准确性。对于谷歌浏览器,我最近发现,如果激活它的选项卡失去焦点,任何超时/间隔(短于 1 秒)都会被减慢到每秒一次。
除此之外,超时/间隔的准确性取决于正在运行的其他功能等。简而言之:它不是很准确。
因此,使用间隔和超时,根据它启动的函数内的开始时间检查时间将为您提供更好的准确性。现在,如果您从 12:00 开始,计算机会在 16:13 左右进入睡眠状态并醒来,检查 16:13 和 12:00 您确定必须更新令牌。可以在此处找到使用时间比较的示例
将当前日期时间与页面加载时的日期时间进行比较,如下所示:
//Force refresh after x minutes.
var initialTime = new Date();
var checkSessionTimeout = function () {
var minutes = Math.abs((initialTime - new Date()) / 1000 / 60);
if (minutes > 20) {
setInterval(function () { location.href = 'Audit.aspx' }, 5000)
}
};
setInterval(checkSessionTimeout, 1000);
这是我的代码:
<!doctype html>
<html>
<body>
<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 120000)"/>
</body>
<script>
</script>
</html>
我已经采取了三个可能回答这个问题的场景。
场景 1:在 00 秒时单击“启动计时器”按钮。计算机在 25 秒时进入睡眠状态。在 1 分 40 秒唤醒计算机。在 2 分钟时显示警报。
场景 2:在 00 秒点击“启动计时器”按钮。在 26 秒时,计算机进入睡眠状态。3 分钟后,我唤醒了计算机。显示警报。
场景3:这真是令人震惊。
<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 600000)"/>
在 00 秒时,我单击“开始计时器”按钮。在大约 1 分 30 秒时,计算机处于休眠模式(我的电脑需要一分钟才能启动休眠)
8 分钟后,我打开笔记本电脑。恰好在 10 分钟时,警报弹出。
PS: This is my first ever comment on Stack Exchange. I prefer to execute code and view results rather than infer from theory.
该行为基于浏览器和操作系统。操作系统处理睡眠,个别应用程序通常不考虑它。
最有可能发生的是,操作系统将在计时器上的剩余时间与关闭时相同的时间恢复。另一种可能性是它根本不会触发。
如果这确实是一个问题,您可能希望比抱歉更安全,并存储令牌初始化时间的时间戳,并用于setInterval
定期检查(例如每分钟两次)。
然而,安全不应该只是客户端的事情。确保您的服务器在使用旧的/无效的令牌时抛出错误,并且 Ajax 的响应行为正确。
[编辑] 我同意另一篇文章,它可能会在下一个滴答声中立即触发。Resig 的博文非常好。
根据 Ben 的回答,我创建了以下实用程序。您可以调整采样持续时间,但是我像这样使用它来刷新令牌:
const absoluteSetInterval = (handler, timeout) => {
let baseTime = Date.now();
const callHandler = () => {
if (Date.now() - baseTime > timeout) {
baseTime = Date.now();
handler();
}
};
return window.setInterval(callHandler, 1000);
};
const absoluteClearInterval = (handle) => window.clearInterval(handle);