fileinput 元素仅用于本地文件选择,不自动上传;需配合 form(enctype="multipart/form-data")提交,或用 JavaScript 读取 files 构造 FormData 并 fetch 上传,且须校验类型、大小,服务端字段名与 Nginx 配置须匹配。

fileinput 元素本身不支持直接上传,必须配合 form 和 submit 或 JavaScript 手动提交
很多人以为 点选文件后就自动上传了,其实它只是本地文件选择控件,不触发任何网络请求。真正上传需要:
– 封装在 中并提交;
– 或用 JavaScript 读取 input.files[0],构造 FormData,再用 fetch 或 XMLHttpRequest 发送。
form 表单上传必须设置 enctype="multipart/form-data"
如果漏掉这个属性,服务端收不到文件字段,request.files(如 Flask)或 $_FILES(PHP)会为空,且浏览器可能静默降级为 application/x-www-form-urlencoded,只传文件名不传内容。
JavaScript 上传时别忘了把文件塞进 FormData,且不能用 JSON.stringify
FormData 是二进制友好的容器,直接 append 文件对象即可;若错误地把 FormData 转成 JSON(比如 JSON.stringify(new FormData())),会得到空对象或报错,因为 FormData 不可序列化。
- ✅ 正确:
formData.append("file", input.files[0]) - ❌ 错误:
JSON.stringify(formData)或fetch(url, { body: formData })却没设headers(其实不用设,fetch会自动设置正确Content-Type,但手动设反而容易出错)
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', () => {
const file = input.files[0];
if (!file) return;
const formData = new FormData();
formData.append('document', file); // 字段名要和服务端约定一致
fetch('/api/upload', {
method: 'POST',
body: formData // 不要加 headers,让浏览器自动设 multipart boundary
});
});
多文件、限制类型、校验大小这些逻辑都得自己写,input[type="file"] 不提供内置上传管理
HTML 原生 input 只负责选文件,后续所有事——比如预览图片、限制 .pdf、拦截超 5MB 的文件、显示进度条、处理失败重试——都得手写 JS 实现。框架(如 Dropzone、Element Plus 的 el-upload)只是封装了这些重复逻辑。
立即学习“前端免费学习笔记(深入)”;
- 限制类型:用
accept="image/png,image/jpeg"是提示,必须在 JS 中用file.type或file.name.split('.').pop()二次校验 - 限制大小:检查
file.size > 5 * 1024 * 1024,否则上传中途可能被 Nginx 或后端截断,返回 413 - 多文件上传:
后遍历input.files,逐个 append 到FormData,或打包成数组字段
实际开发中,最常被忽略的是服务端接收逻辑是否匹配前端字段名,以及 Nginx 是否配置了 client_max_body_size。这两处一错,前端看似发出去了,后端却收不到文件。











