Ajax - 我需要在每个AJAX请求之前检查是否存在有效会话

时间:2009-08-20 03:30:44

标签: javascript jquery

我正在开发一个使用用户身份验证的项目。如果在发出请求时没有经过身份验证的会话,我将面临我的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请求编写错误处理程序。

谢谢。

2 个答案:

答案 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,那么我将重新加载页面。