Azure静态Web应用Data API Builder GraphQL端点CORS问题
问题背景
Blazor 8 WASM前端部署在Azure Static Web Apps(SWA),后端为连接Cosmos DB NoSQL的Data API Builder(DAB)GraphQL端点。生产环境内前端调用API正常,Postman直接访问生产API也正常,但本地开发环境(http://localhost:端口)调用生产API时触发CORS报错:
Access to fetch at 'https://mypublicurl.azurestaticapps.net/data-api/graphql' from origin 'http://localhost:4280' 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.
已尝试在staticwebapp.database.config.json中配置CORS origins,但未解决问题。
核心原因
之前的配置方向有误:staticwebapp.database.config.json是本地独立运行DAB服务时的CORS配置文件,而部署在SWA中的DAB,请求会先经过SWA的反向代理层,CORS规则由SWA统一管控,DAB自身的CORS配置不会生效。
解决思路
1. 通过SWA的staticwebapp.config.json配置生产环境CORS
在前端项目根目录创建或修改staticwebapp.config.json,添加针对DAB GraphQL端点的CORS规则:
全局CORS配置(适用于所有API路径)
{ "globalHeaders": { "Access-Control-Allow-Origin": "http://localhost:4280,http://localhost:5196", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization" }, "routes": [], "mimeTypes": {} }
路径级精细配置(仅针对DAB GraphQL端点)
{ "routes": [ { "route": "/data-api/graphql", "headers": { "Access-Control-Allow-Origin": "http://localhost:4280,http://localhost:5196", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type" } } ] }
配置完成后,将该文件提交并重新部署到SWA,生产环境的API就会返回正确的CORS响应头。
2. 本地开发时用SWA模拟器代理请求(无需修改生产配置)
如果不想改动生产环境的CORS规则,可以通过SWA CLI模拟器将本地请求代理到生产API,避免跨域:
- 在项目根目录创建
swa-cli.config.json:
{ "configurations": { "dev": { "app": { "command": "dotnet watch run --project YourBlazorProjectName", "port": 4280 }, "api": { "url": "https://mypublicurl.azurestaticapps.net/data-api" } } } }
修改Blazor客户端的API请求地址为
/data-api/graphql(相对路径)。启动SWA模拟器:
swa start dev
此时本地Blazor的请求会通过模拟器代理到生产API,不会触发跨域问题。
3. 验证CORS配置是否生效
用curl发送预检请求验证生产API的响应头:
curl -X OPTIONS https://mypublicurl.azurestaticapps.net/data-api/graphql -H "Origin: http://localhost:4280" -H "Access-Control-Request-Method: POST" -v
检查响应头中是否包含Access-Control-Allow-Origin: http://localhost:4280,确认配置生效。
内容的提问来源于stack exchange,提问作者Rodney Mort

