一、微服务跨域核心逻辑
- 前端请求 → 先到 Ocelot 网关 → 再转发给下游微服务
- 浏览器的跨域校验只认网关返回的响应头,不认下游服务
- 最佳实践:网关统一配置跨域,下游微服务【一律不配置跨域】→ 避免跨域头重复、浏览器直接报错
核心是浏览器在 "把关"。前端发跨域请求时,浏览器会自动带上前端的源地址,后端根据配置的白名单决定是否在响应头加 "允许访问" 标记,最后浏览器检查这个标记,如果匹配就放行数据给前端,不匹配就拦截。所以整个跨域校验过程,浏览器是 "执行者",后端配置是 "规则",两者配合完成安全校验。
二、代码(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 个问题
- 没加 OPTIONS:AllowedMethods 漏写预检请求
- 下游服务也配了跨域:头重复,浏览器报错
- 域名写错:AllowedOrigins 没加 http/https 或端口写错
六、总结(一句话记住)
- 微服务跨域 只配网关,不配下游
- Ocelot.json 配置跨域后,网关自动给响应加允许头
- 浏览器看到允许头 → 放行数据 → 前端正常调用接口