首页 > 解决方案 > 在表单中附加文件会导致 InvalidAuthenticityToken 错误和 UnknownFormat 错误

问题描述

我应该使用Carrierwave gem提交图像文件的表单发生了一些奇怪的事情。这是表格:

<% @post = Post.new %>
<%= form_for @post, url: create_post_path(@post), :html => {multipart: true}, remote: true do |f| %>
  <%= f.file_field :images, multiple: true %>
  <%= f.submit "submit" %>
<% end %>

这是控制器:

def create_post
  @post = Post.new(post_params)
  @post.save
  respond_to do |format|
    format.js
  end
end

private

def post_params
  params.require(:post).permit({images: []})
end

这是我得到的第一个错误:

ActionController::InvalidAuthenticityToken in PostsController#create_post ActionController::InvalidAuthenticityToken

如果我通过将此行添加到表单中手动设置令牌,此错误就会消失:

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

但后来我得到这个错误:

PostsController#create_post
ActionController::UnknownFormat 中的 ActionController::UnknownFormat

将此行突出显示为有问题的:

respond_to do |format|

如果我删除此行,两个错误都会消失:

<%= f.file_field :images, multiple: true %>

没有该行,表单将正常提交。我使用 Carrierwave 文件提交编写了许多表单,但从未遇到过任何这些问题。我在同一个应用程序中还有其他表单,除了文件提交字段外,其他所有表单都相同,它们工作正常。这是怎么回事?

更新

我认为这不仅仅是身份验证问题或提交为 JS 的问题。手动添加身份验证令牌修复了一个错误,但是我写了很多表单,包括 AJAX 文件提交表单,都没有这样的错误,而且我也无法理解为什么添加文件会影响真实性令牌,所以我想更深层次的东西是错的。

更新 2

事实证明,它与 Carrierwave 或创建的带有附加图像的 Post 无关,而是与提交的包含文件的参数无关。当我使用香草文件上传输入时,错误仍然存​​在:

<%= file_field_tag "form_images", multiple: true %>

但是,如果我将文件上传留空并在create_post操作中使用 binding.pry 来设置帖子的图像属性,那么一切都没有问题。

但它变得更奇怪了:即使我手动设置了真实性令牌,然后将create_post操作重定向到不同的操作,然后尝试执行 a respond_to,我仍然会收到 UnknownFormat 错误。同样,如果发送到的参数create_post不包含文件,我不会收到此错误。

<% @post = Post.new %>
<%= form_for @post, url: create_post_path(@post), :html => {multipart: true}, remote: true, authenticity_token: true do |f| %>
  <%= file_field_tag "test_images", multiple: true %>
  <%= f.submit "submit" %>
<% end %>

控制器:

def create_post
  @post = Post.new(post_params)
  binding.pry #If I leave the file input blank but then set the @post.images here, I get no errors whatsoever.
  @post.save
  redirect_to continue_path(@post.id)
end

def continue
  @post = Post.find(params[:post])
  respond_to do |format| #If I set the authenticity token manually, I still get the UnknownFormat error on this line.
    format.js
  end
end

private

def post_params
  params.require(:post).permit({images: []})
end

标签: ruby-on-railsrubyfile-uploadcarrierwaveauthenticity-token

解决方案


如果您希望表单作为 js 提交,那么我可以使用以下 gem 来解决这个问题。

gem remotipart

远程部分


推荐阅读