Vue文件上传需用FormData构建载荷、Axios实例统一配置、组件解耦逻辑;禁用手动设Content-Type,通过onUploadProgress显示进度,前置校验类型/大小,用URL.createObjectURL预览,支持取消上传。

Vue 文件上传交互结合 Axios 封装,核心在于三点:用 FormData 构建二进制载荷、用 Axios 实例统一管理请求配置、在组件中解耦选择/预览/上传逻辑。不写死 URL、不裸调 axios.post,才能应对接口变多、token 更新、错误提示风格统一等真实需求。
封装一个支持文件上传的 Axios 实例
避免每个组件都 import axios 再拼 baseURL 和 headers。推荐在 src/api/upload.js 中创建专用实例:
- 设置
baseURL和超时时间,比如https://api.example.com/v1 - 禁用默认的
Content-Type自动设置(因为 FormData 会自动带 boundary) - 在请求拦截器里注入 token(若需):
config.headers.Authorization = 'Bearer ' + getToken() - 响应拦截器统一处理 4xx/5xx,比如跳登录页或弹全局提示
组件内正确构造 FormData 并传入请求
不要手动设 headers: { 'Content-Type': 'multipart/form-data' } —— 这会破坏浏览器自动生成的 boundary,导致后端解析失败。正确做法是:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
- 用
new FormData()实例接收文件对象:formData.append('file', file) - 如需额外字段(如业务 ID、分类),也用
append添加:formData.append('category', 'face') - 直接把
formData当作 Axios 请求的data参数传入,不加任何 content-type 头
增强用户体验的关键细节
真实项目里,用户不只关心“能不能传”,更在意“传到哪了”“出错了为什么”。建议在封装层或组件中补充:
立即学习“前端免费学习笔记(深入)”;
- 上传进度:利用 Axios 的
onUploadProgress回调,计算百分比并触发更新:Math.round((e.loaded / e.total) * 100) - 文件校验前置:在
@change阶段检查类型(file.type.startsWith('image/'))、大小(如 ≤5MB)、数量(单图 or 多图) - 预览控制:用
URL.createObjectURL(file)生成本地临时地址,避免上传前读取 base64 增加内存压力 - 取消上传:配合
CancelToken或AbortController(Axios 1.5+ 推荐后者),暴露 cancel 方法供按钮调用
后端对接注意事项
前端封装再好,也得和后端约定一致。常见坑点:
- 后端接收字段名必须和
formData.append('xxx', ...)的第一个参数完全一致(如 Python Flask 用request.files.get('file')) - 若需同时传 JSON 元数据和文件,不要把 JSON 字符串塞进 FormData;应拆成多个
append字段,后端分别取files和form - 跨域时确保后端设置了
Access-Control-Allow-Headers: Authorization(如果带 token) - 大文件上传建议后端开启分片或直传 OSS,前端 Axios 不适合处理 GB 级文件

















