React向Rails 7 API上传图片时图片字段为空的问题排查
React上传图片到Rails 7 API失败排查与修复
问题根源
你遇到的核心问题集中在React侧的请求处理逻辑,主要三点:
- 错误序列化FormData:将FormData转为普通对象后用
JSON.stringify传递,File对象无法被JSON正确序列化,后端收到的只是[object File]字符串,无法识别为有效文件。 - 请求头设置错误:强制设置
application/json请求头,而文件上传必须使用multipart/form-data编码格式,JSON不支持二进制文件传输。 - 表单字段命名不匹配:Rails控制器期望参数嵌套在
asset命名空间下,但当前表单字段是顶级的name和image,导致asset_params无法正确获取数据。
修复步骤及代码调整
1. 保留FormData原对象,避免序列化转换
直接将FormData对象传递给Redux异步函数,不要转为普通对象:
const handleSubmit = (e) => { e.preventDefault(); const formData = new FormData(e.currentTarget); dispatch(createAsset(formData)); e.currentTarget.reset(); };
2. 调整表单字段name属性,匹配Rails嵌套参数要求
修改表单输入框的name属性,将字段嵌套到asset下,同时修正label的拼写错误:
<form onSubmit={handleSubmit} className={toggleForm && 'hide-form'}> <div> <label>Property Title</label> <input type="text" id="name" name="asset[name]" /> </div> <div> <label>image upload</label> <input type="file" name="asset[image]" /> </div> <button className="btn" type="submit"> create assets</button> </form>
3. 修正Redux请求配置,移除错误请求头
移除Content-type: application/json,浏览器会自动为FormData请求添加正确的multipart/form-data头及边界信息:
const createAsset = createAsyncThunk('asset/create_asset', async (formData) => { const response = await fetch(`${baseUrl}assets`, { method: 'POST', headers: { Authorization: `Bearer ${token()}`, // 移除Content-Type设置,由浏览器自动处理 }, body: formData, // 直接传递FormData对象 }).then((res) => res.json()); return response; });
Rails端代码无需修改
你的Rails控制器和模型代码已经配置正确,asset_params会正确接收嵌套在asset下的name和image字段,模型的has_one_attached :image也能正确处理文件上传。
内容的提问来源于stack exchange,提问作者morris menanya
相关产品推荐
相关产品推荐

