HTML表单文件切片上传实战:Input type=file实现
作者:技术拾光时间:2026-07-27 08:28:33浏览:133
切片上传需开启multiple支持多文件,accept仅初筛;文件大小限制依赖JavaScript。进度条用语义化progress标签。推荐Blob.slice()与fetch()直传,避免FileReader大文件内存问题。
先说几个核心判断:multiple 属性是“不必须,但别省”
很多朋友写文件上传功能时,容易在 input[type="file"] 的 multiple 属性上犹豫:到底要不要加?加了才支持切片上传吗?
先说结论:不是必须的,但强烈建议打开。
不加 multiple,用户每次只能选一个文件,你后端再怎么写切片逻辑,每回都只能处理单个文件——这直接打断了批量上传的流程。而加上 multiple 后,用户一次能选多个文件,每个文件再独立切片,逻辑上更顺畅,用户操作也更自然。
一点细节:一旦开启 multiple,input.files 返回的是 FileList(类数组对象),而不是单个 File 对象。写遍历前最好确认一下长度:
const files = input.files;
for (let i = 0; i < files.length; i++) {
const file = files[i]; // 每个 file 都是 File 实例,可以 .slice()
}
- 不加
multiple也能切片,但那只是单文件场景,扩展性很差 File对象的slice()方法兼容 IE10+ 和所有现代浏览器,不用额外补丁- 千万别用
input.value来判断是否选中文件——它只返回文件名,且路径会被浏览器屏蔽。正确的做法是检查input.files.length > 0
文件选择范围与大小限制:HTML 只能做“初筛”,真拦截得靠 JS
HTML 层面并不能真正执行“切片”操作,但它能帮我们提前过滤掉明显不合规的文件,减少无效的 JS 处理和后续请求。关键靠 accept 属性和 JS 联合把关。
accept 控制文件类型,比如 accept="image/*,.pdf",但它只是提示性的,用户完全可以通过“全部文件”选项绕过。真正要拦截,还是得在 JS 里做:
input.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file && file.size > 500 * 1024 * 1024) { // 500MB
alert('文件超过 500MB,请压缩或分卷');
e.target.value = ''; // 清空 input,否则下次 change 不触发
}
});
几个要点:
accept的值尽量不要写死 MIME 类型,比如application/octet-stream,部分浏览器不识别。优先用扩展名或通用类型(如image/*)- 移动端 Safari 对
accept支持较弱,依赖 JS 校验更可靠 - 文件大小限制只能在 JS 里检查,HTML 的
max属性对type="file"无效
切片时的进度条和暂停按钮:必须用原生语义化元素
很多实现都直接拿 div 模拟进度条,简单是简单,但对辅助技术不友好。正确的做法是用 progress 标签和 formnovalidate 按钮。
是语义化的进度指示器,屏幕阅读器可以识别。暂停或取消操作应该绑定到 ,同时注意同步更新 disabled 状态:
几点建议:
- 不要用
