使用 FileReader 和 FormData 上传文件有什么区别?
What is the difference between file upload using FileReader and FormData?
我可以通过两种方式使用 Ajax (XHR2) 上传文件。首先,我可以将文件内容读取为数组缓冲区或二进制字符串,然后使用 XHR send
方法简单地流式传输。例如,作为 shown here:
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);
}
其次,我可以使用 FormData
将我的文件上传为 shown here:
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);
这两种方法是否等价?使用 FileReader
而不是 FormData
有什么优势吗?一个比另一个更高效吗?
首先,您省略了第三个选项,即直接通过 xhr.send(file)
发送文件,就像您对 ArrayBuffer 所做的那样。
也就是说,首先通过 FileReader 读取内存中的文件不存在任何可能的优势。
从磁盘上的文件上传文件时,浏览器不会在内存中加载完整文件,而是通过请求流它。这就是您可以上传千兆数据的方法,即使它不适合内存。这对 HDD 也更友好,因为它允许其他进程在每个块之间访问它而不是锁定它。
当通过 FileReader 读取文件时,您要求浏览器将 完整 文件读取到内存中,然后当您通过 XHR 发送它时,内存中的数据将被使用.因此,您受到可用内存的限制,无缘无故地膨胀,甚至要求 CPU 在这里工作,而数据几乎可以直接从磁盘传输到网卡。
至于formdata.append(file); xhr.send(formdata);
和xhr.send(file)
有什么区别,基本上只有请求头。前者会将请求包装成 multipart/form-data enctype 请求,而后者会按原样发送。
所以你会在接收端以不同的方式处理这两个请求。
我可以通过两种方式使用 Ajax (XHR2) 上传文件。首先,我可以将文件内容读取为数组缓冲区或二进制字符串,然后使用 XHR send
方法简单地流式传输。例如,作为 shown here:
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);
}
其次,我可以使用 FormData
将我的文件上传为 shown here:
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);
这两种方法是否等价?使用 FileReader
而不是 FormData
有什么优势吗?一个比另一个更高效吗?
首先,您省略了第三个选项,即直接通过 xhr.send(file)
发送文件,就像您对 ArrayBuffer 所做的那样。
也就是说,首先通过 FileReader 读取内存中的文件不存在任何可能的优势。
从磁盘上的文件上传文件时,浏览器不会在内存中加载完整文件,而是通过请求流它。这就是您可以上传千兆数据的方法,即使它不适合内存。这对 HDD 也更友好,因为它允许其他进程在每个块之间访问它而不是锁定它。
当通过 FileReader 读取文件时,您要求浏览器将 完整 文件读取到内存中,然后当您通过 XHR 发送它时,内存中的数据将被使用.因此,您受到可用内存的限制,无缘无故地膨胀,甚至要求 CPU 在这里工作,而数据几乎可以直接从磁盘传输到网卡。
至于formdata.append(file); xhr.send(formdata);
和xhr.send(file)
有什么区别,基本上只有请求头。前者会将请求包装成 multipart/form-data enctype 请求,而后者会按原样发送。
所以你会在接收端以不同的方式处理这两个请求。