NestJS Swagger在CentOS7出现SSL_PROTOCOL_ERR,为何用HTTPS请求?
问题描述
本地执行npm start后,通过HTTP访问http://localhost:11002/api/及相关静态资源,Swagger文档页面可正常打开;将相同项目部署到CentOS7后,访问http://10.62.130.54:11002/api/正常,但加载swagger-ui-bundle.js时使用HTTPS请求,引发SSL_PROTOCOL_ERR,导致Swagger文档页面无法打开。使用版本:@nestjs/swagger@5.2.1、swagger-ui-express@4.5.0。
原因分析
- Swagger UI协议自动推断逻辑:Swagger UI会根据请求头的
X-Forwarded-Proto或当前页面访问协议,自动推断静态资源的请求协议。如果服务器存在反向代理(如Nginx),且代理配置错误将X-Forwarded-Proto设为https,就会触发Swagger UI强制用HTTPS请求资源。 - 服务器环境HTTPS配置残留:CentOS7服务器可能曾配置过HTTPS服务,或系统环境变量、NestJS配置中存在强制HTTPS的设置,导致Swagger UI的资源路径被错误替换为HTTPS。
- @nestjs/swagger版本特性:
@nestjs/swagger@5.x依赖Express的req.protocol值生成资源链接,若服务器Express实例因代理配置错误,获取到的req.protocol为https,就会生成HTTPS格式的资源路径。
解决方法
1. 强制指定Swagger UI资源协议
在NestJS的Swagger配置中,手动指定静态资源的协议和主机地址,覆盖自动推断逻辑:
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); const config = new DocumentBuilder() .setTitle('API文档') .setDescription('API接口描述') .setVersion('1.0') .build(); const document = SwaggerModule.createDocument(app, config); // 手动指定资源路径,强制使用HTTP SwaggerModule.setup('api', app, document, { swaggerOptions: { url: 'http://10.62.130.54:11002/api-json', }, customCssUrl: 'http://10.62.130.54:11002/swagger-ui.css', customJs: [ 'http://10.62.130.54:11002/swagger-ui-bundle.js', 'http://10.62.130.54:11002/swagger-ui-standalone-preset.js' ], }); await app.listen(11002); } bootstrap();
2. 修正反向代理配置
若使用Nginx作为反向代理,确保X-Forwarded-Proto配置正确,示例如下:
server { listen 11002; server_name 10.62.130.54; location / { proxy_pass http://localhost:11002; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 自动匹配当前请求协议(HTTP) } }
3. 修正Express协议推断
在NestJS中配置Express信任代理,确保req.protocol能获取到实际请求协议:
async function bootstrap() { const app = await NestFactory.create(AppModule); // 信任代理,让Express正确识别请求协议 app.set('trust proxy', true); // 或指定具体代理IP:app.set('trust proxy', '10.62.130.54'); // 后续Swagger配置... }
4. 检查环境变量与NestJS配置
确认服务器未设置强制HTTPS的环境变量(如NODE_ENV=production引发的默认配置),同时检查NestJS配置文件中是否存在错误的httpsOptions配置。
内容的提问来源于stack exchange,提问作者GYEONGSEOP KIM
相关产品推荐
相关产品推荐

