我正在寻找一种方法在浏览器中将前端上的任何文本/数据文件拆分为多个文件。我的限制是每次上传40KB。因此,如果用户上传400KB文件,它会将此文件拆分为前端的10个单独的块或10个单独的文件,然后再将其上载到服务器。
目前,我通过将此文件转换为base64格式的字符串来进行此操作,然后将此字符串拆分为40KB,该字符串分为10个单独的块。从那里我上传每个块,文件名为chunk-1-of-10,chunk-2-of-10 ...
当下拉这些文件时,我只是将所有这些块连接起来并将其从base64解压缩为其文件格式。
有更好的方法吗?是否有一个库来处理所有这些而不是从头开始编写它?我不确定base64路由是否是执行此操作的最佳方式。
答案 0 :(得分:2)
您可以使用FileReader
然后以二进制发送方式避免使用base64编码:
const url = 'http://www.example.com/upload';
document.getElementById('file-uploader').addEventListener('change', function(e) {
const size = 40000;
var reader = new FileReader();
var buf;
var file = document.getElementById('file-uploader').files[0];
reader.onload = function(e) {
buf = new Uint8Array(e.target.result);
for (var i = 0; i < buf.length; i += size) {
var fd = new FormData();
fd.append('fname', [file.name, i+1, 'of', buf.length].join('-'));
fd.append('data', new Blob([buf.subarray(i, i + size)]));
var oReq = new XMLHttpRequest();
oReq.open("POST", url, true);
oReq.onload = function (oEvent) {
// Uploaded.
};
oReq.send(fd);
}
}
reader.readAsArrayBuffer(file);
});
&#13;
<input type="file" id="file-uploader"/>
&#13;
答案 1 :(得分:1)
无需使用FileReader将内容读入ram 使用base64只会增加上传内容的大小
使用Blob.slice获取数据块
// simulate a file from a input
const file = new File(['a'.repeat(1000000)], 'test.txt')
const chunkSize = 40000
const url = 'https://httpbin.org/post'
for (let start = 0; start < file.size; start += chunkSize) {
const chunk = file.slice(start, chunkSize + 1)
const fd = new FormData
fd.append('data', chunk, file.name);
await fetch(url, {method: 'post', body: fd}).then(res => res.text())
}