使用axios在rails上删除重复方法

时间:2017-08-01 13:01:30

标签: ruby-on-rails axios

由于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] "/"):

2 个答案:

答案 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 Found302状态最初是为了表明浏览器应该使用相同的方法重试相同的请求,但许多浏览器在早期就已经将这种请求更改为{{{ 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,避免重定向。