Startup.cs
的 ConfigureServices
方法中配置 CorsPolicy
,并在 Configure
方法中使用 app.UseCors
中间件。
C# Web API 中的 CORS(跨域资源共享)是指在不同源(协议、域名、端口)之间进行资源共享的一种机制,在实际应用中,经常会遇到前端和后端分离的情况,此时就需要解决跨域问题,以下是关于 C# Web API 中 CORS 跨域的详细内容:
1、同源策略
定义:同源策略是浏览器的一种安全机制,用于限制不同源的客户端脚本对当前 DOM 对象读/写的操作,如果不同协议、域名、端口号任意一个不同,就被认为是不同的源。
作用:防止反面脚本从其他域访问敏感数据或执行反面操作,保护用户信息安全和网站安全,如果一个反面网站的脚本试图读取用户在另一个银行网站上的账户信息,同源策略会阻止这种访问。
2、跨域资源共享(CORS)
定义:CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器允许应用程序从不同的域访问资源,服务器可以根据这些 HTTP 头来决定是否允许来自特定域的请求。
原理:当浏览器发送一个跨域请求时,它会在请求头中添加一些额外的字段,如Origin
字段,表示请求的来源,服务器接收到请求后,会根据自身的 CORS 配置来判断是否允许该请求,如果允许,服务器会在响应头中添加相应的字段,如Access-Control-Allow-Origin
,告诉浏览器该请求是被允许的。
二、在 C# Web API 中启用 CORS
1、安装 CORS 包
使用 NuGet 包管理器安装Microsoft.AspNetCore.Cors
包,在 Visual Studio 的“工具”菜单中选择“NuGet 包管理器”->“管理解决方案的 NuGet 包”,搜索Microsoft.AspNetCore.Cors
并安装,或者在命令行中使用以下命令安装:
Install-Package Microsoft.AspNetCore.Cors
2、配置 CORS 中间件
在Startup.cs
文件中的ConfigureServices
方法中配置 CORS 服务,可以使用AddCors
方法添加 CORS 策略,并指定允许的源、方法和头部等信息。
public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => { builder.WithOrigins("http://example.com") .WithMethods("GET", "POST", "PUT", "DELETE") .WithHeaders("Content-Type"); }); }); services.AddControllers(); }
在Configure
方法中使用UseCors
中间件将 CORS 策略应用到请求管道中。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseCors("AllowSpecificOrigin"); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
3、全局启用 CORS
如果希望对所有控制器和动作方法都启用 CORS,可以在Startup.cs
文件中进行全局配置。
public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseCors(builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
但是需要注意的是,全局启用 CORS 可能会带来安全风险,应该谨慎使用,在实际生产环境中,建议根据具体需求配置允许的源、方法和头部等信息。
1、简单请求
定义:简单请求是指满足以下条件的请求:
使用了下列方法之一:GET
、HEAD
或POST
。
使用了下列头部字段:Accept
、Accept-Language
、Content-Language
、Content-Type
(但仅限于text/plain
、multipart/form-data
或application/x-www-form-urlencoded
)。
处理方式:对于简单请求,浏览器会自动发送一个预检请求(OPTIONS
方法)到服务器,询问是否允许实际的请求,服务器需要返回适当的响应头,如Access-Control-Allow-Origin
、Access-Control-Allow-Methods
和Access-Control-Allow-Headers
等,以告知浏览器该请求是否被允许,如果预检请求通过,浏览器才会发送实际的请求。
2、预检请求(Preflight Request)
定义:当请求的方法不是简单方法,或者请求头中包含了非简单头部字段时,浏览器会先发送一个预检请求到服务器,预检请求使用OPTIONS
方法,并且会包含Origin
头部字段和Access-Control-Request-Method
、Access-Control-Request-Headers
等字段,用于告知服务器实际请求的方法和头部信息。
处理方式:服务器收到预检请求后,需要检查请求的来源、方法和头部等信息是否符合要求,如果符合要求,服务器应该在响应头中返回Access-Control-Allow-Origin
、Access-Control-Allow-Methods
和Access-Control-Allow-Headers
等字段,以告知浏览器该请求是被允许的,否则,服务器应该返回一个错误响应。
3、实际请求
定义:如果预检请求通过,浏览器会发送实际的请求到服务器,实际请求的方法和头部信息与预检请求中声明的一致。
处理方式:服务器收到实际请求后,按照正常的请求处理流程进行处理,并返回相应的响应结果。
HTTP 头字段 | 描述 |
Origin | 表示请求的来源,即发起请求的域名(协议 + 主机 + 端口),浏览器会自动添加该字段到跨域请求中。 |
Access-Control-Allow-Origin | 服务器在响应中返回该字段,表示允许访问该资源的源,可以是一个具体的域名,也可以是 (表示所有源),但不建议使用 ,以免产生安全破绽。 |
Access-Control-Allow-Methods | 服务器在响应中返回该字段,表示允许的请求方法,如GET 、POST 、PUT 、DELETE 等,多个方法之间用逗号分隔。 |
Access-Control-Allow-Headers | 服务器在响应中返回该字段,表示允许的请求头部字段,如Content-Type 、X-Custom-Header 等,多个头部字段之间用逗号分隔。 |
Access-Control-Max-Age | 服务器在响应中返回该字段,表示预检请求的缓存时间(以秒为单位),在该时间内,浏览器可以直接发送实际请求而不需要再次发送预检请求。 |
Access-Control-Expose-Headers | 服务器在响应中返回该字段,表示暴露给前端的响应头部字段,除了常见的字段外,还可以自定义一些字段供前端使用。 |
1、问题:跨域请求被浏览器拦截
可能原因:服务器没有正确配置 CORS,或者浏览器的安全设置过于严格。
解决方法:检查服务器端的 CORS 配置是否正确,确保返回了正确的Access-Control-Allow-Origin
、Access-Control-Allow-Methods
和Access-Control-Allow-Headers
等字段,检查浏览器的安全设置,确保允许跨域请求。
2、问题:预检请求失败
可能原因:服务器不支持预检请求的方法或头部字段,或者服务器的安全策略不允许预检请求。
解决方法:检查服务器端的配置,确保支持预检请求的方法和头部字段,如果是服务器的安全策略问题,可以适当调整安全策略,允许预检请求。
CORS 跨域是 C# Web API 开发中一个重要的知识点,正确理解和应用 CORS 可以帮助开发者解决跨域问题,实现前后端的数据交互和资源共享,在实际开发中,需要根据具体的需求和安全考虑,合理配置 CORS 策略,确保应用程序的安全性和稳定性。