使用FileReader和FormData上传文件有什么区别?

Har*_*til 5 javascript ajax filereader

我可以通过两种方式使用 Ajax (XHR2) 上传文件。首先,我可以将文件内容读取为数组缓冲区或二进制字符串,然后使用 XHRsend方法简单地进行流式传输。例如,如下所示

function uploadFile(img, file) {
  const reader = new FileReader();
  const xhr = new XMLHttpRequest();

  xhr.upload.addEventListener("progress", function(e) {
        if (e.lengthComputable) {
          const percentage = Math.round((e.loaded * 100) / e.total);
          // Do something with percentage
        }
      });

  xhr.upload.addEventListener("load", (e) => console.log('Do something more'));

  xhr.open("POST", "some-url");
  xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');

  reader.onload = function(evt) {
    xhr.send(evt.target.result);
  };
  reader.readAsBinaryString(file);
}

Run Code Online (Sandbox Code Playgroud)

其次,我可以用来FormData上传我的文件,如下所示

var formData = new FormData();

// HTML file input, chosen by user
formData.append("userfile", fileInputElement.files[0]);

var request = new XMLHttpRequest();

request.open("POST", "some-url");

request.send(formData);
Run Code Online (Sandbox Code Playgroud)

这两种方法等效吗?FileReader使用代替有什么优点吗FormData?其中一个比另一个性能更好吗?

Kai*_*ido 8

首先,您省略了第三个选项,即直接发送文件,xhr.send(file)就像您对 ArrayBuffer 所做的那样。

话虽这么说,首先通过 FileReader 读取内存中的文件并不存在任何可能的优势。


从磁盘上的文件上传文件时,浏览器不会将完整文件加载到内存中,而是通过请求将其流式传输。通过这种方式,您可以上传大量数据,即使内存无法容纳这些数据。这对于 HDD 也更加友好,因为它允许其他进程在每个块之间访问它,而不是锁定它。

当通过 FileReader 读取文件时,您要求浏览器将完整文件读取到内存中,然后当您通过 XHR 发送它时,将使用内存中的数据。因此,你会受到可用内存的限制,无缘无故地让内存膨胀,甚至要求 CPU 在这里工作,而数据几乎可以直接从磁盘传输到网卡。


formdata.append(file); xhr.send(formdata);至于和之间有什么区别xhr.send(file),基本上只是请求头。前者会将请求包装为multipart/form-data enctype 请求,而后者将按原样发送。
因此,您将在接收端以不同的方式处理这两个请求。