我正在使用$.post()
Ajax 调用 servlet,然后使用生成的 HTML 片段替换div
用户当前页面中的元素。但是,如果会话超时,服务器会发送重定向指令将用户发送到登录页面。在这种情况下,jQuery 正在将div
元素替换为登录页面的内容,迫使用户的眼睛确实看到了罕见的场景。
如何使用 jQuery 1.2.6 从 Ajax 调用中管理重定向指令?
我正在使用$.post()
Ajax 调用 servlet,然后使用生成的 HTML 片段替换div
用户当前页面中的元素。但是,如果会话超时,服务器会发送重定向指令将用户发送到登录页面。在这种情况下,jQuery 正在将div
元素替换为登录页面的内容,迫使用户的眼睛确实看到了罕见的场景。
如何使用 jQuery 1.2.6 从 Ajax 调用中管理重定向指令?
我阅读了这个问题并实现了关于将响应HTTP 状态代码设置为 278 的方法,以避免浏览器透明地处理重定向。即使这有效,我还是有点不满意,因为它有点像黑客。
经过更多的挖掘,我放弃了这种方法并使用了JSON。在这种情况下,对 AJAX 请求的所有响应都具有状态代码200,并且响应正文包含在服务器上构建的 JSON 对象。然后客户端上的 JavaScript 可以使用 JSON 对象来决定它需要做什么。
我遇到了和你类似的问题。我执行了一个 AJAX 请求,它有两种可能的响应:一种将浏览器重定向到新页面,另一种用新页面替换当前页面上的现有 HTML 表单。执行此操作的 jQuery 代码如下所示:
$.ajax({
type: "POST",
url: reqUrl,
data: reqBody,
dataType: "json",
success: function(data, textStatus) {
if (data.redirect) {
// data.redirect contains the string URL to redirect to
window.location.href = data.redirect;
} else {
// data.form contains the HTML for the replacement form
$("#myform").replaceWith(data.form);
}
}
});
JSON 对象“数据”在服务器上构造为具有 2 个成员:data.redirect
和data.form
. 我发现这种方法要好得多。
我通过以下方式解决了这个问题:
向响应添加自定义标头:
public ActionResult Index(){
if (!HttpContext.User.Identity.IsAuthenticated)
{
HttpContext.Response.AddHeader("REQUIRES_AUTH","1");
}
return View();
}
将 JavaScript 函数绑定到ajaxSuccess
事件并检查标头是否存在:
$(document).ajaxSuccess(function(event, request, settings) {
if (request.getResponseHeader('REQUIRES_AUTH') === '1') {
window.location = '/';
}
});
没有浏览器正确处理 301 和 302 响应。事实上,标准甚至说他们应该“透明地”处理它们,这对于 Ajax 库供应商来说是一个非常头疼的问题。在Ra-Ajax 中,我们被迫使用 HTTP 响应状态代码 278(只是一些“未使用的”成功代码)来处理来自服务器的透明重定向......
这真的让我很恼火,如果这里有人在 W3C 中有一些“拉动”,我会很感激你能让 W3C知道我们真的需要自己处理 301 和 302 代码......!;)
最终实现的解决方案是对 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。此外,我们只需要重定向到登录页面。
我喜欢 Timmerz 的方法,稍微加一点柠檬。如果你有机会返回的contentType中的text / html,当你期待JSON,你是最有可能被重定向。就我而言,我只是简单地重新加载页面,然后它就会被重定向到登录页面。哦,检查 jqXHR 状态是否为 200,这看起来很傻,因为您在错误函数中,对吧?否则,合法的错误情况将强制迭代重新加载(oop)
$.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();
}
});