文件上传依赖触发change事件获取FileList,需用FileReader异步读取内容并封装进FormData通过fetch上传,禁止手动设置Content-Type。

文件上传靠 ,不是直接发 HTTP 请求
浏览器里没有“上传文件”这个独立操作,本质是用户选中文件后,用 File 或 Blob 对象参与后续流程。关键第一步是监听 change 事件拿到 input.files —— 它是个 FileList,不是数组,不能直接用 map 或展开运算符(除非转成数组)。
- 必须用
input.addEventListener('change', ...),click或submit事件拿不到文件 -
input.files[0]是最常用的单文件入口,多文件需遍历input.files - 表单提交会自动编码文件(
multipart/form-data),但 JS 控制上传时通常走FormData+fetch
FileReader 读内容:只支持浏览器环境,不支持 Node.js
FileReader 是唯一能同步读取本地文件内容的 Web API,但它异步、只在浏览器运行。Node.js 里要用 fs.readFile,两者完全不兼容。读取方式取决于你需要什么格式:
-
readAsText(file, encoding)→ 得到字符串,适合 JSON、CSV、代码文件 -
readAsDataURL(file)→ 得到 base64 字符串,适合预览图片,但体积膨胀 ~33% -
readAsArrayBuffer(file)→ 得到二进制缓冲区,适合处理音视频、加密、解析二进制格式 - 所有方法都触发
load事件,结果在e.target.result里,不是返回值
const reader = new FileReader();
reader.onload = (e) => {
console.log(e.target.result); // 实际内容在这里
};
reader.readAsText(file, 'utf-8');
用 fetch 上传文件:别漏掉 FormData
直接把 File 对象丢给 fetch 会报错。必须包装进 FormData,它会自动设置正确的 Content-Type: multipart/form-data 和边界(boundary)。后端接收时也得按 multipart 解析(比如 Express 用 multer,Python Flask 用 request.files)。
-
FormData.append('key', file)的key必须和后端约定好字段名 - 可追加其他字段:
formData.append('desc', 'my photo'),服务端能一起收到 - 不要手动设
Content-Type头——fetch会自动生成带 boundary 的 header,手动设反而会出错 - 大文件建议加进度监听:
upload.onprogress = e => {...}
const formData = new FormData();
formData.append('avatar', file);
fetch('/upload', {
method: 'POST',
body: formData // 不要加 headers: { 'Content-Type': ... }
});
常见错误:file.size 为 0、readAsText 返回空、fetch 500
这些不是随机发生,基本对应三个确定环节:
立即学习“Java免费学习笔记(深入)”;
-
file.size === 0:文件被清空或 input 被重置过;检查是否重复调用了input.value = '',这会清空files -
reader.result是空字符串:没等load就去读,或文件编码不匹配(比如用gbk读 utf-8 文件) -
fetch返回 500:后端没正确解析 multipart,或没处理file字段名不一致;用curl -F 'avatar=@test.jpg' http://localhost:3000/upload手动测后端是否正常
文件路径在浏览器里永远不可见(出于安全限制),file.name 是用户选中的原始文件名,不是本地完整路径。










