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

Pro*_*ody 13 django jquery

考虑这个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))
Run Code Online (Sandbox Code Playgroud)

显然,它希望使用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))
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

假设settings.SESSION_COOKIE_AGE = 60秒.

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

这就是它发生的地方.
user_passes_test在这里被称为.

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

这是我想到的一些事情:

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

    $.ajax({
        url: "/list_items/" + pageNumber + "/",
        success: sessionExpiryCallbackWrapper(function(data) {
            $("#list_container").html(formatData(data))
        })
    });
Run Code Online (Sandbox Code Playgroud)

但这很丑陋,开发人员可能忘记在任何地方都这样做.

2.使用$.ajaxComplete来处理所有的请求.

    $.ajaxComplete(globalCompleteCallback);
    $.ajax({
        success: successCallback,
        complete: completeCallback
    });
Run Code Online (Sandbox Code Playgroud)

但这是电话订单:

    successCallback(); // success is called before complete
    completeCallback();
    globalCompleteCallback(); // this is called after the local callback
Run Code Online (Sandbox Code Playgroud)

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

3.如果login_required在AJAX请求上返回403:

    if not user.is_authenticated():
        if request.is_ajax():
            # send 403 to ajax calls
            return HttpResponse403("you are not logged in")
        else:
            # regular code path
            return HttpResponseRedirect(settings.LOGIN_URL)
Run Code Online (Sandbox Code Playgroud)

login_required只是使用user_passes_test不这样做.

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

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

use*_*654 6

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