<input type="file"> 仅触发文件选择,需配合 name 属性、JavaScript 或表单提交才能上传;多选用 multiple,类型限制用 accept;读取用 input.files[0] 和 FileReader;上传必须用 FormData,后端需配置对应中间件及大小限制。

file input 必须用 type="file",但仅设这个还不够
光写 <input type="file"> 只能触发本地选择,不会自动上传。浏览器默认只做文件选取,后续必须配合 JavaScript 或表单提交才能发到服务器。常见错误是以为加了 type="file" 就“能传了”,结果点击没反应、选完没提交、或者后端收不到文件。
- 务必添加
name属性,否则 FormData 或表单提交时该字段会被忽略(例如<input type="file" name="avatar">) - 如需多选,加
multiple;限制类型可用accept="image/*,.pdf"(注意:这只是前端提示,不替代后端校验) - 若用在无刷新上传中,
<form>标签不是必需的,但input元素必须在文档流中且未被display: none或visibility: hidden隐藏(否则部分浏览器会拒绝触发)
用 JavaScript 读取选中的文件内容(比如预览图片)
用户选完文件后,input.files 是一个 FileList 对象,不是普通数组,不能直接用 forEach 或展开运算符(除非转成数组)。最常踩的坑是试图访问 input.value 拿路径——现代浏览器出于安全限制,这里只返回伪路径(如 C:\fakepath\xxx.jpg),实际不可用。
- 正确读取第一个文件:
const file = input.files[0] - 预览图片:用
FileReader的readAsDataURL,然后赋值给<img src> - 注意
FileReader是异步的,onload里才能拿到result,别在它外面直接用reader.result
提交文件时 FormData 是最稳妥的选择
用 fetch 或 XMLHttpRequest 上传时,如果手动拼 URL 参数或 JSON body,文件会丢失——因为二进制文件不能塞进 JSON。必须用 FormData 包装,它会自动设置正确的 Content-Type: multipart/form-data 并处理边界分隔符。
- 创建方式:
const fd = new FormData() - 追加文件:
fd.append("photo", input.files[0])(key 名要和后端约定一致) - 追加其他字段也用
append,比如fd.append("desc", "my photo"),不用额外设 header - fetch 时直接传
fd,不要设Content-Typeheader,否则浏览器会覆盖掉 multipart 所需的 boundary
服务端接收不到文件?先检查这几个地方
前端看似正常,但后端 req.files 或 $_FILES 为空,大概率不是代码逻辑问题,而是基础设施拦截。
- Node.js + Express:默认不解析
multipart/form-data,必须加中间件如multer或busboy - PHP:确认
file_uploads = On且post_max_size、upload_max_filesize足够大(改完要重启 PHP-FPM 或 Apache) - Nginx:如果加了反向代理,需显式设置
client_max_body_size 20M,否则大文件直接 413 Request Entity Too Large - 浏览器控制台 Network 标签页里点上传请求,看 Payload 是否真含文件二进制段(而非空对象或字符串)
type="file" 这一行,而是前后端对 multipart 边界、编码、大小限制、中间件配置的理解断层。尤其当开发环境能传、测试环境不行时,八成是某层网关或运行时把文件截掉了。


















