Node.js后端无法接收React Redux前端图片上传请求体问题求助
问题修复方案
核心问题点
- Sell组件中FormData的字段名配置错误:你初始化
form.file_name = null,调用formData.append(form.file_name, files)相当于给FormData追加了一个key为null的字段,但后端multer配置的是upload.single('file_name'),只会解析key为file_name的文件字段,导致req.file为undefined,触发Cannot read property 'originalname' of undefined报错 - 数据传递链路格式不匹配:你构造了FormData对象传给action,但后续的action、service层都把参数当成普通JSON对象处理,没有透传FormData,也没有适配multipart/form-data的请求格式
- 缺少必填业务字段:请求中未携带
image_user_id、image_product_id两个后端需要的关联字段
修复代码
1. 修复Sell组件
import React, { useState } from 'react' import { SetAWSS3ImageUrl } from '../store/actions/ImageActions' import { connect } from 'react-redux' const mapStateToProps = ({ imageState, productState, authenticationState }) => { return { imageState, productState, authenticationState } } const mapDispatchToProps = (dispatch) => { return { setS3Url: (formData) => dispatch(SetAWSS3ImageUrl(formData)), } } function Sell(props) { const [files, setFiles] = useState() function handleFormChange(e) { setFiles(e.target.files[0]) } const handleSubmit = async (e) => { e.preventDefault() if (!files) return let formData = new FormData() // 字段名和后端multer配置的upload.single('file_name')保持一致 formData.append('file_name', files) // 补充必填的关联字段,这里示例从全局状态取,根据你的实际业务逻辑调整取值路径 formData.append('image_user_id', props.authenticationState.user.id) formData.append('image_product_id', props.productState.currentProduct.id) const res = await props.setS3Url(formData) return res } return ( <div className="sell"> <form onSubmit={handleSubmit}> <label>上传商品图片</label> <input type="file" onChange={handleFormChange}></input> <button type="submit">上传</button> </form> </div> ) } export default connect(mapStateToProps, mapDispatchToProps)(Sell)
2. 修复Image Action
import { GetUploadUrl, DeleteImage, GetAllImages } from '../../services/ImageServices' const { SET_AWS_S3_IMAGE_URL, GET_ALL_IMAGES, DELETE_IMAGE } = require('../types') // 直接接收FormData参数透传给service export const SetAWSS3ImageUrl = (formData) => { return async (dispatch) => { try { const s3Url = await GetUploadUrl(formData) dispatch({ type: SET_AWS_S3_IMAGE_URL, payload: s3Url }) } catch (error) { throw error } } }
3. 修复Image Service
import Client from '.' // 接收FormData,直接作为post请求的body,axios会自动设置multipart/form-data请求头 export const GetUploadUrl = async (formData) => { try { const res = await Client.post('/images/upload', formData) return res } catch (error) { throw error } }
可选优化
- 后端CreateImage接口最前面加空值判断,如果
req.file为空直接返回400错误,避免抛出未捕获的异常 - 前端提交前加文件存在、文件大小、文件格式校验,避免无效提交
内容的提问来源于stack exchange,提问作者n0twei
相关产品推荐
相关产品推荐

