API网关代理form-data请求报错Multipart: Unexpected end of form排查
问题解决:API网关代理form-data请求时出现Multipart错误
问题原因
你遇到的Multipart: Unexpected end of form错误,核心原因是网关的express.json()中间件提前消耗了multipart请求体,同时express-http-proxy默认没有正确处理这类请求的转发:
express.json()会尝试解析所有请求的body为JSON,但form-data是二进制格式,解析失败后会截断请求体;- 当代理转发请求到product-ms时,请求体已经不完整,导致微服务的文件解析器报错。
而直接调用product-ms正常,是因为没有经过网关的express.json()中间件,微服务自身的FileInterceptor可以完整读取并解析multipart请求。
解决方案
方案1:移除全局的express.json()(推荐)
如果网关仅做代理功能,不需要自行解析JSON请求,直接去掉全局的express.json():
import express from "express"; import cors from "cors"; import proxy from "express-http-proxy"; import "dotenv/config"; const app = express(); app.use(cors()); // 移除全局JSON解析中间件 // app.use(express.json()); const PORT = process.env.PORT || 8080; app.use('/api/v1/user-ms', proxy(process.env.USER_MS_URL)); app.use('/api/v1/product-ms', proxy(process.env.PRODUCT_MS_URL)); app.listen(PORT, () => console.log(`Server started at port ${PORT}`));
方案2:按需使用JSON解析,配置代理不解析请求体
如果网关还有其他需要解析JSON的路由,保留express.json()但仅在特定路由使用,同时给代理配置parseReqBody: false,让代理直接转发原始请求流:
import express from "express"; import cors from "cors"; import proxy from "express-http-proxy"; import "dotenv/config"; const app = express(); app.use(cors()); // 仅给需要解析JSON的路由单独挂载中间件 app.use('/api/v1/some-json-only-route', express.json()); const PORT = process.env.PORT || 8080; // 配置代理不解析请求体,直接转发原始数据 app.use('/api/v1/user-ms', proxy(process.env.USER_MS_URL, { parseReqBody: false })); app.use('/api/v1/product-ms', proxy(process.env.PRODUCT_MS_URL, { parseReqBody: false })); app.listen(PORT, () => console.log(`Server started at port ${PORT}`));
验证
修改后重启网关,用Postman发送form-data请求到网关的/api/v1/product-ms路径,即可正常被product-ms解析处理。
内容的提问来源于stack exchange,提问作者xw1nchester
相关产品推荐
相关产品推荐

