【问题标题】:Why should FormData be used when uploading a file via AJAX?为什么通过 AJAX 上传文件时要使用 FormData?
【发布时间】:2019-09-15 01:51:05
【问题描述】:

我有一个用户可以上传文件的表单:

<form enctype="multipart/form-data method="POST" id="cool-form-id">
    <input type="file" id="file" name="file">
</form>

我正在尝试使用 AJAX 请求从该表单上传文件:

    $.ajax({
          url: '/path/to/upload/',
          data: $("#cool-form-id").serialize(),
          processData: false,
          contentType: false,
          type: 'POST',
          success: function(data) {
            alert(data)
          }
      });

如果我检查由 $("#cool-form-id") 选择器获得的对象,我会看到有人选择了文件的表单和输入字段,但是在 serialize() 之后这个输入消失了(其他输入此表单中的字段按预期进行序列化。)

      var formData = new FormData($("#cool-form-id")[0]);

      $.ajax({
          url: '/path/to/upload/',
          data: formData,
          processData: false,
          contentType: false,
          type: 'POST',
          success: function(data) {
            alert(data)
          }
      });

我能够通过使用 FormData 对象来传递表单信息(如上所示)来解决此问题,但我无法弄清楚为什么我的原始计划不起作用(我的理解是 FormData 只是创建一系列键/值对)。

大多数引用 FormData 的问题都不是最新的,许多只是提供了一个工作示例。

我很好奇是否有人可以阐明以下任何或所有内容:

1) 为什么不能序列化()“文件”类型输入的表单数据?

2) FormData 有何不同之处使其在这种情况下工作?

3) FormData 是否仍然是您上传文件的唯一/最佳选择(假设您不想使用 iFrame)?

【问题讨论】:

  • FormData API 的创建使使用 XHR 发送文件成为可能。

标签: javascript jquery html


【解决方案1】:

为什么要通过 AJAX 上传文件时使用 FormData?

因为你不能以任何其他方式(除了 iframe hack)

1) 为什么不能序列化()“文件”类型输入的表单数据?

因为:

  • application/x-www-form-urlencoded 编码没有原生方式来表达文件
  • 文件输入的value 没有给出文件内容

serialize 可以重写为,例如,使用 FileList API 读取文件,然后将它们 base64 编码为 application/x-www-form-urlencoded 字符串(它可以但jQuery 没有这样做),然后任何读取数据的服务器端代码都必须解码 base64 数据。

2) FormData 有何不同之处使其在这种情况下工作?

它创建一个多部分/表单数据格式的正文并从文件输入中读取文件。

3) FormData 是否仍然是您上传文件的唯一/最佳选择(假设您不想使用 iFrame)?

这是唯一明智的选择。

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 2015-04-04
    • 2014-08-09
    • 1970-01-01
    • 2012-10-28
    相关资源
    最近更新 更多