我有一个控制器:
class SessionTimeoutController < ApplicationController
# snip
skip_before_filter :authenticate_user!, only: [:has_user_timed_out]
#snip
# Determines whether the user has been logged out due to
# inactivity or not.
def has_user_timed_out
@has_timed_out = (!user_signed_in?) or (current_user.timedout? (user_session["last_request_at"]))
respond_to do |format|
format.json { render json: @has_timed_out, status: :created}
end
end
#snip
end
我发送一个session_timeout/has_user_timed_out
使用 AJAX 的请求:
$.ajax({
url: '/session_timeout/has_user_timed_out',
type: 'GET',
dataType: 'json',
success: function( logged_out ) {
if(logged_out === true)
{
window.location = '/users/sign_in?timedout=1'
}
else
{
checkTimeLeft();
}
}
});
进行此 AJAX 调用时,我希望它始终得到响应,即使用户注销也是如此。我期望这是因为我skip_before_filter :authenticate_user!
在控制器中设置。但是,当我发送 AJAX 时,服务器会发回401 Unauthorized
响应。为什么是这样?
此外,当我从浏览器控制台运行这个 JS 时,它按预期工作。唯一一次我的 AJAX 有问题是从视图中调用它时。
$.ajax({url: '/session_timeout/has_user_timed_out', type: 'GET', dataType:'JSON', success: function(logged_out) {console.log(logged_out + ' ' + typeof logged_out);}});
可能导致问题的一件事是,我在用户由于不活动而自动注销的瞬间发送了 AJAX 请求。这会让设计者感到困惑吗?
编辑:当我发送导致 401 响应的请求时,这是我的 Rails 日志:
Started GET "/session_timeout/has_user_timed_out" for 10.0.2.2 at 2013-07-25 21:25:51 +0000
Processing by SessionTimeoutController#has_user_timed_out as JSON
ConfigVar Load (0.2ms) SELECT `config_vars`.* FROM `config_vars` WHERE `config_vars`.`name` = 'maintenance_mode' ORDER BY `config_vars`.`id` ASC LIMIT 1
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 14 ORDER BY `users`.`id` ASC LIMIT 1
Completed 401 Unauthorized in 4ms
这是我发送有效请求时的 Rails 日志,即使用户已注销:
Started GET "/session_timeout/has_user_timed_out" for 10.0.2.2 at 2013-07-25 21:29:39 +0000
Processing by SessionTimeoutController#has_user_timed_out as JSON
ConfigVar Load (0.1ms) SELECT `config_vars`.* FROM `config_vars` WHERE `config_vars`.`name` = 'maintenance_mode' ORDER BY `config_vars`.`id` ASC LIMIT 1
Completed 201 Created in 3ms (Views: 0.1ms | ActiveRecord: 0.1ms)
再玩一下,看起来我第一次session_timeout/has_user_timed_out
在用户注销后发送请求,无论我等待多长时间,它都会失败。然后,所有后续请求都成功。