React表单上传图片至Express后端,后端接收为空对象求助
问题分析与解决:图片上传后端返回空对象
核心问题原因
- 前端传输格式错误:上传文件不能用普通JSON对象发送,必须使用
FormData格式,否则后端无法解析文件内容。 - 后端读取位置错误:使用
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
相关产品推荐
相关产品推荐

