ASP.NET Core CORS 簡單使用

from:http://www.cnblogs.com/xishuai/p/aspnet-core-cors.htmlcss

CORS 全稱"跨域資源共享"(Cross-origin resource sharing)。html

跨域就是不一樣域之間進行數據訪問,好比 a.sample.com 訪問 b.sample.com 中的數據,咱們若是不作任何處理的話,就會出現下面的錯誤:web

XMLHttpRequest cannot load b.sample.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'a.sample.com' is therefore not allowed access. The response had HTTP status code 404.json

請求和響應信息:api

Response Headers
Content-Type:text/html; charset=utf-8 Server:Microsoft-IIS/10.0 X-Powered-By:ASP.NET Request Headers Accept:*/* Accept-Encoding:gzip, deflate Accept-Language:zh-CN,zh;q=0.8 Connection:keep-alive Content-Length:32384 Host:b.sample.com Origin:a.sample.com

當請求發起後,Host 會獲取 Origin,而後進行判斷是否贊成這個請求,判斷的標準就是 Access-Control-Allow-Origin,若是 Host 服務器指定了 Origin 的配置,那麼在響應頭就會有:跨域

Access-Control-Allow-Origin:a.sample.com

相關的 Access-Control-*:緩存

  • Access-Control-Allow-Origin:指定請求頭中 Origin 是否被訪問,若是值爲 *,則表示可讓任何 Origin 訪問。
  • Access-Control-Request-Method:容許的 HTTP 請求方法,經常使用 Get、Post、Put 等,若是值爲 *,則表示容許全部的 HTTP 請求方法訪問。
  • Access-Control-Expose-Headers:客戶端默承認以從服務器獲取響應頭中的 Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma 字段信息,若是須要額外獲取其它 header 字段信息,則須要在服務端進行配置。
    Access-Control-Request-Headers:容許客戶端向服務器發送的額外請求頭信息,和上面的 Access-Control-Expose-Headers 比較類似,但方向是相反的,通常會用在添加自定義 header 的時候,好比 X-Param 等等。
  • Access-Control-Allow-Credentials:若是值爲 true,則表示服務端能夠接受客戶端發送的 Cookie 信息,但客戶端請求中須要同時設置withCredentials = true;
  • Access-Control-Max-Age:請求檢查的緩存時間,即在一段時間內,客戶端向服務器發送請求,不須要再進行檢查 Origin 的配置,而是直接進行請求訪問,固然服務器更改配置後除外。

以上是 CORS 的基本相關信息,咱們在 ASP.NET MVC 應用程序開發中,須要手動配置 CORS:服務器

public class AllowCorsAttribute : ActionFilterAttribute { private string[] _domains; public AllowCorsAttribute(params string[] domains) { _domains = domains; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var context = filterContext.RequestContext.HttpContext; if (context.Request.UrlReferrer != null) { var host = context.Request.UrlReferrer?.Host; if (host != null && _domains.Contains(host)) { context.Response.AddHeader("Access-Control-Allow-Origin", $"http://{host}"); } } else { context.Response.AddHeader("Access-Control-Allow-Origin", "*"); } context.Response.AddHeader("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT"); context.Response.AddHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); base.OnActionExecuting(filterContext); } }

上面代碼就是截獲每次 Action 請求,手動向請求上下文中增長相應頭的配置,以達到 CORS 的目的,Action 配置:微信

[AllowCors("a.sample.com", "c.sample.com")] public ActionResult Index() { return View(); }

而在 ASP.NET WebAPI 項目中配置 CORS,就不須要上面那麼複雜了,咱們只須要安裝:markdown

Install-Package Microsoft.AspNet.WebApi.Cors

而後配置啓用 CORS:

public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.EnableCors(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }

最後在對應的 Action 上面添加 CORS 配置就好了:

[EnableCors(origins: "http://a.sample.com", headers: "*", methods: "get,post", SupportsCredentials = true)] public ActionResult Index() { return View(); }

在 ASP.NET Core 的 CORS 配置和上面差很少,配置方法:

ConfigureServices 中添加配置:

public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddCors(options => options.AddPolicy("CorsSample", p => p.WithOrigins("http://a.example.com", "http://c.example.com").AllowAnyMethod().AllowAnyHeader())); }

Configure 中啓用配置:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); app.UseCors("CorsSample"); }

Action 啓用對應的 CORS,不啓用使用[DisableCors]

[EnableCors("CorsSample")] public ActionResult Index() { return View(); }

固然 CORS 在 ASP.NET Core 的使用不只於此,你也能夠進行自定義,具體查看最後的參考資料。

跨域除了 CORS,還有其它的解決方式:

  • JSONP:經過在文檔中嵌入一個<script>標記來從另外一個域中返回數據,因此只支持 GET 請求,但使用比較簡單,資料:ASP.NET Web API 配置 JSONP
  • document.domain:JS 配置代碼document.domain = ‘sample.com’;,設置完以後,同域之間就能夠 JS 互相訪問了,但存在一些隱患,好比一個站點被 JS 注入了,那麼就會牽扯到其它站點,資料:ASP.NET 頁面禁止被 iframe 框架引用

參考資料:

做者:田園裏的蟋蟀 
微信公衆號: 你好架構 
出處: http://www.cnblogs.com/xishuai/  公衆號會不定時的分享有關架構的方方面面,包含並不侷限於:Microservices(微服務)、Service Mesh(服務網格)、DDD/TDD、Spring Cloud、Dubbo、Service Fabric、Linkerd、Envoy、Istio、Conduit、Kubernetes、Docker、MacOS/Linux、Java、.NET Core/ASP.NET Core、Redis、RabbitMQ、MongoDB、GitLab、CI/CD(持續集成/持續部署)、DevOps等等。  本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
相關文章
相關標籤/搜索