前端文件上传方案:告别原生 input type=file
现状与痛点
原生上传在处理大文件时往往显得力不从心。
各位前端同行,咱们今天聊聊前端文件上传。别告诉我你还在用原生的 input 上传大文件,那感觉就像在用小水管灌满游泳池——慢得让人绝望。
为什么你需要文件上传方案
最近看到一个项目,上传 100MB 的文件直接卡死浏览器,没有任何进度提示,用户体验极差。我就想问:你是在做上传还是在做浏览器杀手?
反面教材
<!-- 反面教材:原生文件上传 -->
<input type="file" onchange="uploadFile(this.files[0])" />
<script>
function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
// 直接上传,没有进度,没有断点续传
fetch('/api/upload', {
method: 'POST',
body: formData
});
}
</script>
技术点评:这种写法在大文件场景下会导致主线程阻塞,且无法感知进度,用户只能干等。
前端文件上传的正确姿势
1. 分片上传
// 正确姿势:分片上传
class ChunkUploader {
constructor(file, options = {}) {
this.file = file;
this.chunkSize = options.chunkSize || 1024 * 1024; // 1MB
. = .(file. / .);
. = ;
}
() {
promises = [];
( i = ; i < .; i++) {
start = i * .;
end = .(start + ., ..);
chunk = ..(start, end);
promises.(.(chunk, i));
}
.(promises);
.();
}
() {
formData = ();
formData.(, chunk);
formData.(, index);
formData.(, .);
formData.(, ..);
(, {
: ,
: formData
});
.++;
.(. / .);
}
() {
.();
}
() {
(, {
: ,
: { : },
: .({ : .., : . })
});
}
}
uploader = (file, { : * });
uploader.();


