由于previous issue,我必须从application.js中删除//= require jquery_ujs
现在,我需要使用axios将a /users/sign_out
方法替换为ajax。以下是我的代码:
axios.delete("users/sign_out", {
headers: {
"X-CSRF-Token": $('meta[name="csrf-token"]').attr('content') },
params: {
"authenticity_token": $('meta[name="csrf-token"]').attr('content')
}
})
.then(function(response) {
alert(response)
})
.catch(function(error) {
alert(error)
})
服务器日志显示有一个DELETE" /"在删除" / users / sign_out"之后。这是不正确的。
Started DELETE "/users/sign_out?authenticity_token=mHQ3d4lJzDNS5TSWEFkDZ%2F3fI0vTDFxW6CabEffaNk6h2JRYNk8kkgCSBOXFdHmgDKcVtY8e29aGU%2F3q9gajWA%3D%3D" for 127.0.0.1 at 2017-08-01 20:59:55 +0800
Processing by Devise::SessionsController#destroy as HTML
Parameters: {"authenticity_token"=>"mHQ3d4lJzDNS5TSWEFkDZ/3fI0vTDFxW6CabEffaNk6h2JRYNk8kkgCSBOXFdHmgDKcVtY8e29aGU/3q9gajWA=="}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
(0.2ms) BEGIN
(0.2ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 8ms (ActiveRecord: 0.9ms)
**Started DELETE "/" for 127.0.0.1 at 2017-08-01 20:59:55 +0800**
ActionController::RoutingError (No route matches [DELETE] "/"):
答案 0 :(得分:5)
TL; DR - 在初始值设定项/ devise.rb中设置config.sign_out_via = :get
请求DELETE /users/sign_out
时,设计为responding from the server with a redirect_to
。 rails redirect_to
使用的默认HTTP状态代码为302 Found
。 302
状态最初是为了表明浏览器应该使用相同的方法重试相同的请求,但许多浏览器在早期就已经将这种请求更改为{{{ 1}}自动(参见RFC 1945 Note regarding 302 Moved Temporarily
)
Rails docs for redirect_to
也有一个关于此的注释,因为它与通过AJAX的非标准HTTP请求方法有关:
如果您使用GET或POST以外的XHR请求并在请求后重定向,则某些浏览器将使用原始请求方法跟踪重定向。这可能会导致不良行为,例如双重删除。
解决方案是返回GET
,如下所示:303 See Other
。我已经找到了为redirect_to resource_path, status: 303
设置HTTP状态的方法,目前在Devise API中似乎不存在。
但是,您可以告诉Devise使用GET作为在Devise初始化程序中注销的请求方法:
Devise::SessionsController#destroy
现在,当您访问注销链接时,您应该在服务器日志中看到# in initializers/devise.rb
Devise.setup do |config|
. . .
config.sign_out_via = :get
. . .
end
,浏览器重定向也应该使用GET。
我用来研究这个问题的其他一些资源:
答案 1 :(得分:0)
您还可以通过确保 axios
请求具有带有 Accept
的 'application/json'
标头来解决此问题。正如在会话控制器的 devise source code 中所见:
def respond_to_on_destroy
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
end
end
这意味着它应该对任何非导航格式响应 head :no_content
,避免重定向。