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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:18:02