NestJS、Vue与Nginx分Docker容器部署出现CORS错误求助
问题分析与解决步骤
核心问题提示
Chrome报错*net::ERR_HTTP2_PROTOCOL_ERROR*是核心线索,大概率是协议不匹配或容器网络/HTTPS配置错误,Firefox的跨域报错可能是此问题引发的连锁反应,而非单纯的CORS规则失效。
步骤1:确认容器网络连通性
确保Vue、NestJS容器处于同一个Docker自定义网络:
- 执行
docker network ls查看现有网络,验证两个容器是否加入同一网络(可通过docker-compose的networks字段统一配置) - 进入Vue容器,执行
curl http://api:8802(先尝试HTTP请求),确认能正常访问NestJS接口,排除DNS解析或网络不通问题
步骤2:修正NestJS的服务配置
2.1 协议匹配检查
你Vue请求的是https://api:8802,但默认NestJS启动的是HTTP服务,协议不兼容会直接导致HTTP2错误。如果未给NestJS配置HTTPS证书,需将Vue请求地址改为http://api:8802;如果要启用HTTPS,需在NestJS中配置证书:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; import * as fs from 'fs'; async function bootstrap() { const httpsOptions = { key: fs.readFileSync('/path/to/private.key'), // 容器内证书路径 cert: fs.readFileSync('/path/to/certificate.crt'), }; const app = await NestFactory.create(AppModule, { httpsOptions, cors: { origin: '*', credentials: true, allowedHeaders: ['*'], methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], }, }); app.useGlobalPipes(new ValidationPipe()); await app.listen(8802, '0.0.0.0'); // 绑定0.0.0.0允许容器外访问 } bootstrap();
2.2 改用NestJS原生CORS配置
替换原express的cors中间件为NestJS原生配置,框架集成的方式更可靠:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule, { cors: { origin: '*', credentials: true, allowedHeaders: ['*'], methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], }, }); app.useGlobalPipes(new ValidationPipe()); await app.listen(8802, '0.0.0.0'); } bootstrap();
步骤3:Nginx代理的CORS配置(若Nginx介入API请求)
如果Nginx作为API的反向代理,需在配置中添加CORS响应头并处理预检请求:
server { listen 443 ssl; server_name your-domain.com; ssl_certificate /path/to/cert.crt; ssl_certificate_key /path/to/private.key; location /api/ { proxy_pass http://api:8802/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 配置CORS头 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; add_header Access-Control-Allow-Headers 'Content-Type, Authorization'; # 直接返回204处理OPTIONS预检请求 if ($request_method = OPTIONS) { return 204; } } }
验证流程
- 重启所有容器,确保配置生效
- 在Vue容器内执行
curl -v http(s)://api:8802/your-test-endpoint,查看响应头是否包含Access-Control-Allow-Origin: * - 重新测试前端请求,观察浏览器错误是否消失
内容的提问来源于stack exchange,提问作者Edward
相关产品推荐
相关产品推荐

