- 项目中有个系统更新的需求, 又不能整个文件上传,如果文件特别大,几个G大小,会直接把内存占满,卡死. 需求是,把整个文件分批发送, 后台拿到一部分 用一部分,然后就"扔"掉.这样即完成了系统更新,又不会把内存卡死
下面是解决方法, 后端同事丢给我的js版本,用Vue的写法改造了一下, 亲测有效!
有大神看懂的可以解释下:
HTML代码:
<el-button type="primary" @click="$refs.file.click()">上传<i class="el-icon-upload el-icon--right"></i></el-button>
<input
type="file"
id="el1"
ref="file"
@change="change"
style="display: none"
/>
<el-button class="shengji" type="primary" @click="shengji">升级</el-button>
JS代码:
data() {
return {
setStatus: "",
f: "",
};
},
methods: {
sendFileData(name, data, chunkSize) {
var sendChunk = (offset) => {
this.jindu = (offset / data.length) * 100;
var chunk = data.subarray(offset, offset + chunkSize) || "";
var opts = { method: "POST", body: chunk };
var url =
"/upload?offset=" + offset + "&name=" + encodeURIComponent(name);
this.setStatus =
"sending bytes " +
offset +
".." +
(offset + chunk.length) +
" of " +
data.length;
// console.log(data);
fetch(url, opts).then(function () {
// console.log(res);
if (chunk.length > 0) sendChunk(offset + chunk.length);
});
};
sendChunk(0);
},
change(ev) {
if (!ev.target.files[0]) return;
let ff = ev.target.files[0];
this.f = ev.target.files[0];
let r = new FileReader();
r.readAsArrayBuffer(ff);
// r.onload = () => {
// ev.target.value = "";
// this.sendFileData(f.name, new Uint8Array(r.result), 4096);
// };
// this.jindu = 0; // 也是进度条, 再次上传,进图条归零
},
shengji() {
// console.log(this.f.size);
// this.tiji = this.f.size; // 这块是 为了计算文件大小, 写上传进度条用的
let r = new FileReader();
r.readAsArrayBuffer(this.f);
r.onload = () => {
// ev.target.value = ""; // 不知道这块为啥报错,但注释了对上传又没影响
this.sendFileData(this.f.name, new Uint8Array(r.result), 4096); // 应该是每次上传4096KB(4Mb)的文件
};
},
},
这是从上一篇js版本文章改编过来的,本来文件上传成功到浏览器后,自动触发,更新到浏览器. 为了确认文件,又加了手动上传提交的按钮.