Jquery 响应内容类型与预期不同

Jquery 响应内容类型与预期不同,jquery,asp.net-mvc,asp.net-mvc-2,session-cookies,expired-sessions,Jquery,Asp.net Mvc,Asp.net Mvc 2,Session Cookies,Expired Sessions,我有一个jquery日历小部件,它可以查询服务器上的多个事件源,这些源都返回相同的JSON格式响应 真正令人恼火的是,当用户cookie过期时,这些源都会将用户重定向到返回HTML内容的登录页面 我已经用fiddler查看了请求,我可以看到两个请求完成了:第一个是来自jquery日历对象的请求,以更新http状态为302的事件,在请求之后立即更新http状态为200的登录页面 GET /xyz/Adempimenti/GetEvents?_=1289170335910&start=128

我有一个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电子邮件系统中看到了这一点,该系统会自动创建一个对话框,说明会话已过期


这方面有什么帮助吗?

当jQuery执行AJAX请求时,它会发送带有标题的HTTP\u X\u REQUESTED\u

您是否考虑过在服务器端检查该标头?如果会话超时,您可以返回包含please log in错误消息的JSON结构,而不是重定向到登录页面

那将是我眼中最干净的方法


另一个想法是在执行真正的Ajax请求之前再发出一个额外的Ajax请求。如果第一个请求失败或返回文本/html内容类型,则表明您不再登录。不是很优雅,但比在客户端计算会话持续时间更容易,这肯定是不可靠的。

我相信您正在处理一个会话,它的超时信息存储在服务器端,客户端不一定知道他的会话何时不再有效。获取该信息并将其与请求一起发送给客户机。一个简单的setTimeoutnotifySessionExpiration,sessTimeout*1000就可以了

回答外围问题:

$ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 
($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
如果您正在处理一个XML请求,则将$ajax设置为true,假设浏览器发送符合要求的头文件,而现在它往往会这样做

您可能希望隔离发送302的代码部分,可能是一个应用程序范围的控制器,用于根据会话获取用户的个人信息,如果$ajax为true,则将异常放在一起。您可能希望发回401或403,然后让Javascript回调以特定方式响应该状态,例如重定向到登录页面或提供弹出式Ajax登录覆盖

如果这只是一个玩具网站,而你愿意动手创建一个更强大的解决方案,我可以提出以下建议

不要使用语义误导性的XHR检测器:在我看来,如果是相同的ish内容,并对请求者进行了特定的调整(例如,浏览器怪癖),那么向不同的请求者提供不同的内容是完全合理的。但是,当一个特定的请求者有一个根本不同的功能角色时,例如,当一个XHR被发送到一个JSON/XML响应时,与当一个浏览器发送一个正常的HTML HTTP请求时,那么该请求不应该针对同一个资产。在我看来,最佳实践是为.HTML或无扩展名路径生成HTML,例如GET/mypage.HTML或GET/mypage,而XHR定制的内容应该是GET/mypage.json或GET/mypage.xml。这并不是说XHR永远不会得到HTML响应。有时候,这是非常合适的,比如当您为登录表单加载HTML代码段时,或者如果您只是使用AJAX进行页面转换。 实现一个让会话保持活动状态的系统:如果您必须让会话在一段时间内过期,而不是一直持续到浏览器关闭,那么在会话过期之前,在客户端调用一个简单的AJAX请求刷新会话。如果页面关闭,则不会触发请求,允许会话在分配的时间过后过期。
你无法控制服务器端?@Pekka:不喜欢你的第二种方法!:但第一个似乎很有趣。我可以编写一个自定义操作过滤器,并将其放置在我的基本控制器中,对吗?你有什么代码示例要开始吗?@Lorenzo对不起,我是一个PHP人,我没有ASP方面的经验,所以我无法帮助实现。正是jQuery标签把我吸引到这里:@Pekka:好的。非常感谢你的建议。我将尝试实现它。@Pekka:我清楚如何在服务器端处理检查以及如何正确地返回JSON吗。我还是应该在每次ajax调用中处理错误,还是有更干净的方法来捕捉错误?@Lorenzo我认为您必须在每次调用中处理错误,或者在遇到错误时停止进行ajax调用。是将用户重定向到登录页面还是显示登录拨号的选项
og?re第一段:在我看来,客户端超时不够可靠——想象一个用户打开两个选项卡,并在一个选项卡中保持会话活动。我认为这需要一个服务器端解决方案,即以一种适用于客户端的方式处理超时。但是请注意,他在服务器端的ASP上。关于XHR detectorI的有趣之处在于,我不能使用setTimeout示例,我也无法找到保持会话活动的方法。您是对的,检查用户是否仍然连接的问题与服务器会话有关,应该在应用程序范围的控制器中处理。但真正的问题是在客户端,我希望避免在每个ajax上检查错误和重定向call@Pekka,我也不喜欢这个解决方案,因为我对依赖它的相对过时的应用程序感到厌烦@洛伦佐,我不知道你要什么。这两种不一定相互排斥的方法是:1让客户端通过指示会话何时将要到期来抢占会话到期;2让服务器更优雅地处理XHR请求,而不是仅仅抛出302个请求,后者对Javascript是透明的。假设你想让课程过期,那就是你的选择。对不起,我的英语还远没有达到完美,所以我可能没有解释得那么好。现在,我已经实现了服务器处理检查是否存在HTTP_X_请求的带有头的_。如果用户会话已过期,我将向客户端发送一个简单的JSON结构。我现在的问题是:我是否必须在每次调用ajax时处理这种结构,或者有更好的方法来集中它?谢谢你的帮助help@Lorenzo,您可以像在编程中集中处理大多数事情一样进行操作。将AJAX函数调用一般化为一个中心处理程序或几个处理程序层,然后将响应代码的过滤器放入相应的处理程序中。如果XMLHttpRequest.send在代码中出现多次,则可能是做错了。