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

React表单上传图片至Express后端,后端接收为空对象求助

问题分析与解决:图片上传后端返回空对象

核心问题原因

  1. 前端传输格式错误:上传文件不能用普通JSON对象发送,必须使用FormData格式,否则后端无法解析文件内容。
  2. 后端读取位置错误:使用express-fileupload中间件时,上传的文件会被解析到req.files对象中,而非req.body。

前端代码修改

将文件放入FormData,让Axios以表单形式发送请求:

import Axios from 'axios'
import { useForm } from 'react-hook-form'

const Create_post = () => {
    const { register, handleSubmit } = useForm()

    const onSubmit = (data) => {
        const formData = new FormData();
        // 把文件添加到FormData,键名要和后端对应
        formData.append('file', data.image[0]);
        handleApi(formData)
    }

    const handleApi = (formData) => {
        console.log(formData)
        // 发送FormData时,无需手动设置Content-Type,浏览器会自动处理边界标识
        Axios.post('http://localhost:3001/api/post', formData)
            .then((response) => console.log(response))
    }

    return (  
        <div>
            <form onSubmit={handleSubmit(onSubmit)}>      
                <input type='text'/>
                <div>
                    <div>
                        <div>
                            <input type='file' name='fileInput' {...register(
                                'image', {required: true}
                            )}/>
                        </div>
                    </div>
                </div>
                <input type='submit' name='submitButton'/>
            </form>
        </div>
    );
}
 
export default Create_post;

后端代码修改

从req.files获取文件,并添加本地保存逻辑:

const express = require('express')
const app = express()
const cors = require('cors')
const sql = require('mysql')
const bodyParser = require('body-parser')
const imgUpload = require('express-fileupload')
const fs = require('fs');
const path = require('path');

const db = sql.createPool({
    host:'localhost',
    user:'root',
    password:'password',
    database:'photo_website_database'
})

app.use(cors())
app.use(express.json())
app.use(bodyParser.urlencoded({extended:true}))
// 开启自动创建保存目录的配置
app.use(imgUpload({ createParentPath: true }))

app.post('/api/post/', (req, res)=>{
    // 从req.files读取上传的文件
    const uploadedFile = req.files?.file;
    if (!uploadedFile) {
        return res.status(400).send('未上传文件');
    }

    // 设置文件保存路径(示例:项目根目录下的uploads文件夹)
    const savePath = path.join(__dirname, 'uploads', uploadedFile.name);
    
    // 将文件写入本地磁盘
    uploadedFile.mv(savePath, (err) => {
        if (err) {
            console.error('文件保存失败:', err);
            return res.status(500).send('文件保存失败');
        }
        console.log('文件保存成功:', savePath);
        // 此处可添加将文件信息存入数据库的逻辑
        res.send('文件上传并保存成功');
    })
})

app.listen(3001,()=>{
    console.log('running on port 3001')  
})

额外注意点

  • 确保后端项目的uploads目录存在,或者依赖createParentPath: true让中间件自动创建。
  • 前端FormData.append的键名(示例中为file)必须和后端req.files.file的键名完全一致。
  • 发送FormData时不要手动设置Content-Type,浏览器会自动添加正确的边界标识,避免解析失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:50:41