本身不上传文件,仅选择本地文件;必须配合 enctype="multipart/form-data" 表单或 formdata + fetch/xhr 发起 http 请求,且后端需部署对应接口接收并保存文件。

HTML 本身不能直接把本地文件“上传到服务器”——它只是提供一个选择文件的界面,真正传输动作必须由浏览器发起 HTTP 请求,且需后端服务接收并保存。没有后端,<input type="file"> 点了也没用。
为什么 <input type="file"> 单独不工作
用户常误以为加个 <input type="file"> 就能上传,结果点完没反应、控制台无报错、网络面板没请求。这是因为:
-
<input type="file">只负责读取本地文件路径和生成File对象,不自动发请求 - 表单缺
enctype="multipart/form-data"时,文件数据根本不会被编码进请求体 - 表单
action指向的地址若无后端服务监听(比如只放了个静态 HTML),请求会 404 或直接被浏览器拦截 - 现代浏览器禁止前端 JS 直接读取文件内容后“悄悄发给任意域名”,必须显式构造
FormData并调用fetch()或XMLHttpRequest
必须配 enctype="multipart/form-data" 的表单
这是最基础但最容易漏掉的一环。不设这个,哪怕后端代码完全正确,也收不到文件字段。
-
method必须是POST;GET不支持文件传输 -
name属性值决定后端取文件用的键名,比如name="avatar",后端就要用req.files.avatar(Express + multer)或$_FILES['avatar'](PHP) - 如果想限制类型,用
accept="image/png,image/jpeg",但仅前端校验,不可信 - 不要写
action="upload.php"却没部署 PHP 环境——先确认后端接口真实可访问
用 fetch() + FormData 异步上传更可控
相比传统表单跳转,用 JS 提交能做进度条、错误提示、多文件并发、取消上传等。关键点:
- 必须用
new FormData()包裹File对象,不能直接JSON.stringify() -
fetch('/upload', { method: 'POST', body: formData })——body直接传formData,别加Content-Type头,浏览器会自动生成带 boundary 的 multipart 头 - 监听
upload.onprogress需用XMLHttpRequest;fetch无法原生监听进度,得靠ReadableStream分块读取(较复杂) - 上传大文件前,先检查
file.size,比如if (file.size > 5 * 1024 * 1024) { alert('不能超过 5MB'); return; }
后端没接住,前端再规范也没用
常见现象:前端控制台显示 200,但服务器目录里没文件;或返回 500 却没日志。问题通常在后端:
- Node.js + Express 必须用
multer等中间件解析multipart/form-data,原生req.body是空的 - PHP 要确认
file_uploads = On且post_max_size、upload_max_filesize足够大 - Nginx 默认限制 1MB,需在配置中加
client_max_body_size 20M; - 上传路径权限不足(如
/var/www/html/uploads目录 www-data 用户无写权限)会导致静默失败
真正卡住的地方往往不是 HTML 写法,而是前后端对“谁该处理哪部分”的责任划分不清:前端管选、校验、发;后端管收、验、存、回。少一环,整个链路就断在中间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











