You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React向Rails 7 API上传图片时图片字段为空的问题排查

React上传图片到Rails 7 API失败排查与修复

问题根源

你遇到的核心问题集中在React侧的请求处理逻辑,主要三点:

  1. 错误序列化FormData:将FormData转为普通对象后用JSON.stringify传递,File对象无法被JSON正确序列化,后端收到的只是[object File]字符串,无法识别为有效文件。
  2. 请求头设置错误:强制设置application/json请求头,而文件上传必须使用multipart/form-data编码格式,JSON不支持二进制文件传输。
  3. 表单字段命名不匹配: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:46:24