複数のファイルとしてアップロードする前に、ブラウザのフロントエンドでテキスト/データファイルを分割する方法を探しています。私の制限はアップロードごとに40KBです。したがって、ユーザーが400KBのファイルをアップロードすると、サーバーにアップロードする前に、このファイルがフロントエンドで10個の個別のチャンクまたは10個の個別のファイルに分割されます。
現在、このファイルをbase64形式の文字列に変換し、この文字列を40KBで分割して、10個の個別のチャンクに変換しています。そこから、chunk-1-of-10、chunk-2-of-10のファイル名のように各チャンクをアップロードします...
これらのファイルをプルダウンするときは、これらすべてのチャンクを連結して、base64からファイル形式に逆変換します。
これを行うためのより良い方法はありますか?ゼロから作成するのではなく、これらすべてを処理するライブラリはありますか? base64ルートがこれを行うための最良の方法であるかどうかはわかりません。
Base64を使用してFileReaderでコンテンツをRAMに読み込む必要はありません。アップロードする必要があるもののサイズが増えるだけです。
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, start + chunkSize + 1)
const fd = new FormData()
fd.append('data', chunk)
await fetch(url, {method: 'post', body: fd}).then(res => res.text())
}
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"/>