为何React前端File对象传至Node后端后属性丢失?React-Admin图片上传问题
问题本质
- 你当前的实现存在两个核心认知偏差,导致文件传输异常:
- 浏览器原生
File对象是Web环境独有的类,它的大部分属性(包括文件本身的二进制流、文件名、大小、修改时间等)都不是可枚举属性,执行JSON.stringify序列化的时候,只会把可枚举的path字段提取出来,其他所有信息在序列化阶段就已经永久丢失 - 二进制文件不能按照JSON格式做文本序列化传输,这种方式天生就传不了完整的文件内容,后端接收到的
{path: 'xxx.png'}只是序列化后剩下的残缺字符串对象,根本没有文件的实际内容
- 浏览器原生
- 你不需要在Node.js后端拿到和前端完全一致的浏览器
File类实例:Web环境的原生类在Node运行时根本不存在,只要能拿到完整的文件元信息和二进制流,就能完成存储逻辑。
正确实现流程
按照Web文件传输的标准multipart/form-data协议改造前后端逻辑即可:
前端改造(dataprovider层)
- 废弃直接把整个
params.data做JSON.stringify的写法,改用FormData承载请求体 - 普通的商品文本字段(名称、价格、库存等)逐个append到FormData实例中
- 从
params.data中取出对应的rawFile(浏览器端的File对象),单独append到FormData的对应字段下 - 发请求时不要手动设置
Content-Type请求头,让浏览器自动生成带boundary分隔符的multipart请求头,否则后端的文件解析中间件无法正确识别文件边界
参考代码片段:
create: (resource, params) => { const formData = new FormData(); // 处理非文件类普通字段 Object.entries(params.data).forEach(([key, value]) => { // 跳过图片字段,单独走文件逻辑 if (key !== 'Images') { formData.append(key, value); } }); // 批量处理图片文件 params.data.Images.forEach(imageItem => { formData.append('Images', imageItem.rawFile); }); return httpClient(`${apiUrl}/${resource}/Create`, { method: "POST", body: formData, }).then(({ json }) => ({ data: { ...params.data, id: json._id }, })); }
后端配置
- 接入multer中间件,配置对应的文件存储规则(指定上传目录、文件命名规则、文件大小限制等)
- 配置完成后,multer会自动完成multipart请求的解析:文件的元信息、二进制流会被解析到
req.files对象上,普通文本字段会被自动解析到req.body上 - 拿到文件的存储路径后,将可访问的图片URL存入数据库对应商品的图片字段即可完成全流程
内容的提问来源于stack exchange,提问作者Salah
相关产品推荐
相关产品推荐

