我正在使用 jQuery 和 jQuery.form 插件来提交我的表单(也使用 ASP.Net MVC)。
问题是用户在使用表单身份验证的网站部分中,如果他们的身份验证 cookie 在页面上过期而不是返回 302 状态,这将是重定向到登录页面,我仍然得到 200 ?
在 FireBug 中,我看到 302 Found,然后我的登录页面接下来作为 200 提供,这是发送回我的 Ajax 调用的状态代码。如果我从未看到将 302 发送回 jQuery 表单插件,我如何检测到它们已被注销?
我正在使用 jQuery 和 jQuery.form 插件来提交我的表单(也使用 ASP.Net MVC)。
问题是用户在使用表单身份验证的网站部分中,如果他们的身份验证 cookie 在页面上过期而不是返回 302 状态,这将是重定向到登录页面,我仍然得到 200 ?
在 FireBug 中,我看到 302 Found,然后我的登录页面接下来作为 200 提供,这是发送回我的 Ajax 调用的状态代码。如果我从未看到将 302 发送回 jQuery 表单插件,我如何检测到它们已被注销?
我真的很喜欢这个解决方案。通过将 ajax 请求的 302 响应更改为 401,它允许您在客户端设置 ajax 以监视任何寻找 401 的 ajax 请求,如果找到一个重定向到登录页面。非常简单有效。
全球.asax:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302 &&
Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
}
}
客户端代码:
$(function () {
$.ajaxSetup({
statusCode: {
401: function () {
location.href = '/Logon.aspx?ReturnUrl=' + location.pathname;
}
}
});
});
尝试使用缓存:jquery ajax 中的 false 缓存选项:
$.ajax({
url: "test.html",
cache: false,
success: function(html){
$("#results").append(html);
}
});
---编辑在 C# 代码中尝试这个:
protected void Page_Load(object sender, System.EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
...
}
之前也遇到过类似的问题。这个问题中给出的解决方案有帮助吗?
我很确定您永远不会在 XHR 对象的已完成状态下获得 302。如果发生重定向,则连接仍在进行中,直到您看到来自登录页面的响应(如果存在,则应为 200)。
但是,为什么需要查看 302?当然,如果您要重定向到 login.php,那么只需获取返回响应的 url(或解析内容)就可以告诉您他们已被注销?
仅当您想在会话过期后(在他们执行某些操作之前)立即知道的另一种方法是使用 setTimeout 或类似方法轮询服务器以获取有关身份验证状态的信息。
祝你好运。
这是我过去使用的解决方案:
服务器端:
当我检查会话是否仍然有效时,我还会留意“X-Requested-With”标头,如果您使用的是 jQuery,它应该是“XMLHttpRequest”(注意:IE 倾向于返回小写的标题名称,所以也要注意)。如果会话确实已经过期并且标头存在,我不使用 HTTP 重定向,而是使用一个简单的 JSON 对象进行响应,如下所示:
{ "SESSION": "EXPIRED" }
客户端:
在我的 onload 代码中,我使用 jQuery 的 ajaxComplete 事件来检查会话过期对象的所有传入请求负载。代码看起来像这样:
$(window).ajaxComplete(function(ev, xmlhr, options){
try {
var json = $.parseJSON(xmlhr.responseText);
}
catch(e) {
console.log('Session OK');
return;
}
if ($.isPlainObject(json) && json.SESSION == 'EXPIRED') {
console.log('Session Expired');
//inform the user and window.location them somewhere else
return;
}
console.log('Session OK');
});