使用javascript将上传的文件分割成多个块

问题描述 投票:0回答:2

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

目前,我正在通过将此文件转换为 Base64 格式的字符串,然后将此字符串分割为 40KB,将其分成 10 个单独的块。从那里我上传每个块,文件名为 chunk-1-of-10、chunk-2-of-10...

当拉下这些文件时,我只需将所有这些块连接回去并将其从 Base64 反转换为其文件格式。

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

javascript google-chrome base64 compression frontend
2个回答
29
投票

无需使用FileReader将内容读取到ram中 使用base64只会增加您需要上传的内容的大小,base64占用约33%的大小

使用 Blob.slice 获取块

blob 切片(块)不会增加内存,它只会创建对旧 blob 的新引用,并更改偏移量和新的大小,以从其开始读取的位置。

fetch
发送数据时,它将直接从磁盘传输到网络,甚至不接触主线程。

// 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, start + chunkSize)
  const fd = new FormData()
  fd.set('data', chunk)
  
  await fetch(url, { method: 'post', body: fd }).then(res => res.text())
}

4
投票

您可以使用

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);
});
<input type="file" id="file-uploader"/>

© www.soinside.com 2019 - 2024. All rights reserved.