【发布时间】:2012-01-16 23:47:47
【问题描述】:
构建一个 Ajax 应用程序非常简单,该应用程序会检查所有响应以确保它们不是会话到期的指示,如果会话已到期,则使用友好的“您的会话因不活动而超时”自动注销用户" 错误信息。
但在 Ajax 应用程序中常见的情况是:
- 用户已登录,愉快地使用应用程序,通过已建立的 http 会话通过 http 检索数据
- 用户关闭笔记本电脑
- 主机在 N 分钟后超时 http 会话
- 用户稍后重新打开笔记本电脑。 Ajax 应用程序看起来很活跃。他们可以点击左右,这很好,因为该应用可以让他们看到他们已经加载的内容。
- 然后,他们点击需要加载数据的内容,然后返回的数据表明会话到期
- Ajax 应用程序将它们踢出并显示“您的会话由于不活动而超时”。
这对用户来说真的很奇怪,因为从他们的角度来看,他们并没有处于非活动状态。
现在,一种可能性是在客户端中使用 Javascript 代码,该代码使用 setTimeout() 定期(例如,如果会话超时为 30 分钟,则每 15 分钟一次)触发对主机的请求,询问还剩多少时间会议。这种定期检查非常棒,因为它可以让您在它们接近超时时向它们显示警告,例如“除非你做某事,否则你的会话将在 1 分钟内超时”。
但是当用户的机器被挂起时,这无济于事。这是因为根据我在许多不同浏览器中的所有测试,setTimeout 时间适用于经过的运行时间,而不是经过的实时时间。也就是说,如果你调用 setTimeout("alert('hi')",2*60*1000);然后在 10 秒后暂停您的机器,等待 5 分钟,然后重新激活您的机器,您将再等待 110 秒,直到您收到该警报(我无法找到有关此行为的确切文档,但这是一个可证明的事实)。因此,这意味着您的经期检查可能不会在用户机器恢复后很长时间内发生。
我对此的解决方案是,不是基于长的 setTimeout 进行定期检查,而是做一个短的 setTimeout(例如,每 5 秒),并使用 new Date() 检查自上次检查以来经过的时间.getTime() 获取实际时钟时间。这样我总是检查真实时钟,而不是客户端等待从零到十五分钟才意识到它在暂停后超时,最多它会等待大约五秒(加上 http 响应时间)来找出答案。
但我不喜欢这种解决方案,因为它依赖于频繁的基于计时器的中断。 有没有更聪明的方法来处理这个问题?
【问题讨论】:
标签: ajax session-timeout