如何使用axios向Rails 5后端正确上传用户头像文件数据
问题定位与修复方案
- 错误1:FormData使用方式不符合axios要求
axios仅在直接接收FormData实例作为请求体参数时,才会正确序列化multipart/form-data格式数据。你当前将FormData实例嵌套在普通JS对象user中传递,axios会将整个user对象序列化为JSON字符串,其中的FormData实例会被调用toString方法转为[object FormData],导致后端完全无法解析上传参数。 - 错误2:手动指定multipart/form-data请求头
multipart/form-data请求头必须附带随机生成的boundary分隔符参数,该参数由axios自动生成并填充,手动指定请求头会丢失boundary信息,导致后端无法拆分表单字段。 - 错误3:Promise回调写法错误
addFileToProfile(user).then(closeModal())会在发起请求时立即执行closeModal(),而不是请求成功后再执行,正确写法是传入函数引用then(closeModal)。 - 日志中额外GET请求的原因
GET "/[object%20FormData]"请求是前端代码某处将FormData实例直接作为URL赋值导致的,常见场景为上传后预览头像时直接把FormData/File对象赋值给了img标签的src属性,正确操作是调用URL.createObjectURL(file)生成临时预览地址。
修复后的代码
1. 表单提交处理代码
const handleSubmit = (e) => { e.preventDefault(); const formData = new FormData(); // 所有user嵌套参数都按Rails要求的格式append到FormData Object.entries(avatarUser).forEach(([key, value]) => { formData.append(`user[${key}]`, value) }) // 追加头像文件 formData.append('user[profpic]', file) // Rails伪方法兼容PATCH请求 formData.append('_method', 'PATCH') // 直接传递FormData实例给请求方法 addFileToProfile(avatarUser.id, formData).then(closeModal); };
2. 封装的axios请求代码
export const addFileToProfile = (userId, formData) => axios.post(`/api/users/${userId}`, formData)
3. 后端Rails代码无需修改
现有强参数和update逻辑可兼容修复后的请求格式,无需调整。
内容的提问来源于stack exchange,提问作者KGE
相关产品推荐
相关产品推荐

