【发布时间】:2012-10-25 22:20:47
【问题描述】:
我正在尝试使用 ajax 将文件上传到我的 Rails 应用程序。为方便起见,我添加了jQuery.remotipart gem。
// app/assets/javascripts/application.js
//= require jquery.remotipart
我有一个上传文件的表格。这些文件由 CarrierWave 处理。
<%= form_for @import, remote: true do |f| %>
<fieldset>
<%= f.label :file, "Attach a CSV file" %>
<%= f.file_field :file %>
</fieldset>
<%= f.submit :upload %>
<% end -%>
不幸的是,当我提交附有文件的表单时,它似乎没有正确到达我的控制器操作。 params 哈希将 JS 对象字符串化为键。
Started POST "/file_imports" for 127.0.0.1 at 2012-11-06 01:00:49 +0000
Processing by FileImportsController#create as JS
Parameters: {"object Object"=>{","=>{"object Object"=>{","=>{"object Object"=>nil}}}}}`
在 Chrome 的开发工具中,我可以看到这确实是正在发送到服务器的表单数据:
当我删除 remote: true 时,表单可以完美运行(当然,在这种情况下,它发送的是 HTML 请求而不是 JS 请求)。
有人知道我做错了什么吗?顺便说一句,我使用的是 Rails 3.2.8 和 Remotipart 1.0.2(最新)。
编辑:做了更多的挖掘工作。
查看 Remotipart 源,我似乎无法理解它应该做什么。例如,在vendor/assets/javascripts/jquery.remotipart.js 中,第 22 行有以下内容:
settings.data = form.serializeArray();
再往下一点,设置通过$.rails.ajax(settings)发送到服务器。
$.fn.serializeArray() 方法返回一个 JS 对象数组。如果我们将它们分配给对jQuery.ajax() 的调用的数据属性,这将解释我在服务器上看到的序列化对象参数。我们需要传递一个对象作为数据属性,而不是一个对象数组?
但是,当我尝试将数组扁平化为一个对象时,整个事情都会中断,并且会向服务器发送 HTML 请求而不是 JS 请求。我认为这与jQuery.ajax.processData == false 的事实有关。
【问题讨论】:
-
参数看起来真的很糟糕。您确定所有先决条件的 javascript 都已加载吗?你也不需要清单中的所有路径,单独的 application.js 应该没问题。
-
清单中的注释实际上并不存在,我只是想指出
//= require jquery.manifest位于应用程序的哪个文件中。对于混淆表示歉意。我确定我需要一切。我有jquery,然后是jquery_ujs,然后是jquery.remotipart。 -
没问题。一切看起来都是正确的。您在原始帖子中说“一个文件”,但 remotipart 完全是关于“多部分”上传。您是否考虑过删除“remotipart”gem 并试图让基本文件上传与“单个”文件上传一起工作?那么,一旦你了解了单个文件上传的基本机制,然后引入'remoteipart'来处理同一个帖子中的多个文件上传?
-
是的,我可能应该在问题中提及它,但如果我从表单中删除
remote: true则它工作正常(仅适用于 HTML 请求而不是 JS)。我在 Remotipart Github 上看不到任何表明它不适用于单数上传的内容。
标签: javascript jquery ruby-on-rails file-upload ruby-on-rails-3.2