.NET Core + Ocelot 网关 跨域 (CORS) 配置

一、微服务跨域核心逻辑

  1. 前端请求 → 先到 Ocelot 网关 → 再转发给下游微服务
  2. 浏览器的跨域校验只认网关返回的响应头,不认下游服务
  3. 最佳实践:网关统一配置跨域,下游微服务【一律不配置跨域】→ 避免跨域头重复、浏览器直接报错

核心是浏览器在 "把关"。前端发跨域请求时,浏览器会自动带上前端的源地址,后端根据配置的白名单决定是否在响应头加 "允许访问" 标记,最后浏览器检查这个标记,如果匹配就放行数据给前端,不匹配就拦截。所以整个跨域校验过程,浏览器是 "执行者",后端配置是 "规则",两者配合完成安全校验。


二、代码(Ocelot 网关项目)

1. 第一步:Program.cs 核心代码(完整可复制)

csharp

运行

复制代码
using Ocelot.DependencyInjection;
using Ocelot.Middleware;

var builder = WebApplication.CreateBuilder(args);

// 1. 加载 Ocelot 配置文件(ocelot.json)
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);

// 2. 注入 Ocelot 服务
builder.Services.AddOcelot(builder.Configuration);

var app = builder.Build();

// 3. 使用 Ocelot 中间件(自动处理跨域+路由转发)
await app.UseOcelot();

app.Run();

2. 第二步:Ocelot.json 跨域配置(核心)

json

复制代码
{
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9000",  // 你的网关访问地址
    "CorsOptions": {
      "AllowedOrigins": [
        "http://localhost:8080",  // 前端开发地址(必须精准填写)
        "https://www.你的生产域名.com"  // 生产环境前端域名
      ],
      "AllowedMethods": [
        "GET",
        "POST",
        "PUT",
        "DELETE",
        "OPTIONS"  // 必须加!浏览器预检请求,不加必报错
      ],
      "AllowedHeaders": ["*"],  // 允许所有请求头(Token、Authorization等)
      "AllowCredentials": true,  // 允许携带Cookie/Token(登录必开)
      "MaxAge": 3600  // 预检请求缓存1小时,提升性能
    }
  },
  "Routes": [
    {
      "UpstreamPathTemplate": "/api/{service}/{everything}",  // 前端请求地址
      "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ],
      "DownstreamPathTemplate": "/api/{everything}",  // 转发到下游服务地址
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",  // 下游微服务地址
          "Port": 5001  // 下游微服务端口
        }
      ]
    }
  ]
}

三、关键配置解释

1. AllowedOrigins(允许的前端域名)

  • 必须精准填写:协议(http/https)+ 域名 + 端口
  • ❌ 错误写法:localhost:8080
  • ✅ 正确写法:http://localhost:8080
  • 生产环境禁止用 *,只填真实前端域名,保证安全

2. AllowedMethods(允许的请求方式)

  • 必须包含 OPTIONS:浏览器跨域前会先发预检请求,不包含直接报错

3. AllowCredentials(允许携带凭证)

  • 登录、Token、Cookie 必开 true
  • 开启后 不能用 * 允许所有域名,必须指定具体域名

4. 下游微服务注意事项

必须删除所有跨域代码(AddCors/UseCors) → 网关已经加了跨域头,下游再加会导致头重复,浏览器直接拦截


四、开发环境简易配置(本地调试用)

如果只是本地快速调试,Ocelot.json 可以这样写(允许所有前端访问):

json

复制代码
"CorsOptions": {
  "AllowedOrigins": ["*"],
  "AllowedMethods": ["GET","POST","PUT","DELETE","OPTIONS"],
  "AllowedHeaders": ["*"],
  "AllowCredentials": false,  // 允许所有域名时,必须关闭凭证
  "MaxAge": 3600
}

⚠️ 警告:生产环境绝对不能用这个配置,存在严重安全风险!


五、跨域不生效?99% 是这 3 个问题

  1. 没加 OPTIONS:AllowedMethods 漏写预检请求
  2. 下游服务也配了跨域:头重复,浏览器报错
  3. 域名写错:AllowedOrigins 没加 http/https 或端口写错

六、总结(一句话记住)

  1. 微服务跨域 只配网关,不配下游
  2. Ocelot.json 配置跨域后,网关自动给响应加允许头
  3. 浏览器看到允许头 → 放行数据 → 前端正常调用接口
相关推荐
xxwl58514 小时前
markdown基础语法
状态模式
三川69814 小时前
深入浅出SSD 01:SSD综述
状态模式
cyadyx14 小时前
MapStruct 的转换实践
状态模式·mapstruct·充血模式
sugar__salt8 天前
从零理解 LLM 流式输出:Vue3 + DeepSeek API 实战
前端·人工智能·状态模式·sse·流式输出
ttwuai8 天前
Go 后台接口 401/403 排查:JWT 过期、刷新请求和权限码怎么定位
开发语言·golang·状态模式
ji_shuke9 天前
Vue3 前端批量打印 PDF/图片踩坑记:跨域、合并打印、对话框闪退与按钮一直 loading
前端·pdf·状态模式·pdf打印
ttwuai10 天前
Go 后台富文本图片上传失败排查:前端限制、接口和存储目录要一起看
前端·golang·状态模式
从此以后自律10 天前
三大传参注解完整详解
状态模式
ttod_qzstudio11 天前
【软考设计模式】状态模式:状态驱动行为自动转换与代码填空精讲
设计模式·状态模式
折哥的程序人生 · 物流技术专研11 天前
Java 23 种设计模式:从踩坑到精通 | 番外:状态 vs 策略 —— if-else 消除的两条路,你走对了吗?
java·spring·状态模式·策略模式·java面试·java设计模式·从踩坑到精通