我正在开发一个使用用户身份验证的项目。如果在发出请求时没有经过身份验证的会话,我将面临我的AJAX请求问题。
我的会话超时为3分钟,因此如果用户保持空闲3分钟然后执行一些导致AJAX请求的操作,则请求将失败并返回403错误。这里我打算做的是拦截页面中的所有AJAX请求,并向服务器发送ping,该服务器将返回一个JSON对象,说明是否存在有效会话。如果有,那么客户端将继续当前请求,否则它将重新加载当前页面,这将使用户进入登录页面,并且用户必须再次提供凭证。
这是我的实施。
$("#param-ajax").ajaxSend(function(evt, request, settings) {
var pingurl = GtsJQuery.getContextPath() + '/ping.json';
var escapedurl = pingurl.replace(/\//g, "\\/");
var regexpr1 = eval('/^' + escapedurl + '\\?.*$/');
var regexpr2 = eval('/^' + escapedurl + '$/');
// Proceed with the ping only if the url is not the ping url else it will
// cause recursive calls which will never end.
if (!regexpr1.test(settings.url) && !regexpr2.test(settings.url)) {
var timeout = false;
$.ajax({
url : pingurl,
cache : false,
data : {
url : settings.url
},
async : false,
complete : function(request, status) {
if (status == "error") {
try {
// GtsJQuery.getJsonObject() converts the string
// response to a JSON object
var result = GtsJQuery
.getJsonObject(request.responseText)
if (result.timeout) {
timeout = true;
return;
}
} catch (e) {
// ignore the error. This should never occure.
}
}
}
});
// Reload the window if there is a timeout -- means there is no valid
// sesstion
if (timeout) {
window.location.reload();
}
}
});
这里一切正常包括window.location.reload(),但原始的ajax请求没有中止。由于在触发页面重新加载后原始AJAX请求未中止,因此AJAX请求也会发送到服务器。我想要一些机制,如果超时结果为真,我将允许我中止原始请求。
This post提供了一些答案,但问题仍然存在于第三方插件,例如使用AJAX的数据表。我们无法为这些AJAX请求编写错误处理程序。
谢谢。
答案 0 :(得分:2)
如果我了解情况,你不需要任何这些。在原始的ajax请求中,只需添加一个将重定向用户的错误函数。
errHandler = function(XMLHttpRequest, textStatus, errorThrown) {
if( textStatus.match(/forbidden/i) ) {
redirectUserToLoginHere();
}
}
$.ajax({
success: yourFunctionHere,
error: errHandler
})
然后你可以创建一个总是有errHandler的ajax包装器,这样你就不必将它放在每个单独的ajax调用中。
编辑:
经过一些实验,如果'ajaxSend'处理程序抛出错误,那么原始请求将永远不会被发送。
此外,如果处理程序
document.location = '/login';
然后永远不会发送原始请求。
希望这有助于:)
答案 1 :(得分:0)
我现在改变了我的概念,我正在使用请求标头'x-requested-with'检查服务器端的xmlHTTPRequest。
如果是xmlHTTPRequest,那么'x-requested-with'将具有值'XMLHttpRequest'。我正在使用的javascript库(EXTjs和jQuery)都正确设置了这个标题。
这是我的服务器端代码
boolean isAjaxRequest = StringUtils.endsWithIgnoreCase(request.getHeader("x-requested-with"), "XMLHttpRequest")
修改
如果给定的请求是ajax请求,则响应将是json数据,其状态为403,并且它将包含一个名为timeout的键,其值为true 例如:{timeout:true,....}
然后我们将在$ .ajaxError()事件处理程序中处理这个错误。如果错误状态为403且超时值为true,那么我将重新加载页面。