我有一个带有Rails / Devise服务器的Backbone.js客户端。
我想通过重定向实现注销流程。
这是我的客户端代码
$.ajax
url: "/sign_out"
xhrFields:
'X-CSRF-Token': $('meta[name=csrf-token]').attr('content')
type: "DELETE"
complete: xCompleteFunction = (XMLHttpRequest, textStatus) ->
#handle here?
请求由适当的控制器方法处理。然后我有
def after_sign_out_path_for(resource)
root_path
end
这是日志
[2012/12/11 15:44:07] (INFO) 76430 Started DELETE "/sign_out"
[2012/12/11 15:44:07] (INFO) 76430 Processing by Devise::SessionsController#destroy as */*
....
[2012/12/11 15:44:07] (INFO) 76430 Redirected to http://localhost:3000/
Hoverer,重定向由Rails控制器处理,实际上重定向使用相同的动词“DELETE”。
[2012/12/11 15:44:13] (INFO) 76430 Started DELETE "/"
[2012/12/11 15:44:13] (INFO) 76430 Processing by HomeController#index as */*
是否可以处理客户端上的重定向,并防止Rails控制器捕获它?由于ajax调用,我期待设计将301/302返回给客户端。
答案 0 :(得分:1)
我也在寻找这个问题的答案。在发送用于注销用户的第一个DELETE请求之后,我不确定处理第二个重定向设计。但是here我发现添加ajax初始化代码可以捕获401(未经授权的)响应,解决了这个问题。
$.ajaxSetup({
statusCode: {
401: function(){
// Redirect the to the login page.
location.href = "/admin/auth/sign_in";
}
}
});
希望它有所帮助。欢呼声。
答案 1 :(得分:1)
我实际上也遇到了同样的问题。可以覆盖Devise::SessionsController
,这就是我解决它的方式。
在Devise::SessionsController
内,有method #respond_to_on_destroy
实际进行重定向。通过覆盖它,它只有200秒。
class SessionsController < Devise::SessionsController
private
# We sign out using Ajax calls so we override this method to render plain
# text instead of redirecting unnecessarily
def respond_to_on_destroy
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { render plain: "Signed out" }
end
end
end
这有一个明显的问题,因为重写这样的私有方法并不好(使用它的实现可能会在没有我们意识到的情况下改变),但我找不到任何其他方法来很好地完成这项工作。如果Devise让你在这种情况下渲染而不是重定向,那就太棒了。
答案 2 :(得分:0)
这是因为默认情况下,您的Ajax调用跟随302('暂时移动')不是错误状态,而是如果存在位置标题,则重试第二个请求。
更改状态并重定向到js代码成功回调中的位置标头,或返回nil位置并在客户端处理重定向。
如果您想通过json和html区分登录,那么只需在控制器代码中的self.request.format.symbol上添加条件。