我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
当前回答
使用ASP.NET MVC RedirectToAction方法可能会出现此问题。为了防止表单在div中显示响应,您可以简单地使用$.ajaxSetup对响应进行某种ajax响应过滤。如果响应包含MVC重定向,则可以在JS端评估此表达式。JS的示例代码如下:
$.ajaxSetup({
dataFilter: function (data, type) {
if (data && typeof data == "string") {
if (data.indexOf('window.location') > -1) {
eval(data);
}
}
return data;
}
});
如果数据为:“window.location='/Acount/Login'”,则过滤器将捕捉到该数据并进行评估以进行重定向,而不是让数据显示。
其他回答
没有浏览器正确处理301和302响应。事实上,标准甚至说他们应该“透明”地处理它们,这对于Ajax库供应商来说是一个非常头疼的问题。在RaAjax中,我们被迫使用HTTP响应状态代码278(只是一些“未使用”的成功代码)来透明地处理来自服务器的重定向。。。
这真的让我很恼火,如果这里有人对W3C有一些“吸引力”,我会很感激你能让W3C知道我们确实需要自己处理301和302代码…!;)
我通过以下方式解决了这个问题:
向响应中添加自定义标头:公共操作结果索引(){if(!HttpContext.User.Identity.IsAuthenticated){HttpContext.Response.AddHeader(“REQUIRES_AUTH”,“1”);}return View();}将JavaScript函数绑定到ajaxSuccess事件并检查标头是否存在:$(document).ajaxSuccess(函数(事件、请求、设置){if(request.getResponseHeader('REQUIRES_AUTH')==“1”){window.location='/';}});
让我再次引用@Steg描述的问题
我有一个和你类似的问题。我执行一个ajax请求可能的响应:将浏览器重定向到新页面将当前页面上的现有HTML表单替换为新的一
IMHO这是一个真正的挑战,必须正式扩展到当前的HTTP标准。
我相信新的Http标准将使用新的状态代码。意思:目前301/302告诉浏览器去把这个请求的内容取到一个新的位置。
在扩展标准中,它会说如果响应状态为:308(只是一个示例),那么浏览器应该将主页重定向到提供的位置。
话虽如此;我倾向于模仿这种未来的行为,因此当需要document.redirect时,我让服务器响应如下:
status: 204 No Content
x-status: 308 Document Redirect
x-location: /login.html
当JS获得“status:204”时,它检查x-status:308标头的存在,并将document.redirect指向位置标头中提供的页面。
这对你有意义吗?
您还可以钩住XMLHttpRequest发送原型。这将使用一个处理程序处理所有发送(jQuery/dojo/etc)。
我编写这段代码是为了处理一个500页的过期错误,但它应该可以捕获200个重定向。准备好有关readyState含义的XMLHttpRequest onreadystatechange上的维基百科条目。
// Hook XMLHttpRequest
var oldXMLHttpRequestSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
//console.dir( this );
this.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 500 && this.responseText.indexOf("Expired") != -1) {
try {
document.documentElement.innerHTML = this.responseText;
} catch(error) {
// IE makes document.documentElement read only
document.body.innerHTML = this.responseText;
}
}
};
oldXMLHttpRequestSend.apply(this, arguments);
}
作为ajax的替代,正在开发一个新的Fetch API,它允许手动重定向处理。您需要检查当前的浏览器支持是否足以满足您的需要。