MEAN应用图片上传失败:后端无法接收图片
兄弟,我太懂这种上传文件卡壳的憋屈感了!你遇到的req.body空对象、req.files返回undefined的问题,大概率就是请求配置或者服务器中间件没弄对,咱们一步步来排查解决:
一、先盯紧前端的请求配置
文件上传绝对不能用普通JSON格式发请求,必须用FormData对象,而且千万别手动设置Content-Type——浏览器会自动给你加上带分隔符的正确头,手动加反而会搞砸解析。
给你个axios的正确示例:
// 选完图片拿到file对象 const file = document.querySelector('input[type="file"]').files[0]; const formData = new FormData(); formData.append('avatar', file); // 'avatar'是你后端要接收的字段名,前后端要一致! // 发送请求,别瞎加Content-Type axios.post('/api/upload', formData) .then(res => console.log('上传成功', res)) .catch(err => console.error('上传失败', err));
要是你手动加了Content-Type: multipart/form-data,后端就拿不到分隔字段的boundary,直接就解析不了文件,这是高频踩坑点!
二、后端必须配置文件解析中间件
Node.js本身不处理multipart/form-data格式的请求,得靠中间件帮忙,最常用的就是multer或者express-fileupload,二选一就行。
用multer的配置示例(Express框架)
- 先装依赖:
npm install multer --save
- 后端代码配置:
const express = require('express'); const multer = require('multer'); const app = express(); // 配置文件存储路径和文件名(怕麻烦也可以用multer.memoryStorage()存在内存里) const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, './uploads'); // 一定要提前创建好uploads文件夹,不然会报错! }, filename: (req, file, cb) => { cb(null, Date.now() + '-' + file.originalname); // 加时间戳避免文件名重复 } }); const upload = multer({ storage: storage }); // 接口路由,upload.single('avatar')对应前端FormData里的字段名 app.post('/api/upload', upload.single('avatar'), (req, res) => { // 这会儿req.file就是上传的PNG文件对象,req.body里是其他文本字段(如果有的话) console.log('上传的文件:', req.file); console.log('其他表单数据:', req.body); res.send('文件上传成功'); }); app.listen(3000, () => console.log('服务器跑在3000端口啦'));
要是嫌multer麻烦,试试express-fileupload
- 装依赖:
npm install express-fileupload --save
- 后端代码更简单:
const express = require('express'); const fileUpload = require('express-fileupload'); const app = express(); app.use(fileUpload()); // 默认配置就能用 app.post('/api/upload', (req, res) => { // 此时req.files.avatar就是上传的PNG文件 console.log('上传的文件:', req.files.avatar); // 把文件存到服务器 req.files.avatar.mv('./uploads/' + req.files.avatar.name, (err) => { if (err) return res.status(500).send(err); res.send('文件上传成功'); }); });
三、最后再查几个细节
- 确认你的
uploads文件夹已经手动创建好了,不然中间件会直接报错,请求处理失败; - 前端FormData里的字段名和后端接收的字段名必须完全一致(比如前端append的是'image',后端就要用
upload.single('image')); - 要是用原生fetch发请求,同样要传FormData,别瞎设置Content-Type。
内容的提问来源于stack exchange,提问作者tilly




