我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
当前回答
<script>
function showValues() {
var str = $("form").serialize();
$.post('loginUser.html',
str,
function(responseText, responseStatus, responseXML){
if(responseStatus=="success"){
window.location= "adminIndex.html";
}
});
}
</script>
其他回答
最终实现的解决方案是为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,我们使用该元素替换页面的一部分。此外,我们只需要重定向到登录页面。
这对我有用:
success: function(data, textStatus, xhr) {
console.log(xhr.status);
}
一旦成功,ajax将获得浏览器从服务器获得的相同状态代码并执行它。
我喜欢蒂默兹的方法,稍微加一点柠檬。如果在期望JSON时返回text/html的contentType,则很可能会被重定向。在我的例子中,我只需重新加载页面,它就会被重定向到登录页面。哦,检查jqXHR状态是否为200,这看起来很傻,因为您处于错误函数中,对吗?否则,合法的错误情况将强制迭代重新加载(oops)
$.ajax(
error: function (jqXHR, timeout, message) {
var contentType = jqXHR.getResponseHeader("Content-Type");
if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
// assume that our login has expired - reload our current page
window.location.reload();
}
});
我只是想分享我的方法,因为这可能会帮助某人:
我基本上包含了一个JavaScript模块,它处理身份验证,例如显示用户名,以及本例中处理重定向到登录页面。
我的场景:我们之间基本上有一个ISA服务器,它监听所有请求,并用302和位置标头响应登录页面。
在我的JavaScript模块中,我最初的方法是
$(document).ajaxComplete(function(e, xhr, settings){
if(xhr.status === 302){
//check for location header and redirect...
}
});
问题(这里已经提到了很多)是浏览器自己处理重定向,因此我的ajaxComplete回调从未被调用,但我得到了已经重定向的Login页面的响应,这显然是状态200。问题是:如何检测成功的200响应是您实际的登录页面还是其他任意页面??
解决方案
由于无法捕获302个重定向响应,我在登录页面上添加了LoginPage标头,其中包含登录页面本身的url。在模块中,我现在侦听标头并执行重定向:
if(xhr.status === 200){
var loginPageRedirectHeader = xhr.getResponseHeader("LoginPage");
if(loginPageRedirectHeader && loginPageRedirectHeader !== ""){
window.location.replace(loginPageRedirectHeader);
}
}
…这就像魅力一样:)。你可能想知道为什么我在LoginPage头中包含url。。。基本上是因为我找不到从xhr对象自动定位重定向得到的GET url的方法。。。
最后,我通过添加自定义HTTP头来解决这个问题。就在服务器端响应每个请求之前,我将当前请求的url添加到响应的头部。
我在服务器上的应用程序类型是Asp.NetMVC,这是一个很好的地方。在Global.asax中,我实现了application_EndRequest事件,因此:
public class MvcApplication : System.Web.HttpApplication
{
// ...
// ...
protected void Application_EndRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
app.Context.Response.Headers.Add("CurrentUrl",app.Context. Request.CurrentExecutionFilePath);
}
}
它非常适合我!现在,在JQuery$.post的每个响应中,我都有请求的url和其他响应头,这些响应头是post方法的结果,状态为302、303。
另一个重要的是,不需要在服务器端或客户端修改代码。
下一个是能够访问动作后的其他信息,例如错误、消息和。。。,以这种方式。
我发布了这个,也许可以帮助某人:)