瀏覽器的安全阻止一個域的本地頁面請求另外不同域的本地頁面,這個限制叫同源策略,這個安全特性用來阻止惡意站點從別的網站讀取數據
例如假如我有一個頁面叫A.html?
https://foo.example/A.html
現在頁面A.html有一個ajax代碼嘗試讀取B.html的HTML的源代碼,B頁面位于
https://bar.other
B.html位于不同的域,由于同源策略限制,A.html不能做ajax請求,ajax調用將返回錯誤消息:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
W3C提供了標準來放寬同源策略,允許實現跨源資源共享(CORS),如果https://bar.other實現CORS https://foo.example/A.html能夠ajax請求并讀取B.html
1 CORS如何工作
站點一旦啟用了CORS,Access-Control-Allow-Origin會被添加到請求的頭部,請求頭部將被自動設置跨域請求
因此,當一個頁請求到另外一個服務器或者域名的資源,服務器的響應Access-Control-Allow-Origin值被設置
通常,這個值為*,這意味著服務器共享請求資源針對互聯網上的每個域名,有時候,這個header的值將被設置為特定域名(或者域名列表),這意味著服務將共享資源僅僅針對特定域名(域列表)。
2 在ASP.NET Core中啟用CORS
在啟動項中添加如下代碼:
builder.Services.AddCors();
注意我們添加代碼行使用可選AllowAnyOrigin允許每一個域能夠CORS請求:
app.UseCors(builder =>
{builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
下面描述了各個方法作用
AllowAnyMethod() – 允許所有HTTP方法
AllowAnyHeader() – 允許所有請求頭
AllowCredentials() – 服務器必須允許憑據
如果只針對特定的域名啟用CORS,像http://www.domain.com , 在這種場景下你需要修改代碼如下:
app.UseCors(builder =>
{builder.WithOrigins("http://www.domain.com").AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
你也可以指定多個域在下面:
app.UseCors(builder =>
{builder.WithOrigins(new string[] { "https://example1.com", "https://example2.com" }).AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
3 在action或者controller上應用CORS策略
我們能定義一個或者多個CORS策略,針對策略添加CORS規則,我們將這些CORS規則應用到Controller和Action方法
下面代碼定義了用戶CORS策略命名為MyPolicy
var builder = WebApplication.CreateBuilder(args);
//?Adding?CORS?Policy
builder.Services.AddCors(options =>
{options.AddPolicy("MyPolicy",builder => builder.WithOrigins("https://www.yogihosting.com"));
});
//?Add?services?to?the?container.
builder.Services.AddControllersWithViews();
var?app?=?builder.Build();
//?Configure?the?HTTP?request?pipeline.
if (!app.Environment.IsDevelopment())
{app.UseExceptionHandler("/Home/Error");// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
//?Shows?UseCors?with?named?policy.
app.UseCors("MyPolicy");
app.UseAuthorization();
app.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
將策略名字傳遞到UseCors()方法:現在將CORS策略應用到每個action或者controller
3.1 每個Action
指定CORS策略針對特定的action,在action上添加[EnableCors]特性并指定策略名稱:
[EnableCors("MyPolicy")]
public?IEnumerable<string>?Get()
{return?new?string[]?{?"value1",?"value2"?};
}
3.2 每個Controller
[EnableCors("MyPolicy")]
public?class?HomeController?:?Controller?
在Controller和action上禁用CORS,使用[DisableCors]特性:
[DisableCors]
public?string?Get(int?id)
{return?"value";
}
源代碼地址:
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.GlobalizationLocalization/AspNetCore.GlobalLocalResFiles