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

时间:2019-04-25 15:10:13

标签: javascript jquery html5

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

<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)吗?

1 个答案:

答案 0 :(得分:5)

  

为什么通过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)吗?

这是唯一明智的选择。