如何使用 Webpack 在 Rails6 中提交 ajax 表单?收到 ActionController::InvalidAuthenticityToken 错误
How to submit ajax form in Rails 6 with Webpack? Getting ActionController::InvalidAuthenticityToken error
所有!
我正在观看 Go 上的视频Rails,了解如何使用动作电缆制作聊天应用程序。在视频中,我相信正在使用 Rails 5,但是,我想用 Rails 6.
试试看
到目前为止一切都很顺利。安装了 Bootstrap 和 jQuery 并正确配置了我的 environments.js
文件。太棒了。然后我在添加动作电缆之前进入部分,我们将聊天室形式设置为 remote: true.
我不明白为什么我的表单仍试图以 HTML 而不是 JS 提交。最重要的是,我收到 ActionController::InvalidAuthenticityToken
错误。
这是我设置表单的方式:
<%= simple_form_for [@chatroom, Message.new], remote: true, html: { id: 'message-input' } do |f| %>
<%= f.input :body, label: false, input_html: { rows: 1, autofocus: true } %>
<% end %>
当我提交时,我的 rails 服务器出现这个错误:
Started POST "/chatrooms/1/messages" for ::1 at 2019-10-16 21:02:01 -0500
Processing by MessagesController#create as HTML
Parameters: {"message"=>{"body"=>"test3"}, "chatroom_id"=>"1"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 968)
ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
Started POST "/__better_errors/cf3c4e5c6fa2d1b1/variables" for ::1 at 2019-10-16 21:02:01 -0500
不知道该怎么做。我用谷歌搜索并发现了这个,但我不确定它是否完全适用:
如有任何帮助,我们将不胜感激!
请求时 POST
请求 rails 会 authenticity_token
检查。
在 javascript 的请求中,您需要添加 header:'X-CSRF-Token': csrfToken
。
你可以通过以下JS获得csrfToken
:
const csrfToken = document.querySelector('[name="csrf-token"]').getAttribute('content');
另一个解决方案是禁用 verify_authenticity_token
,您可以将其添加到您的 application_controller.rb
以禁用它,或者您可以将其添加到特定控制器:
skip_before_action :verify_authenticity_token
所以,我必须使用 form_with
而不是 form_for
才能让它作为 JS 处理。我想 form_for
正在减慢被弃用的速度?
我的表单现在看起来像这样:
<%= form_with(model: [@chatroom, Message.new]) do |f| %>
<%= f.text_field :body %>
<% end %>
并且输出是我所期望的,无需使用 JS 提交 CSRF 令牌或跳过控制器中的之前操作。
Started POST "/chatrooms/1/messages" for ::1 at 2019-10-18 20:15:14 -0500
Processing by MessagesController#create as JS
Parameters: {"authenticity_token"=>"xPBQ+4LOS5aMa7PQ3HEGXAMX6wIIEfQ0Izy/xUqUtleK4mB18IYxC4mOcIoiS5M+FGm6J/WEYMdbM4IVPojScw==", "message"=>{"body"=>"test 5"}, "chatroom_id"=>"1"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 1], ["LIMIT", 1]]
Chatroom Load (0.3ms) SELECT "chatrooms".* FROM "chatrooms" WHERE "chatrooms"."id" = LIMIT [["id", 1], ["LIMIT", 1]]
↳ app/controllers/messages_controller.rb:19:in `set_chatroom'
(0.1ms) BEGIN
↳ app/controllers/messages_controller.rb:12:in `create'
Message Create (0.7ms) INSERT INTO "messages" ("chatroom_id", "user_id", "body", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["chatroom_id", 1], ["user_id", 1], ["body", "test 5"], ["created_at", "2019-10-19 01:15:14.619853"], ["updated_at", "2019-10-19 01:15:14.619853"]]
↳ app/controllers/messages_controller.rb:12:in `create'
(5.6ms) COMMIT
↳ app/controllers/messages_controller.rb:12:in `create'
Redirected to http://localhost:3000/chatrooms/1
Completed 200 OK in 17ms (ActiveRecord: 7.6ms | Allocations: 4690)
所有!
我正在观看 Go 上的视频Rails,了解如何使用动作电缆制作聊天应用程序。在视频中,我相信正在使用 Rails 5,但是,我想用 Rails 6.
试试看到目前为止一切都很顺利。安装了 Bootstrap 和 jQuery 并正确配置了我的 environments.js
文件。太棒了。然后我在添加动作电缆之前进入部分,我们将聊天室形式设置为 remote: true.
我不明白为什么我的表单仍试图以 HTML 而不是 JS 提交。最重要的是,我收到 ActionController::InvalidAuthenticityToken
错误。
这是我设置表单的方式:
<%= simple_form_for [@chatroom, Message.new], remote: true, html: { id: 'message-input' } do |f| %>
<%= f.input :body, label: false, input_html: { rows: 1, autofocus: true } %>
<% end %>
当我提交时,我的 rails 服务器出现这个错误:
Started POST "/chatrooms/1/messages" for ::1 at 2019-10-16 21:02:01 -0500
Processing by MessagesController#create as HTML
Parameters: {"message"=>{"body"=>"test3"}, "chatroom_id"=>"1"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 968)
ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
Started POST "/__better_errors/cf3c4e5c6fa2d1b1/variables" for ::1 at 2019-10-16 21:02:01 -0500
不知道该怎么做。我用谷歌搜索并发现了这个,但我不确定它是否完全适用:
如有任何帮助,我们将不胜感激!
请求时 POST
请求 rails 会 authenticity_token
检查。
在 javascript 的请求中,您需要添加 header:'X-CSRF-Token': csrfToken
。
你可以通过以下JS获得csrfToken
:
const csrfToken = document.querySelector('[name="csrf-token"]').getAttribute('content');
另一个解决方案是禁用 verify_authenticity_token
,您可以将其添加到您的 application_controller.rb
以禁用它,或者您可以将其添加到特定控制器:
skip_before_action :verify_authenticity_token
所以,我必须使用 form_with
而不是 form_for
才能让它作为 JS 处理。我想 form_for
正在减慢被弃用的速度?
我的表单现在看起来像这样:
<%= form_with(model: [@chatroom, Message.new]) do |f| %>
<%= f.text_field :body %>
<% end %>
并且输出是我所期望的,无需使用 JS 提交 CSRF 令牌或跳过控制器中的之前操作。
Started POST "/chatrooms/1/messages" for ::1 at 2019-10-18 20:15:14 -0500
Processing by MessagesController#create as JS
Parameters: {"authenticity_token"=>"xPBQ+4LOS5aMa7PQ3HEGXAMX6wIIEfQ0Izy/xUqUtleK4mB18IYxC4mOcIoiS5M+FGm6J/WEYMdbM4IVPojScw==", "message"=>{"body"=>"test 5"}, "chatroom_id"=>"1"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 1], ["LIMIT", 1]]
Chatroom Load (0.3ms) SELECT "chatrooms".* FROM "chatrooms" WHERE "chatrooms"."id" = LIMIT [["id", 1], ["LIMIT", 1]]
↳ app/controllers/messages_controller.rb:19:in `set_chatroom'
(0.1ms) BEGIN
↳ app/controllers/messages_controller.rb:12:in `create'
Message Create (0.7ms) INSERT INTO "messages" ("chatroom_id", "user_id", "body", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["chatroom_id", 1], ["user_id", 1], ["body", "test 5"], ["created_at", "2019-10-19 01:15:14.619853"], ["updated_at", "2019-10-19 01:15:14.619853"]]
↳ app/controllers/messages_controller.rb:12:in `create'
(5.6ms) COMMIT
↳ app/controllers/messages_controller.rb:12:in `create'
Redirected to http://localhost:3000/chatrooms/1
Completed 200 OK in 17ms (ActiveRecord: 7.6ms | Allocations: 4690)