<input type="file"> 必须配合 enctype="multipart/form-data",否则后端收不到文件二进制数据;提交需用 FormData,不可设 Content-Type 头,且前后端 name 属性须严格一致。

HTML 中 <input type="file"> 必须配合 enctype="multipart/form-data"
不加这个属性,后端根本收不到文件二进制数据,只会收到空值或文件名字符串。浏览器默认用 application/x-www-form-urlencoded 编码,它不支持二进制传输。
常见错误现象:req.file 为 undefined(Express)、$_FILES 为空(PHP)、Django 中 request.FILES 为空。
-
<form method="POST" enctype="multipart/form-data">是硬性要求,缺一不可 - 如果用
fetch或axios提交,不能直接传 JSON 对象,得用FormData实例 - 多个文件上传时,
<input type="file" multiple>的name值建议带[](如name="files[]"),方便后端统一解析
前端提交前检查 input.files 是否存在有效文件
用户可能点了“选择文件”但没选任何文件,或取消了对话框,此时 input.files.length === 0。直接提交会导致后端收不到文件却以为已上传。
示例判断逻辑:
立即学习“前端免费学习笔记(深入)”;
const fileInput = document.querySelector('input[type="file"]');
if (!fileInput.files.length) {
alert('请选择文件');
return;
}
// 后续可构造 FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]); // 单文件
// formData.append('files', fileInput.files); // 多文件(注意:部分后端框架不直接支持 FileList)
-
fileInput.files是FileList,只读类数组,不能用map等数组方法,需转成数组再操作:Array.from(fileInput.files) - 不要用
input.value判断是否选中——它返回路径字符串(浏览器出于安全限制,实际是假路径),且 IE/Edge 旧版本行为不一致 - 若需限制类型或大小,应在
change事件里立刻校验,避免提交后才提示
后端接收时注意 name 属性与字段名严格匹配
表单中 <input name="avatar">,后端就必须按 avatar 这个 key 去取文件。大小写、下划线、中横线全敏感,拼错一个字符就取不到。
常见问题场景:
- 前端写
<input name="userAvatar">,后端写req.file('useravatar')(Express + multer)→ 找不到 - 用了
multiple但后端仍按单文件处理,比如 Express 中用upload.single('files')却传了多个 → 只收到第一个 - PHP 中
$_FILES['my_file']['error'] === 4表示没上传文件,常因name不匹配或前端未触发选择导致
用 fetch 提交时别忘了设置 Content-Type: multipart/form-data 让浏览器自动处理
千万别手动设 headers: { 'Content-Type': 'multipart/form-data' } —— 这会破坏边界(boundary),导致后端解析失败。浏览器必须自己生成 boundary 并附在请求头里。
正确做法:不设 Content-Type,让 fetch 自动识别 FormData:
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('desc', 'profile photo');
fetch('/upload', {
method: 'POST',
body: formData // 不要加 headers!
});
- 如果额外加了其他字段(如 token),也用
formData.append('token', 'xxx'),别试图混用 JSON 和 FormData - 使用
axios时同理:直接传formData,不要配headers;若需全局 token,用axios.defaults.headers.common['Authorization']更安全 - 某些代理(如 Nginx)默认限制文件上传大小,报
413 Request Entity Too Large,需调client_max_body_size



















