Angular 4上传文件及POST数据时Node.js端接收空对象问题
解决Angular上传FormData到Node.js后端接收空对象的问题
我刚看完你的代码,问题出在后端没有正确处理multipart/form-data类型的请求——你现在用的body-parser只能解析JSON和urlencoded格式的数据,没法处理包含文件的FormData。另外前端的请求配置也有小问题,咱们一步步改:
第一步:后端添加multer中间件处理文件上传
multer是Node.js专门用来处理multipart/form-data请求的中间件,先安装它:
npm install multer --save
然后修改你的后端代码:
1. 在server.js中引入并配置multer
const express = require('express'); const mongoose = require('mongoose'); const admin = require('./routes/admin'); const path = require('path'); const app = express(); const config = require('./config/config'); const bodyParser = require('body-parser'); const cors = require('cors'); // 新增:引入multer const multer = require('multer'); // 配置存储:这里先用内存存储测试,后续可以改成磁盘存储 const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); mongoose.Promise = global.Promise; mongoose.connect(config.database, (err) => { if (err) { console.log(err); } else { console.log('connected') } }) app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'client/dist'))); app.use(cors()); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header('Access-Control-Allow-Methods', 'DELETE, PUT, POST, GET'); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); // 修改:把multer中间件应用到admin路由,这里用array表示接收多个名为image[]的文件 app.use('/admin', upload.array('image[]'), admin); app.listen(3000, (err) => { if (err) console.log("err"); console.log("port started"); })
2. 修改控制器代码,获取表单数据和文件
module.exports.addRecipe = (req, res) => { // 文本字段在req.body里 const body = req.body; // 文件在req.files里(因为用了array,所以是数组) const files = req.files; console.log('文本数据:', body); console.log('上传的文件:', files); // 后续处理逻辑... res.status(200).json({message: '数据接收成功', body, files}); }
第二步:修复前端Angular的请求配置
当你上传FormData时,不要手动设置Content-Type——浏览器会自动生成包含boundary的正确Content-Type,手动设置反而会导致解析失败。修改你的Angular服务代码:
addRecipe(data){ console.log(this.baseUrl); // 删掉自定义的headers和options,HttpClient会自动处理FormData的请求头 return this.http.post(`${this.baseUrl}addRecipe`, data) .pipe(map(res=>res.json())); }
另外,确认你的组件里formData是正确初始化的:
// 组件里要先初始化formData formData = new FormData(); save(data) { console.log(data); const files: Array<File> = this.filesToUpload; console.log(files); // 先清空之前的内容,避免重复添加 this.formData = new FormData(); for(let i = 0; i < files.length; i++){ this.formData.append("image[]", files[i], files[i]['name']); } this.formData.append('title','dasdasdas'); this.restApi.addRecipe(this.formData).subscribe(res => { console.log(res); }); }
为什么之前的代码不行?
body-parser的json()和urlencoded()方法无法解析multipart/form-data格式的请求,所以后端req.body是空对象。- 前端手动设置了空的headers,没有让浏览器自动生成正确的
Content-Type: multipart/form-data; boundary=xxx,导致后端无法识别请求格式。
现在重新测试,后端应该能正常接收到title字段和上传的文件了。
内容的提问来源于stack exchange,提问作者Tarzy
相关产品推荐
相关产品推荐

