.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. 浏览器看到允许头 → 放行数据 → 前端正常调用接口
相关推荐
csdn_aspnet3 小时前
如何在 .NET Core WebAPI 和 Javascript 应用程序中安全地发送/接收密钥参数
javascript·.netcore·cryptojs
前端不太难6 小时前
鸿蒙游戏如何接入支付 / 排行榜 / 社交
游戏·状态模式·harmonyos
前端不太难13 小时前
OpenClaw:探索未知的多智能体中枢
状态模式·openclaw
阿珊和她的猫17 小时前
TypeScript 中的 `extends` 条件类型:定义与应用
javascript·typescript·状态模式
GISer_Jing1 天前
Electron 全场景调试实战指南
javascript·electron·状态模式
fe7tQnVan1 天前
三大 Agent-UI 协议深度剖析:AG-UI、A2UI 与 MCP-UI 的设计哲学与工程实践
ui·状态模式·命令模式
We་ct1 天前
JS手撕:DOM操作 & 浏览器API高频场景详解
开发语言·前端·javascript·面试·状态模式·操作·考点
MwEUwQ3Gx1 天前
用户智能体交互协议AG-UI(下)
ui·状态模式·交互
阿珊和她的猫2 天前
TypeScript中的never类型: 深入理解never类型的使用场景和特点
javascript·typescript·状态模式