【问题标题】:Ajax - I need to check whether a valid session exists before every AJAX requestsAjax - 我需要在每个 AJAX 请求之前检查是否存在有效会话
【发布时间】:2010-11-21 04:29:22
【问题描述】:

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

谢谢。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    如果我了解情况,您就不需要这些。在您的原始 ajax 请求中,只需添加一个将重定向用户的错误函数。

    errHandler = function(XMLHttpRequest, textStatus, errorThrown) {
          if( textStatus.match(/forbidden/i) ) {
            redirectUserToLoginHere();
          }
    }
    
    $.ajax({
    
        success: yourFunctionHere,
    
        error: errHandler
    })
    

    然后你也许可以制作一些总是有那个 errHandler 的 ajax 包装器,这样你就不必把它放在每一个 ajax 调用中。

    编辑:

    经过一些实验,如果“ajaxSend”处理程序抛出错误,那么原始请求将永远不会被发送。

    此外,如果处理程序这样做

    document.location = '/login';
    

    那么原始请求永远不会发送。

    希望对您有所帮助:)

    【讨论】:

    • 问题是我正在使用第三方工具,例如内部使用 AJAX 获取数据的数据表。我不能在那里编写错误处理程序,我也不希望每个请求都单独处理这种情况。
    【解决方案2】:

    我现在改变了我的概念,我正在使用请求标头“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,我将重新加载页面。

    【讨论】:

    • 我认为您仍然没有解决如何处理问题的重新加载部分。使用“x-requested-with”标头是了解给定请求是否为 AJAX 请求的好方法
    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多