在ajax请求中处理会话超时的最佳方法是什么?

时间:2012-03-14 01:24:29

标签: jquery django

考虑这个Django视图,它将获得与当前用户关联的项目列表:

@login_required
def list_items(request, page_number=0):
    items = Paginator(request.user.items, 5).page(page_number).object_list
    return HttpResponse(cjson.encode(items))

显然,它希望使用login_required装饰器来限制对已登录用户的视图的访问。

当未经身份验证的用户尝试访问该视图时,login_required会做什么?它向HttpResponseRedirect返回settings.LOGIN_URL

考虑这个调用视图的JavaScript代码:

var getPage = function(pageNumber) {
    $.ajax({
        url: "/list_items/" + pageNumber + "/",
        success: function(data) {
            $("#list_container").html(formatData(data))
        }
    });
};

假设settings.SESSION_COOKIE_AGE = 60秒。

如果用户转到第1页,将其读取61秒,然后单击第2页的按钮,Django的login_required装饰器将检测到会话不再处于活动状态,并将返回{{1这将导致HttpResponseRedirect(settings.LOGIN_URL)回调获取HTML登录页面而不是JSON编码列表。

This is where it happens.
It's called by user_passes_test here.

处理此问题的最佳方法是什么?

以下是我想到的一些事情:

success 1.回调应检查响应,并通过任何方式查看它是否获得登录页面(检查内容类型是否为html,检查内容等)。但这意味着我们必须使用回调包装器包装所有AJAX调用,如下所示:

success

但这很难看,开发人员可能忘记在任何地方都这样做。

$.ajax({ url: "/list_items/" + pageNumber + "/", success: sessionExpiryCallbackWrapper(function(data) { $("#list_container").html(formatData(data)) }) }); 使用2.来处理所有请求。

$.ajaxComplete

但这是电话订单:

    $.ajaxComplete(globalCompleteCallback);
    $.ajax({
        success: successCallback,
        complete: completeCallback
    });

因此,在successCallback失败后,我们只捕获重定向,并且可能由于收到的数据无效而导致JS错误。

successCallback(); // success is called before complete completeCallback(); globalCompleteCallback(); // this is called after the local callback 如果login_required在AJAX请求中返回403:

3.

但是login_required只使用user_passes_test而不是这样做。

user_passes_test有很多功能,所以重新实现它并不是一个好主意。

处理AJAX调用超时的最佳方法是什么?

2 个答案:

答案 0 :(得分:6)

我会通过让你的会话超时方法检查它是否被AJAX请求来处理它。如果是ajax,则使用空的json字符串返回未授权的401(或403禁止或任何有意义的状态)状态代码。接下来,在您的javascript中,绑定一个全局ajaxError处理程序,该处理程序检查该状态代码并对其进行适当处理。

答案 1 :(得分:1)

您可以使用类似http://amplifyjs.com/的东西,让您为AJAX调用编写一个漂亮的包装器,然后使用其data mapping功能检查用户是否仍在登录之前进行AJAX调用。< / p>

通过这种方式,您可以拥有一个客户端计时器,将用户设置为注销状态并提供提示,以便在每次调用AJAX之前不需要进行登录检查。

或者,您可以使用自定义decoder,如果用户已注销,则会要求用户登录并重试AJAX调用。它需要存储它所调用的所有xhr数据和回调,直到用户登录。