Node.js合并多项目Swagger文档及跨项目调用CORS报错问题咨询
问题根因分析
- 跨域本质:Swagger UI部署在3002端口的administrator服务下,前端页面发起请求到3005端口的authentication服务时,属于浏览器同源策略限制的跨域场景,报错核心是3005端口的服务没有正确处理跨域请求,尤其是预检OPTIONS请求
- Swagger配置侧的隐藏问题:你当前的配置中会动态将
swaggerDocument的host设置为当前请求的host(即3002),切换服务下拉列表时的host配置可能被这段逻辑覆盖,导致实际请求地址和选中的目标地址不一致
可行解决方案
方案1:正确配置authentication服务的CORS(最直接)
在authentication的Express服务中配置CORS规则,注意优先处理预检OPTIONS请求,且CORS配置要放在所有路由定义之前:
// 先安装依赖:npm install cors const cors = require('cors') const corsOptions = { origin: 'http://localhost:3002', // 放行Swagger所在的3002端口请求 credentials: true, allowedHeaders: ['Content-Type', 'Authorization', 'Accept'] } // 优先处理所有预检OPTIONS请求 app.options('*', cors(corsOptions)) app.use(cors(corsOptions)) // 后续再写路由相关代码
如果之前已经配置过CORS仍报错,优先检查配置顺序是否在路由定义之后,或者规则里没有放行Swagger发起请求的请求头、请求方法。
方案2:在administrator服务配置代理转发(无需修改authentication服务)
在administrator服务中添加代理中间件,所有Swagger发起的authentication服务请求都先经过3002端口转发,天然规避跨域:
- 安装代理依赖:
npm install http-proxy-middleware - 在administrator的
app.js中添加代理配置:
const { createProxyMiddleware } = require('http-proxy-middleware'); // 所有以/auth为前缀的请求转发到3005端口的authentication服务 app.use('/auth', createProxyMiddleware({ target: 'http://localhost:3005', changeOrigin: true, pathRewrite: { '^/auth': '' // 如不需要前缀可删除该行,根据实际接口规则调整 } }))
- 调整Swagger配置中authentication服务的接口前缀或服务地址,将目标地址修改为
http://localhost:3002/auth即可。
方案3:合并多服务Swagger文档统一暴露
将authentication服务的Swagger文档也加载到administrator的Swagger UI中,无需手动切换服务地址:
// 加载authentication服务的Swagger yaml文件,也可以通过接口从3005服务拉取实时文档 const authSwaggerDocument = YAML.load('./auth-swagger.yml') // 新增路由暴露authentication服务的Swagger文档 app.use('/auth-api-docs', function(req, res, next) { authSwaggerDocument.host = req.get('host') req.swaggerDoc = authSwaggerDocument next() }, swaggerUi.serve, swaggerUi.setup(null, swaggerOptions))
排查技巧:打开浏览器控制台的网络面板,查看跨域请求的响应头是否存在
Access-Control-Allow-Origin字段,如果不存在说明目标服务的CORS配置未生效,优先检查配置规则。
内容的提问来源于stack exchange,提问作者Soham Lawar
相关产品推荐
相关产品推荐

