我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
当前回答
如果您还想传递值,那么还可以设置会话变量和访问如:在jsp中,您可以编写
<% HttpSession ses = request.getSession(true);
String temp=request.getAttribute("what_you_defined"); %>
然后,您可以将这个temp值存储在javascript变量中,并四处游玩
其他回答
使用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'”,则过滤器将捕捉到该数据并进行评估以进行重定向,而不是让数据显示。
最终实现的解决方案是为Ajax调用的回调函数使用包装器,并在该包装器中检查返回的HTML块上是否存在特定元素。如果找到元素,则包装器执行重定向。如果没有,包装器将调用转发给实际的回调函数。
例如,我们的包装器函数类似于:
function cbWrapper(data, funct){
if($("#myForm", data).length > 0)
top.location.href="login.htm";//redirection
else
funct(data);
}
然后,在进行Ajax调用时,我们使用了类似的方法:
$.post("myAjaxHandler",
{
param1: foo,
param2: bar
},
function(data){
cbWrapper(data, myActualCB);
},
"html"
);
这对我们很有用,因为所有Ajax调用都会在DIV元素中返回HTML,我们使用该元素替换页面的一部分。此外,我们只需要重定向到登录页面。
我发现的另一个解决方案(如果要设置全局行为,尤其有用)是将$.ajaxsetup()方法与statusCode属性一起使用。正如其他人指出的,不要使用重定向状态码(3xx),而是使用4xx状态码并处理客户端重定向。
$.ajaxSetup({
statusCode : {
400 : function () {
window.location = "/";
}
}
});
将400替换为要处理的状态代码。正如前面提到的401未经授权可能是个好主意。我使用400,因为它非常不具体,我可以在更具体的情况下使用401(比如错误的登录凭据)。因此,当会话超时并且您处理重定向客户端时,后端应该返回4xx错误代码,而不是直接重定向。即使使用backbone.js这样的框架,也非常适合我
使用低级$.ajax()调用:
$.ajax({
url: "/yourservlet",
data: { },
complete: function(xmlHttp) {
// xmlHttp is a XMLHttpRquest object
alert(xmlHttp.status);
}
});
尝试此操作进行重定向:
if (xmlHttp.code != 200) {
top.location.href = '/some/other/page';
}
我认为更好的处理方法是利用现有的HTTP协议响应代码,特别是401未授权。
我是这样解决的:
服务器端:如果会话过期,请求为ajax。发送401响应代码头客户端:绑定到ajax事件$('body').bind('ajaxSuccess',函数(事件,请求,设置){if(401==请求状态){window.location='/users/login';}}).bind('ajaxError',函数(事件、请求、设置){if(401==请求状态){window.location='/users/login';}});
IMO这是更通用的,您没有编写一些新的自定义规范/标题。您也不必修改任何现有的ajax调用。
编辑:根据@Rob下面的评论,401(验证错误的HTTP状态代码)应该是指示符。有关详细信息,请参阅403禁止与401未授权HTTP响应。尽管如此,一些web框架使用403来处理身份验证和授权错误,因此进行相应的调整。谢谢Rob。