在表单中附加文件会导致InvalidAuthenticityToken错误和UnknownFormat错误

时间:2018-08-13 02:54:20

标签: ruby-on-rails ruby file-upload carrierwave authenticity-token

我的表单有些奇怪,应该使用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

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

  

PostsController#create_post中的ActionController :: InvalidAuthenticityToken   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设置帖子的images属性,一切都会顺利进行。

但是这很奇怪:即使我手动设置了真实性令牌,然后将create_post操作重定向到另一个操作,然后尝试执行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

1 个答案:

答案 0 :(得分:0)

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

gem remotipart

remotipart