使用javascript将上传的文件拆分为多个块

时间:2018-05-01 18:35:04

标签: javascript google-chrome base64 compression frontend

我正在寻找一种方法在浏览器中将前端上的任何文本/数据文件拆分为多个文件。我的限制是每次上传40KB。因此,如果用户上传400KB文件,它会将此文件拆分为前端的10个单独的块或10个单独的文件,然后再将其上载到服务器。

目前,我通过将此文件转换为base64格式的字符串来进行此操作,然后将此字符串拆分为40KB,该字符串分为10个单独的块。从那里我上传每个块,文件名为chunk-1-of-10,chunk-2-of-10 ...

当下拉这些文件时,我只是将所有这些块连接起来并将其从base64解压缩为其文件格式。

有更好的方法吗?是否有一个库来处理所有这些而不是从头开始编写它?我不确定base64路由是否是执行此操作的最佳方式。

2 个答案:

答案 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;
&#13;
&#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())
}