- 项目中有个系统更新的需求, 又不能整个文件上传,如果文件特别大,几个G大小,会直接把内存占满,卡死. 需求是,把整个文件分批发送, 后台拿到一部分 用一部分,然后就"扔"掉.这样即完成了系统更新,又不会把内存卡死
下面是js解决方法, 后端同事丢给我的,有大神看懂的可以解释下:
HTML代码
<div id="wrapper">
<input type="file" id="el1" style="display: none"/>
<button id="el2">choose file...</button>
<div id="el3"></div>
</div>
JS代码
// 用于显示上载状态的助手函数
var setStatus = function(text) {
document.getElementById('el3').innerText = text; // 显示拼接后的文件名字+进度,大小等
};
// 当用户单击按钮时,触发文件选择对话框
var button = document.getElementById('el2');
button.onclick = function(ev) {
input.click();
};
// 逐块发送一大块数据
var sendFileData = function(name, data, chunkSize) {
var sendChunk = function(offset) {
var chunk = data.subarray(offset, offset + chunkSize) || '';
var opts = {method: 'POST', body: chunk};
var url = '/upload?offset=' + offset + '&name=' + encodeURIComponent(name); // upload 路径
setStatus(
'sending bytes ' + offset + '..' + (offset + chunk.length) + ' of ' +
data.length);
fetch(url, opts).then(function(res) {
if (chunk.length > 0) sendChunk(offset + chunk.length);
});
};
sendChunk(0);
};
// 若用户选择了一个文件,则将其读入内存并触发sendFileData()
var input = document.getElementById('el1');
input.onchange = function(ev) {
if (!ev.target.files[0]) return;
var f = ev.target.files[0], r = new FileReader();
r.readAsArrayBuffer(f);
r.onload = function() {
ev.target.value = '';
sendFileData(f.name, new Uint8Array(r.result), 4096);
};
};