Google Cloud Run服务拦截CORS预检OPTIONS请求排查求助
我有一个运行标准Node.js/Express应用的Google Cloud Run服务。当Chrome扩展发送Content-Type为application/json且带自定义请求头的POST请求时,浏览器的预检OPTIONS请求触发CORS错误:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource。
我已经在Express中间件栈最顶部配置了手动处理OPTIONS请求并添加所需响应头的中间件,但问题依然存在,说明请求在到达应用代码前就被拦截了。服务部署启动成功,没有入口点错误。
想请教:Google Cloud Run或Google Cloud网络基础设施中,哪些环节可能会拦截预检OPTIONS请求、阻止其到达容器,或是从响应中剥离Access-Control-Allow-Origin头?
完整index.js代码
// index.js (手动处理CORS重写版) const express = require('express'); const { google } = require('googleapis'); // --- 配置 --- const API_KEY = '**************'; // 已脱敏 const app = express(); const PORT = process.env.PORT || 8080; // --- 中间件 --- // 手动处理预检请求的CORS中间件 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key'); if (req.method === 'OPTIONS') { return res.status(204).send(); } next(); }); app.use(express.json()); // --- 路由处理 --- app.post('/', (req, res) => { console.log("主 '/' 路由收到请求。请求体:", req.body); res.status(200).json({ response: `命令已接收。` }); }); // ... 其他路由 // --- 服务启动 --- app.listen(PORT, () => { console.log(`服务监听端口 ${PORT}`); });
Cloud Run的Ingress设置:如果服务设置了
Ingress: Internal only或Ingress: Internal and Cloud Load Balancing,而Chrome扩展从外部网络发起请求,预检OPTIONS请求会被直接拦截,根本到不了容器。检查服务的Ingress配置,确保设置为Ingress: All(允许所有来源请求)。Cloud Armor安全策略:如果服务前端配置了Cloud Armor,可能存在拦截OPTIONS请求或修改响应头的规则。检查Cloud Armor的策略,确认没有针对OPTIONS方法的拦截规则,也没有移除CORS相关响应头的配置。
容器端口映射错误:确保Express应用监听的端口(
process.env.PORT或8080)和Cloud Run配置的容器端口完全一致。端口不匹配时,请求会被Cloud Run负载均衡器拦截,无法到达应用。自定义域名SSL配置问题:如果使用了自定义域名,SSL证书失效或域名映射配置错误,可能导致浏览器处理预检请求时出现异常,表现为CORS错误。检查自定义域名的SSL证书有效性及Cloud Run域名映射是否正确。
请求超时配置:虽然OPTIONS请求通常响应很快,但如果容器启动后未及时响应,Cloud Run可能提前终止请求。可以检查服务的超时设置是否合理。
内容的提问来源于stack exchange,提问作者randomblink

