考虑这个Django的观点将得到有关当前用户的项目清单:在Ajax请求中处理会话超时的最佳方式是什么?
@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
当未经身份验证的用户尝试访问视图时会做什么?它向settings.LOGIN_URL
返回HttpResponseRedirect
。
考虑这段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
装饰将检测该会话不再处于活动状态,并且将返回一个HttpResponseRedirect(settings.LOGIN_URL)
,这将导致success
回调来获取HTML登录页面而不是JSON编码列表。
This is where it happens.
It's called by user_passes_test
here.
什么是处理这个最好的方法是什么?
这里的一些事情我已经想到了:
1.
的success
回调应检查响应,并看它是否得到一个登录页面,以任何方式(检查内容类型为HTML,检查内容等)。但是,这意味着我们必须包装都用AJAX回调的包装,像这样调用:
$.ajax({
url: "/list_items/" + pageNumber + "/",
success: sessionExpiryCallbackWrapper(function(data) {
$("#list_container").html(formatData(data))
})
});
但这是丑陋的,和开发人员可能会忘记处处做到这一点。使用$.ajaxComplete
来处理所有请求。
$.ajaxComplete(globalCompleteCallback);
$.ajax({
success: successCallback,
complete: completeCallback
});
但是,这是调用顺序:
successCallback(); // success is called before complete
completeCallback();
globalCompleteCallback(); // this is called after the local callback
所以我们只能抓重定向,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)
但login_required
只是使用user_passes_test
不这样做。
user_passes_test
在那里有很多功能,所以重新实现它并不是一个好主意。
处理AJAX调用超时的最佳方式是什么?
对不起,但我要对你全部哲学。会话超时的最初意图是防止服务器占用大量资源或不得不对每个请求执行昂贵的操作。我们现在拥有完成大部分工作的客户端框架。那么为什么短时间超时甚至需要? – 2012-03-14 01:30:46
@DaveMethvin需要会话超时来缩小会话劫持的窗口,无论是a)在有线/无线上,还是b)物理上有人在AFK一点点后去别人的计算机。 – Prody 2012-03-14 08:53:11
这个问题似乎很容易解决,只是客户端会话超时比服务器更短。如果是这种情况,那么客户端应该很少发出请求,发现自己在没有有效会话的服务器上。此外,这意味着你可以提出一个漂亮的客户端启动的“你的会话超时”消息。 – 2012-03-21 05:25:19