部署NestJS API至Google App Engine遇CORS问题求助
把NestJS API部署到Google App Engine后碰到了CORS问题,已经在main.ts里试了三种不同的CORS配置,每次部署只单独用一种,但本地Angular项目请求API还是报错:
尝试过的三种配置:
1.
const app = await NestFactory.create(AppModule, { cors: true });
app.enableCors();
const whiteList = ['http://localhost:4200',]; app.enableCors({ origin: whiteList, });
错误详情:
- 请求URL:
https://gle*********appspot.com/auth/login - Referrer Policy:
strict-origin-when-cross-origin - 错误提示:
Access to XMLHttpRequest at 'https://gleaming-****.uc.r.appspot.com/auth/login' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
还需要排查哪些配置或操作才能解决这个问题?
检查App Engine的
app.yaml配置
Google App Engine的路由规则可能会覆盖NestJS的CORS响应头。如果用了app.yaml里的handlers配置,要确保没有额外的拦截规则,也可以直接在handlers中添加CORS头:handlers: - url: /.* script: auto http_headers: Access-Control-Allow-Origin: http://localhost:4200 Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization注意:别同时在NestJS和
app.yaml里配置CORS,容易冲突,选一个统一配置就行。确认NestJS的CORS配置是否真的生效
部署后用Postman这类工具发一个OPTIONS请求到https://你的域名/auth/login,看响应头里有没有Access-Control-Allow-Origin。如果没有,要么是代码部署时没更新,要么是main.ts里的配置位置错了(比如放在app.listen()之后调用enableCors())。检查是否有前置代理或负载均衡干扰
App Engine前端可能有Cloud Load Balancer这类代理服务,它们可能会剥离或修改CORS响应头。去Google Cloud Console里看看负载均衡的配置,确保没有自定义的头过滤规则。手动处理预检OPTIONS请求
有时候NestJS没正确处理OPTIONS预检请求,导致失败。可以加个全局中间件专门处理:import { NestMiddleware, Injectable, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { Request, Response } from 'express'; @Injectable() export class CorsMiddleware implements NestMiddleware { use(req: Request, res: Response, next: () => void) { res.header('Access-Control-Allow-Origin', 'http://localhost:4200'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); if (req.method === 'OPTIONS') { res.sendStatus(200); } else { next(); } } } // 在AppModule里注册中间件 export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(CorsMiddleware).forRoutes('*'); } }清除部署缓存
App Engine有时候会缓存旧版本的部署,导致新的CORS配置不生效。可以在Google Cloud Console里手动删掉旧版本,或者部署时加--no-cache参数:gcloud app deploy --no-cache
内容的提问来源于stack exchange,提问作者EdgarAlejandro

