3

我正在尝试使用 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.

在 Remotipart Github 上有一个问题

4

1 回答 1

5

经过大量的调试和阅读大量代码后,我终于有了与 Rails 3.2.8 配合使用的最新 gem。我被三个陷阱钉住了:

(1) 我在提交表单之前禁用了我的文件输入字段,这导致 remotipart 忽略它以包含在 iframe 提交中。您必须确保您的文件输入已启用。这是您看到的错误的直接原因。

(2) 在我的调试过程中,我jquery.iframe-transport用最新的上游源代码覆盖,它不支持X-Http-Acceptsiframe 中的隐藏变量。您必须使用与 remotipart gem 捆绑的版本。

(3) 如果您使用的数据类型不是script. 如果您未在全局 ajax 选项中指定 dataType 或在表单上使用 data-type 属性,则这是默认设置。

于 2012-11-07T08:06:57.380 回答