使用GCP API Gateway时XMLHttpRequest遇CORS错误求助
错误信息
Access to XMLHttpRequest at 'https://blablabla.ue.gateway.dev/customers/?platform=android' from origin 'https://blablabla-customer.web.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
问题背景
Web应用托管在https://blablabla-customer.web.app,向https://blablabla.ue.gateway.dev的API端点发起请求时触发CORS错误,核心原因是响应未包含正确的Access-Control-Allow-Origin标头。
已尝试无效的方法
- 在客户端手动添加
Access-Control-Allow-Origin标头(该标头为服务器响应头,客户端设置不生效) - 在Node.js Express服务中配置
cors中间件:
const express = require('express'); const cors = require("cors"); const app = express(); const corsOptions = { origin: "*", } app.use(cors(corsOptions))
正确解决方案
由于你使用了Google Cloud API Gateway,请求会先经过Gateway路由到后端服务,因此必须在Gateway层面配置CORS规则,后端服务的CORS配置仅在直接访问时生效,通过Gateway访问时不生效。
1. 在OpenAPI配置中添加CORS规则
GCP API Gateway依赖OpenAPI规范定义API行为,需在你的OpenAPI YAML/JSON配置文件中添加CORS配置:
全局CORS配置(所有端点通用)
在openapi根节点下添加与paths同级的x-google-cors配置:
openapi: 3.0.1 info: title: 你的API名称 version: 1.0.0 x-google-backend: address: https://your-backend-service-url.run.app # 替换为你的Node.js服务地址 # 全局CORS配置 x-google-cors: allowOrigins: - https://blablabla-customer.web.app # 指定允许的前端源,不要用*(若需带凭证) allowMethods: - GET - POST - PUT - DELETE - OPTIONS allowHeaders: - Content-Type - Authorization maxAge: 3600 # 预检请求缓存时长(秒) paths: # 你的API路径定义 /customers/: get: summary: 获取客户列表 responses: '200': description: 请求成功
特定路径CORS配置(仅针对单个端点)
如果只需给某个API路径配置CORS,可在对应路径下添加options方法处理预检请求:
paths: /customers/: options: summary: 处理CORS预检请求 responses: '200': description: 预检响应 headers: Access-Control-Allow-Origin: schema: type: string example: https://blablabla-customer.web.app Access-Control-Allow-Methods: schema: type: string example: GET, OPTIONS Access-Control-Allow-Headers: schema: type: string example: Content-Type x-google-backend: address: https://your-backend-service-url.run.app path_translation: APPEND_PATH_TO_ADDRESS get: summary: 获取客户列表 responses: '200': description: 请求成功
2. 重新部署API Gateway
修改完OpenAPI配置后,执行以下命令重新部署Gateway实例:
gcloud api-gateway apis deploy YOUR_API_ID --api-config=YOUR_CONFIG_ID --project=YOUR_PROJECT_ID
替换其中的YOUR_API_ID、YOUR_CONFIG_ID和YOUR_PROJECT_ID为你的GCP资源信息。
3. 避免后端与Gateway的CORS配置冲突
如果后端Express服务仍保留cors中间件,确保其配置与Gateway的规则一致,或者暂时关闭后端的CORS配置,由Gateway全权处理跨域逻辑,防止响应标头冲突。
带凭证请求的额外配置
如果你的请求需要携带凭证(如Cookie、HTTP认证信息),需在x-google-cors中添加allowCredentials: true,且allowOrigins必须指定具体源(不能用*):
x-google-cors: allowOrigins: - https://blablabla-customer.web.app allowMethods: - GET - POST - OPTIONS allowHeaders: - Content-Type - Authorization allowCredentials: true maxAge: 3600
内容的提问来源于stack exchange,提问作者muhammad refda

