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

如何从React向Node.js发送同时包含文件与JSON数据的单次请求

实现方案:单次请求同时上传文本数据与图片文件到Express服务

前端实现逻辑

  • 使用浏览器原生的FormData接口封装所有数据,该接口天然支持同时承载二进制文件和文本键值对,会自动设置multipart/form-data编码类型,无需手动修改请求头
  • 具体操作步骤:
    1. 获取用户输入的文本数据(商品名、分类、描述、价格)和选中的图片文件对象后,实例化空的FormData对象
    2. 调用append()方法按后端约定的键名,依次添加所有文本字段,价格类的数字可以直接传入,后端接收后再做类型转换即可
    3. 调用append()方法添加图片文件对象,多张图片可以用同一个键名加数组后缀(比如productImages[])或者按序号命名实现批量上传
    4. 用fetch、axios等请求库把FormData实例作为请求体直接发送,不需要额外序列化处理
      前端示例代码:
// 假设已获取表单输入和文件对象
const productName = document.querySelector('#product-name').value
const category = document.querySelector('#category').value
const description = document.querySelector('#description').value
const price = document.querySelector('#price').value
const productImage = document.querySelector('#image-upload').files[0]

// 封装FormData
const formData = new FormData()
formData.append('name', productName)
formData.append('category', category)
formData.append('description', description)
formData.append('price', price)
formData.append('productImage', productImage)

// 发送请求
fetch('/api/product/create', {
  method: 'POST',
  body: formData
})
.then(res => res.json())
.then(data => console.log('提交成功', data))

后端Express处理逻辑

  • Express原生不支持解析multipart/form-data类型的请求体,需要引入multer中间件处理文件上传,这是目前Express生态最成熟的文件处理中间件
  • 具体操作步骤:
    1. 安装依赖:npm install multer pg
    2. 配置multer:支持两种存储模式,一是将图片存储到本地磁盘/对象存储服务,数据库仅存访问路径;二是直接拿到文件二进制Buffer存入PostgreSQL,更推荐前者,避免数据库体积过大影响查询性能
    3. 在对应接口路由上挂载multer中间件,配置接收的文件字段名、数量、大小限制
    4. 接口处理函数中通过req.body获取所有文本字段,通过req.file(单文件)/req.files(多文件)获取上传的文件信息
    5. 将文本数据和文件的存储路径/二进制数据写入PostgreSQL即可
      后端示例代码:
const express = require('express')
const multer = require('multer')
const { Pool } = require('pg')
const app = express()
const pgPool = new Pool(/* 自行填入PostgreSQL连接配置 */)

// 配置multer存储到本地磁盘,如需直接拿Buffer存库可替换为multer.memoryStorage()
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, './public/product-images') // 提前创建好对应文件夹
  },
  filename: (req, file, cb) => {
    // 重命名避免文件名重复
    const fileName = `${Date.now()}-${Math.round(Math.random() * 1e9)}-${file.originalname}`
    cb(null, fileName)
  }
})
const upload = multer({ storage: storage, limits: { fileSize: 5 * 1024 * 1024 } }) // 限制单文件5M以内

// 接口配置,single('productImage')表示接收单文件,对应前端FormData的文件字段名
app.post('/api/product/create', upload.single('productImage'), async (req, res) => {
  try {
    const { name, category, description, price } = req.body
    const imagePath = `/product-images/${req.file.filename}`
    // 写入PostgreSQL
    const result = await pgPool.query(
      `INSERT INTO products (name, category, description, price, image_url) 
       VALUES ($1, $2, $3, $4, $5) RETURNING id`,
      [name, category, description, Number(price), imagePath]
    )
    res.json({ code: 0, message: '商品创建成功', productId: result.rows[0].id })
  } catch (err) {
    console.error(err)
    res.status(500).json({ code: 1, message: '商品创建失败' })
  }
})

app.listen(3000, () => console.log('服务启动在3000端口'))

PostgreSQL存储说明

如果选择直接存储图片二进制数据,可将对应字段类型设置为BYTEA,配置multer使用内存存储模式后,取req.file.buffer写入数据库即可。

内容的提问来源于stack exchange,提问作者Ashutosh Dubey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:30:05