我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.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对象“data”在服务器上构造为有两个成员:data.redirect和data.form。我发现这种方法要好得多。
其他回答
我这样解决了这个问题:
添加一个中间件来处理响应,如果是对ajax请求的重定向,则使用重定向url将响应更改为正常响应。
class AjaxRedirect(object):
def process_response(self, request, response):
if request.is_ajax():
if type(response) == HttpResponseRedirect:
r = HttpResponse(json.dumps({'redirect': response['Location']}))
return r
return response
然后在ajaxComplete中,如果响应包含重定向,则它必须是重定向,因此请更改浏览器的位置。
$('body').ajaxComplete(function (e, xhr, settings) {
if (xhr.status == 200) {
var redirect = null;
try {
redirect = $.parseJSON(xhr.responseText).redirect;
if (redirect) {
window.location.href = redirect.replace(/\?.*$/, "?next=" + window.location.pathname);
}
} catch (e) {
return;
}
}
}
<script>
function showValues() {
var str = $("form").serialize();
$.post('loginUser.html',
str,
function(responseText, responseStatus, responseXML){
if(responseStatus=="success"){
window.location= "adminIndex.html";
}
});
}
</script>
我通过在login.php页面中放置以下内容来解决这个问题。
<script type="text/javascript">
if (top.location.href.indexOf('login.php') == -1) {
top.location.href = '/login.php';
}
</script>
我喜欢蒂默兹的方法,稍微加一点柠檬。如果在期望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();
}
});
最终实现的解决方案是为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,我们使用该元素替换页面的一部分。此外,我们只需要重定向到登录页面。