我有一个jquery日历小部件,可以在服务器上查询多个事件源,这些源都返回相同的JSON格式响应。
真正令人讨厌的是,当用户cookie过期时,所有这些来源都会将用户重定向到返回HTML内容的登录页面。
我已经用fiddler查看了请求,我可以看到两个请求已完成:第一个是来自jquery日历对象的请求,用于更新具有http状态302的事件,并在请求到http状态为200的登录页面后立即
GET /xyz/Adempimenti/GetEvents?_=1289170335910&start=1288566000&end=1291590000 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/javascript, */*; q=0.01
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Location: /xyz/Login/LogOn?ReturnUrl=%2fxyz%2fAdempimenti%2fGetEvents%3f_%3d1289170335910%26start%3d1288566000%26end%3d1291590000&_=1289170335910&start=1288566000&end=1291590000
我的网站非常基于ajax调用,这个日历只是一个例子来解释我面临的问题。我想避免在每次ajax调用时处理错误并进行重定向。最佳方法是找到一种在会话cookie过期时自动断开用户连接的方法。我已经看到这在一些Web电子邮件系统中实现,该系统会自动创建一个对话框,说明会话已过期。
在这方面有任何帮助吗?
答案 0 :(得分:4)
当jQuery执行AJAX请求时,它会发送HTTP_X_REQUESTED_WITH
标题。
您是否考虑过在服务器端检查该标头?如果会话超时,您可以返回包含“请登录”错误消息的JSON结构,而不是重定向到登录页面。
这将是我眼中最干净的方法。
另一个想法是在执行“真实”之前创建一个额外的Ajax请求。如果第一个请求失败或返回text/html
内容类型,则表示您已不再登录。不是非常优雅,但比尝试计算客户端的会话持续时间(必然不可靠)更容易。
答案 1 :(得分:1)
我相信你正在处理一个会话,其超时信息存储在服务器端(客户端不一定知道他的会话何时不再有效)。获取该信息并将其与请求一起发送给客户端。一个简单的setTimeout(notifySessionExpiration, sessTimeout * 1000)
就行了。
回答外围问题:
$ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
如果您正在处理XML请求,请将$ajax
设置为true,假设浏览器发送符合标题的标题(这些日期往往会这样做)。
您可能希望隔离发送302的代码部分(可能是一个应用程序范围的控制器,根据会话处理获取用户的个人信息),并在$ajax
为真时汇总异常。您可能希望发回401或403,然后让您的Javascript回调以特定方式响应该状态(例如,重定向到登录页面或提供弹出式Ajax登录覆盖)。
如果这只是一个玩具网站,并且您愿意亲自动手创建更强大的解决方案,我可以提出以下建议。
.html
或无扩展路径生成HTML,例如GET /mypage.html
或GET /mypage
,而XHR定制的内容应为{{1} }或GET /mypage.json
性质。这并不是说XHR应该从不获得HTML响应。有时,它非常合适,例如当您为登录表单加载HTML片段或者您只是使用AJAX进行页面转换时。