CentOS 7虚拟机中NestJS与React前端的CORS问题求助
同一CentOS 7虚拟机上React与NestJS的CORS问题排查与解决
问题描述
在同一台CentOS 7虚拟机上运行React前端和NestJS后端应用时,前端无法向后端发起REST请求,触发CORS错误,但本地Ubuntu机器上运行相同代码无此问题。需排查原因、解决方法,以及确认是否需要修改Axios配置。
错误信息
Multi-origin request blocked (cross-origin): the origin match criterion does not allow the remote resource to be read from http://localhost:3001/user. Reason: CORS request failed. Status code: (null)
NestJS后端代码
import { ValidationPipe } from "@nestjs/common"; import { NestFactory } from "@nestjs/core"; import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger"; import { AppModule } from "./app.module"; import * as cookieParser from "cookie-parser"; async function bootstrap() { const app = await NestFactory.create(AppModule, { cors: true, }); const config = new DocumentBuilder() .setTitle("Backend ") .setDescription("Api Backend") .setVersion("1.0") .addTag("Backend") .addBearerAuth( { type: "http", scheme: "bearer", bearerFormat: "JWT" }, "access-token" ) .build(); //Setup swagger module var options = { deepScanRoutes: true, }; const document = SwaggerModule.createDocument(app, config, options); SwaggerModule.setup("api", app, document); app.useGlobalPipes(new ValidationPipe()); app.use(cookieParser()); //Enable cors app.enableCors({ origin: ["http://localhost:3001","http://localhost:3006", "http://80.211.128.77:3001","http://memoryp.org:3006"], methods: ["GET", "POST", "PUT", "DELETE"], credentials: true, }); await app.listen(3001); } bootstrap();
原因分析
- CentOS 7防火墙拦截:虚拟机防火墙可能未开放3001端口,导致前端请求无法到达后端,浏览器误判为CORS错误(状态码null说明请求无响应)。
- CORS配置冲突:代码中同时在
NestFactory.create时设置{cors: true},又调用app.enableCors(),双重配置可能导致规则冲突,实际生效的CORS策略不符合预期。 - 请求地址指向错误:若从宿主机访问虚拟机上的前端,前端请求
localhost:3001会指向宿主机而非虚拟机,引发跨域。
解决方法
1. 处理虚拟机端口与防火墙
- 临时关闭防火墙测试:
systemctl stop firewalld - 永久开放3001端口(推荐):
firewall-cmd --add-port=3001/tcp --permanent firewall-cmd --reload - 检查虚拟机端口转发规则,确保宿主机能访问到虚拟机的3001端口(若从宿主机访问前端)。
2. 修复NestJS的CORS配置冲突
删除NestFactory.create中的{cors: true},仅保留app.enableCors()的配置,避免规则冲突:
async function bootstrap() { const app = await NestFactory.create(AppModule); // 移除{cors: true} // ... 其他代码保持不变 app.enableCors({ origin: ["http://localhost:3001","http://localhost:3006", "http://80.211.128.77:3001","http://memoryp.org:3006"], methods: ["GET", "POST", "PUT", "DELETE"], credentials: true, }); await app.listen(3001); }
3. 修正前端请求地址
- 若前端在虚拟机内运行,请求
localhost:3001正常; - 若从宿主机访问虚拟机前端,前端请求地址需改为虚拟机的IP地址:3001,而非
localhost。
4. Axios配置调整
由于后端开启了credentials: true,前端Axios需设置withCredentials: true以携带凭证(如Cookie):
// 全局配置 import axios from 'axios'; axios.defaults.withCredentials = true; // 单个请求配置 axios.get('/user', { withCredentials: true });
内容的提问来源于stack exchange,提问作者riki
相关产品推荐
相关产品推荐

