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

Javascript 为什么在通过AJAX上传文件时要使用FormData?,javascript,jquery,html,Javascript,Jquery,Html,我有一个用户可以上传文件的表单: <form enctype="multipart/form-data method="POST" id="cool-form-id"> <input type="file" id="file" name="file"> </form> 如果我检查由$(“#cool form id”)选择器获得的对象,我会看到表单&输入字段,其中有人选择了一个文件,但在serialize()之后,该输入消失了(此表单中的其他输入字段按

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

<form enctype="multipart/form-data method="POST" id="cool-form-id">
    <input type="file" id="file" name="file">
</form>
如果我检查由$(“#cool form id”)选择器获得的对象,我会看到表单&输入字段,其中有人选择了一个文件,但在serialize()之后,该输入消失了(此表单中的其他输入字段按预期序列化)

我可以通过使用FormData对象来传递表单信息(如上所示)来解决这个问题,但我很难弄清楚为什么我的原始计划不起作用(据我所知,FormData只创建了一系列键/值对)

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

我很好奇,是否有人能对以下任何或所有问题提供一些线索:

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

2) FormData有什么不同之处导致它在这种情况下工作

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

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

因为你不能用任何其他的方法(除了iframe hack)

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

因为:

  • application/x-www-form-urlencoded编码没有表示文件的本机方式
  • 文件输入的
    不会给出文件内容
serialize
可以重写为,例如,使用FileList API读取文件,然后将其base64编码为应用程序/x-www-form-urlencoded字符串(可以,但jQuery没有这样做),然后读取数据的任何服务器端代码都必须解码base64数据

2) FormData有什么不同之处导致它在这种情况下工作

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

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


这是唯一明智的选择。

创建
FormData
API是为了使使用XHR发送文件成为可能。
    $.ajax({
          url: '/path/to/upload/',
          data: $("#cool-form-id").serialize(),
          processData: false,
          contentType: false,
          type: 'POST',
          success: function(data) {
            alert(data)
          }
      });
      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)
          }
      });