使用express http-proxy-middleware上传文件失败,返回400错误
解决FormData上传文件经代理后后端返回400的问题
问题原因
- 全局中间件仅配置了
bodyParser.json()和express.urlencoded(),无法解析multipart/form-data类型的请求,导致代理层无法获取到FormData中的参数和文件。 - 代理的
restream函数强制将所有带有req.body的请求的Content-Type设置为application/json,并将请求体转为JSON格式写入,破坏了原始的multipart请求结构,后端自然无法识别文件参数。
解决方案
1. 添加multipart请求解析中间件
使用multer处理文件上传的multipart请求,同时保留原有对JSON和urlencoded请求的支持。先安装依赖:
npm install multer
修改全局中间件代码:
const multer = require('multer'); // 用内存存储上传文件,也可根据需求配置磁盘存储路径 const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); app.use(morgan("dev")); app.use(cors(corsOptions)); app.use(bodyParser.json()); app.use(express.urlencoded({ extended: false })); // 添加multer中间件,解析所有multipart字段和文件 app.use(upload.any());
2. 修改代理的restream函数
根据请求的原始Content-Type分情况处理请求体,仅对JSON请求做转写,multipart请求直接转发原始数据:
let restream = function(proxyReq, req, res, options) { const contentType = req.headers['content-type']; // JSON类型请求保持原有转写逻辑 if (contentType && contentType.includes('application/json') && req.body) { let bodyData = JSON.stringify(req.body); proxyReq.setHeader('Content-Type','application/json'); proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); proxyReq.write(bodyData); } // multipart请求不修改请求头和体,直接转发原始流 else if (contentType && contentType.includes('multipart/form-data')) { // 无需额外处理,代理会自动转发原始请求内容 } // 其他类型请求默认直接转发 } router.use('',checkAuthentication,createProxyMiddleware({ target: config.MAIN_SERVER_BASE_URL, changeOrigin: true, on: { proxyReq: restream }, preserveReqSession: true }));
3. 验证效果
- 前端发送JSON请求时,代理层正常转写请求体为JSON格式转发给后端。
- 前端发送FormData上传文件时,multer解析请求后,代理层保留原始multipart结构转发,后端可正确获取
file和type参数。
内容的提问来源于stack exchange,提问作者Deevanshu Kushwah
相关产品推荐
相关产品推荐

