使用Axios和Multer上传图片时req.file为undefined的问题求助
React+Axios+Multer图片上传问题:req.file为undefined且返回500状态码
我正在开发React应用,使用Axios在客户端上传图片到Multer处理的Express服务器,但遇到req.file为undefined的问题,Axios返回500状态码。以下是我的代码和错误日志:
客户端代码
import React, { useState } from 'react'; import './uploadPhoto.css'; const axios = require('axios'); const UploadPhoto = () => { const [selectedImage, setSelectedImage] = useState(null); const [text, setText] = useState(''); const submitPhoto = (event) => { event.preventDefault(); //TODO: Add a check to make sure the user has selected an image and send the photo to the server const formData = new FormData(); formData.append('image', selectedImage); console.log(formData.get('image')); axios.post('http://localhost:3000/photo', formData) .then((response) => { // setText(response.data.pixels); console.log("Image sent successfully"); }) .catch((error) => { console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); }); } return ( <div className='UploadPhoto'> <form encType='multipart/form-data' onSubmit={ submitPhoto }> <input type="file" name='image' onChange={(event) => { setSelectedImage(event.target.files[0]); }}/> <input type="submit" value="Submit"/> </form> </div> ); }
服务端代码
const express = require('express'); const multer = require('multer'); const cors = require('cors'); const port = 3000; const app = express(); app.use(express.json()) app.use(express.urlencoded({ extended: true })) app.use(cors()); const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 1024 * 1024 * 10 } }); app.post('/photo', upload.single('image'), (req, res, next) => { console.log(req.file); const file = req.file; if(!file) { const error = new Error('Please upload a file'); error.httpStatusCode = 400; console.log(error); return next(error); } }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
错误日志
console.log(error.response.data)
dispatchXhrRequest @ C:\Users\user\Docume…node\axios.cjs:3389 xhr @ C:\Users\user\Docume…node\axios.cjs:3191 dispatchRequest @ C:\Users\user\Docume…node\axios.cjs:3489 request @ C:\Users\user\Docume…node\axios.cjs:3839 httpMethod @ C:\Users\user\Docume…node\axios.cjs:3878 wrap @ C:\Users\user\Docume…t\node\axios.cjs:29 onSubmit @ uploadPhoto.js:18 callCallback @ C:\Users\user\Docume…development.js:4164 invokeGuardedCallbackDev @ C:\Users\user\Docume…development.js:4213 invokeGuardedCallback @ C:\Users\user\Docume…development.js:4277 invokeGuardedCallbackAndCatchFirstError @ C:\Users\user\Docume…development.js:4291 executeDispatch @ C:\Users\user\Docume…development.js:9041 processDispatchQueueItemsInOrder @ C:\Users\user\Docume…development.js:9073 processDispatchQueue @ C:\Users\user\Docume…development.js:9086 dispatchEventsForPlugins @ C:\Users\user\Docume…development.js:9097 (anonymous) @ C:\Users\user\Docume…development.js:9288 batchedUpdates$1 @ C:\Users\user\Docume…evelopment.js:26140 batchedUpdates @ C:\Users\user\Docume…development.js:3991 dispatchEventForPluginEventSystem @ C:\Users\user\Docume…development.js:9287 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ C:\Users\user\Docume…development.js:6465 dispatchEvent @ C:\Users\user\Docume…development.js:6457 dispatchDiscreteEvent @ C:\Users\user\Docume…development.js:6430
error.response.status
Error: Please upload a file [1] at C:\Users\user\Documents\Project Intern\project-intern\backend\server.js:54:19 [1] at Layer.handle [as handle_request] (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\layer.js:95:5) [1] at next (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\route.js:144:13) [1] at multerMiddleware (C:\Users\user\Documents\Project Intern\project-intern\node_modules\multer\lib\make-middleware.js:13:41) [1] at Layer.handle [as handle_request] (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\layer.js:95:5) [1] at next (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\route.js:144:13) [1] at Route.dispatch (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\route.js:114:3) [1] at Layer.handle [as handle_request] (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\layer.js:95:5) [1] at C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\index.js:284:15 [1] at Function.process_params (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\index.js:346:12)
error.response.headers
AxiosHeaders access-control-allow-origin : "*" connection : "keep-alive" content-length : "1525" content-security-policy : "default-src 'none'" content-type : "text/html; charset=utf-8" date : "Tue, 14 Mar 2023 04:15:57 GMT" keep-alive : "timeout=5" x-content-type-options : "nosniff" x-powered-by : "Express" Symbol(Symbol.toStringTag) : (...) [[Prototype]] : Object
解决方法
1. 客户端手动设置请求头
Axios默认会给FormData添加错误的Content-Type,需显式设置为multipart/form-data:
axios.post('http://localhost:3000/photo', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
2. 移除服务端冲突的解析中间件
express.json()和express.urlencoded()会干扰Multer解析multipart数据,删除这两行:
// app.use(express.json()) // app.use(express.urlencoded({ extended: true }))
3. 完善服务端响应逻辑
当前接口在验证通过后无响应,需添加返回代码:
app.post('/photo', upload.single('image'), (req, res, next) => { console.log(req.file); const file = req.file; if(!file) { const error = new Error('Please upload a file'); error.httpStatusCode = 400; return next(error); } // 返回成功响应 res.status(200).json({ message: '图片上传成功', fileInfo: { originalName: file.originalname, size: file.size, mimeType: file.mimetype } }); });
4. 客户端添加文件校验
提交前检查是否选中文件,避免无效请求:
const submitPhoto = (event) => { event.preventDefault(); if (!selectedImage) { console.log('请先选择要上传的图片'); return; } const formData = new FormData(); formData.append('image', selectedImage); // ...后续请求代码 }
内容的提问来源于stack exchange,提问作者InvalidHop
相关产品推荐
相关产品推荐

