在ajax请求中处理会话超时的最佳方法是什么? [英] What's the best way to handle session timeouts in ajax requests?
问题描述
考虑这个Django视图,它将获得与当前用户相关联的项目列表:
Consider this Django view which will get a list of items associated to the current user:
@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
装饰器限制访问登录用户的视图。
Obviously, it wants to use the login_required
decorator, to restrict access to the view for logged-in users.
当未经身份验证的用户尝试时, login_required
会做什么?访问视图?它向 settings.LOGIN_URL
返回一个 HttpResponseRedirect
。
What does login_required
do when a non-authenticated user tries to access the view? It returns a HttpResponseRedirect
toward settings.LOGIN_URL
.
考虑这个JavaScript代码,调用视图:
Consider this JavaScript code, which calls the view:
var getPage = function(pageNumber) {
$.ajax({
url: "/list_items/" + pageNumber + "/",
success: function(data) {
$("#list_container").html(formatData(data))
}
});
};
假设 settings.SESSION_COOKIE_AGE = 60
秒。
如果用户进入第1页,读取第61页,然后点击Django的 login_required
装饰器将检测到会话不再活动,并将返回一个 HttpResponseRedirect(settings.LOGIN_URL)
,这将导致成功
回调获取HTML登录页面而不是JSON编码列表。
If a user goes to page 1, reads it for 61 seconds, then clicks on the button for page 2, Django's login_required
decorator will detect that the session is no longer active, and will return a HttpResponseRedirect(settings.LOGIN_URL)
, which will cause the success
callback to get a HTML login page instead of the JSON-encoded list.
这是发生的地方。
这里由 user_passes_test
调用。
最好的方式来处理这个问题?
What's the best way to handle this?
这里有几件事我已经想到:
Here's a few things I've thought of:
1。
成功
回调应该检查响应,看看是否通过任何方式获取登录页面(检查内容类型是否为HTML,检查内容等)。但是这意味着我们必须使用回调包装器来包装所有AJAX调用:
1.
The success
callback should check the response, and see if it gets a login page, by whatever means (check if content-type is html, check contents, etc). But this means that we have to wrap all AJAX calls with a callback wrapper like so:
$.ajax({
url: "/list_items/" + pageNumber + "/",
success: sessionExpiryCallbackWrapper(function(data) {
$("#list_container").html(formatData(data))
})
});
但这是丑陋的,开发人员可能会忘记无处不在。
But this is ugly, and developers might forget to do this everywhere.
2。
使用 $。ajaxComplete
来处理所有请求。
2.
Use $.ajaxComplete
to handle all requests.
$.ajaxComplete(globalCompleteCallback);
$.ajax({
success: successCallback,
complete: completeCallback
});
但这是电话订单:
successCallback(); // success is called before complete
completeCallback();
globalCompleteCallback(); // this is called after the local callback
所以我们只抓住重定向,在successCallback失败后,并且可能由于收到的无效数据而导致JS错误。
So we only catch the redirect, after successCallback has failed, and possibly with JS errors due to the invalid data it received.
3。
如果 login_required
将返回403 AJAX请求:
3.
If login_required
would return 403 on AJAX requests:
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
,不执行此操作。
But login_required
just uses user_passes_test
which doesn't do this.
user_passes_test
有很多功能在那里,所以重新实现它不是一个好主意。
user_passes_test
has a lot of functionality in there, so it's not such a good idea to reimplement it.
处理AJAX调用超时的最佳方法是什么?
What's the best way to handle the timeouts for AJAX calls?
推荐答案
我将通过让您的会话超时方法检查是否使用AJAX请求来处理它。如果它是ajax,则返回一个没有授权(或403禁止或任何状态有意义)的状态代码为空的json字符串的 401
。接下来,在你的javascript中,绑定一个全局 ajaxError
处理程序,它检查该状态代码并正确处理它。
I would handle it by having your session timeout method check whether or not it is being requested with AJAX. If it is ajax, return a 401
not authorized(or 403 forbidden or whatever status makes sense) status code with an empty json string. Next, in your javascript, bind a global ajaxError
handler that checks for that status code and handles it appropriately.
这篇关于在ajax请求中处理会话超时的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!