自己造轮子是一件苦差事。 现在,您可以专注于业务开发,仅需集成 ⭐️Furion⭐️ 即可。
Skip to main content

16. CORS 跨域

16.1 什么是跨域

简单来说,当一个请求 url 的协议、域名、端口三者之间任意一个与当前页面 url 不同即为跨域。那为什么会出现跨域问题呢?

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的 javascript 脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

16.2 有跨域行为示例

当前页面 url被请求页面 url是否跨域原因
http://www.furion.icu/http://www.furion.icu/index.html同源(协议、域名、端口号相同)
http://www.furion.icu/https://www.furion.icu/index.html跨域协议不同(http/https)
http://www.furion.icu/http://www.baidu.com/跨域主域名不同(chinadot/baidu)
http://www.furion.icu/http://blog.furion.icu/跨域子域名不同(www/blog)
http://www.furion.icu:8080/http://www.furion.icu:7001/跨域端口号不同(8080/7001)

16.3 什么是 CORS

跨源资源共享 (CORS) :

  • 是一种 W3C 标准,可让服务器放宽相同的源策略。
  • 不是一项安全功能,CORS 放宽 securityAPI 不能通过允许 CORS 来更安全。 有关详细信息,请参阅 CORS 工作原理
  • 允许服务器明确允许一些跨源请求,同时拒绝其他请求。
  • 比早期的技术(如 JSONP)更安全且更灵活。

16.4 如何使用

16.4.1 添加 CORS 服务

启用跨域 Cors 支持首先添加 CorsAccessor 服务,如:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Furion.Web.Core
{
[AppStartup(700)]
public sealed class FurWebCoreStartup : AppStartup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCorsAccessor();

// ...
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...

app.UseCorsAccessor();

// ...
}
}
}
特别注意

services.AddCorsAccessor(); 需在 services.AddControllers() 之前注册。

app.UseCorsAccessor(); 需在 app.UseRouting();app.UseAuthentication(); 之间注册。

16.4.2 配置允许跨域域名

小提醒

默认情况下,Furion 允许所有域名来源访问,也就是无需配置任何来源域名,另外前端也需要设置请求参数:withCredentials:false

如果需要指定特定域名,则添加以下配置即可:

{
"CorsAccessorSettings": {
"PolicyName": "自定义跨域策略名",
"WithOrigins": ["http://localhost:4200", "https://furion.icu"]
}
}

16.5 CorsAccessorSettings 配置

  • CorsAccessorSettings
    • PolicyName:跨域策略名,字符串类型,必填,默认 FurCorsAccessor
    • WithOrigins:允许跨域的域名列表,字符串数组类型,默认 [ "http://localhost:4200" ]
    • WithHeaders:请求表头,没有配置则允许所有表头,字符串数组类型
    • WithExposedHeaders:响应标头,字符串数组类型
    • WithMethods:设置跨域允许请求谓词,没有配置则允许所有,字符串数组类型
    • AllowCredentials:跨域请求中的凭据,bool 类型
    • SetPreflightMaxAge:设置预检过期时间,int 类型,单位秒,**此配置可以控制客户端发送非 GETHEADPOST 请求前发送 OPTION 请求检查,状态码(204)

16.6 使用 axios 前端注意事项

由于 axios 对跨域有特定的需要,需要响应报文中公开特定 Header 才能放行,如:Access-Control-Expose-Headers: xxxxx,所以,如果前端使用了 axios 请求,需要添加以下配置:

{
"CorsAccessorSettings": {
"WithExposedHeaders": ["access-token","x-access-token"]
}
}

另外请求设置 withCredentials: false 即可。

16.7 使用 $.ajax 前端注意事项

使用 Jquery 前端请求可以参考以下配置:

$.ajax({
       url: "http://localhost:8080/getdata",
       type: "GET",
       xhrFields: {
           withCredentials: false // 如果是https请求,可以试试 true
       },
       crossDomain: true,
       success: function (res) {
           render(res);
       }
});

16.8 禁用跨域

有时候,我们希望某个方法不检查跨域请求,可以在 Action 中贴 [DisableCors] 特性即可。

16.9 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 跨域请求 知识可查阅 ASP.NET Core - 启用跨域请求 章节。