ASP.NET WebAPI 15 CORS

來源:互聯網
上載者:User

標籤:

同源策略

首先基於安全的原因,瀏覽器是存在同源策略這個機制的,同源策略阻止從一個源載入的文檔或指令碼擷取或設定另一個源載入的文檔的屬性。

對於同源必須要求URL在如下幾個方面相同:

  1. 網路通訊協定(http與https不同)
  2. 網域名稱
  3. 連接埠(80與8080不同)

 

 

JSONP

JSONP是跨域訪問的一種方法。在web開發中我們經常會引用第三方的js檔案,這個時候我們會發現瀏覽器並沒有攔截。JSONP就是利用向網頁中添加script標籤的方式去進行跨域訪問。

一般處理在處理JSONP的時候會將回呼函數名與參數作為QueryString傳給服務端,服務端再根據上傳的函數名產生js回傳給用戶端。

由於採用的是添加script標籤的方式,所以JSONP只能通過GET方法訪問伺服器。另外由於服務端要根據上傳的函數名產生js,所以JSONP方法得到的並不是資料,而是方法的調用。

在Demo中我寫了一個JSONP的服務端產生與用戶端調用方法。

 

CORS

對於CORSAccess-Control-Allow-Origin

引用System.Web.Http.Cors庫

通過NuGet管理添加System.Web.Http.Cors,我引用的庫名為:Microsoft ASP.NET Web API 2.2 Cross-Origin Support

 

引用庫後,首先在WebApiConfig.Register方法中首行,添加一句 config.EnableCors()(記得一定要添加到首行。開始我也是添加在末行,但一直運行不成功,花了好半天功夫,才找到是這個問題。這個以後有時間再看看Cors內部的實現原理,按說不應該出現這樣的問題。)。

 

public static void Register(HttpConfiguration config)  { // Web API 配置和服務config.EnableCors(); // Web API 路由config.MapHttpAttributeRoutes();   config.Routes.MapHttpRoute(  name: "DefaultApi",  routeTemplate: "api/{controller}/{action}/{id}",  defaults: new { id = RouteParameter.Optional } );  } 

 

 

 

 

System.Web.Http.Cors庫對於Cors控制也是通過特性(Attribute)來實現的。System.Web.Http.Cors庫提供了兩個與Cors的特性:EnableCorsAttribute與DisableCorsAttribute,這兩個特性都是基於Controller與Action的。

 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public sealed class DisableCorsAttribute : Attribute, ICorsPolicyProvider { public DisableCorsAttribute(); public Task<System.Web.Cors.CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken);  } 

 

 

 

 

 

 

 

 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public sealed class EnableCorsAttribute : Attribute, ICorsPolicyProvider { public EnableCorsAttribute(string origins, string headers, string methods); public EnableCorsAttribute(string origins, string headers, string methods, string exposedHeaders); public IList<string> ExposedHeaders { get; } public IList<string> Headers { get; } public IList<string> Methods { get; } public IList<string> Origins { get; } public long PreflightMaxAge { get; set; } public bool SupportsCredentials { get; set; }  public Task<System.Web.Cors.CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken);  } 

 

 

 

EnableCorsAttribute與DisableCorsAttribute都實現了ICorsPolicyProvider介面。但 DisableCorsAttribute沒有別的屬性與建構函式,它的使用情境大致為當Controller已經被添加EnableCorsAttribute後,為個別不做Cors的Action禁用掉。

EnableCorsAttribute的與回應標頭部資訊相對應,其對應關係如下:

屬性

頭部資訊

備忘

Origins

Allow-Control-Allow-Origin

CORS允許的請求網域名稱,用逗號(,)去區他不同的網域名稱,如:http://localhost:64299,http://www.baidu.com。

對於沒有網域名稱,可以用星號(*)

Methods

Allow-Control-Allow-Method

CORS允許的要求方法,用法同Origins

Headers

Allow-Control-Allow-Headers

 

ExposedHeaders

Allow-Control-Expose-Header

 

PreflightMaxAge

Allow-Control-Max-Age

 

SupportsCredentials

Allow-Control-Allow-Credentials

 

 

 

 

 

 

還是IE

 

在測試過程中我發現在Firefox上能夠正常運行,但到了IE是就不行了,經過一番尋找,發現要在要添加一句話:

jQuery.support.cors = true;

 

但加了這句話後,雖然/api/demo/GetFigureByCors可以調的,但/api/demo/GetFigureNoCors也可以調用了。到這又鬱悶了,這又是要搞那樣。又經過一番折騰,才發現這個時候jQuery並不是用的XMLHttpRequest,而是採用的IE內建的XDomainRequest組件,並且該組件只支援IE8及以上。

 

 

關於Demo

在Demo中出於對同源的規則的考慮,我定義了兩個Web項目:API_15與API_15.Web。API_15中的DemoController分別定義的三個方法GetFigureByJsonP,GetFigureNoCors,GetFigureByCors分別用於JSONP,非Cors,Cors調用。

 

public class DemoController : ApiController { public HttpResponseMessage GetFigureByJsonP(string callback)  { StringBuilder result = new StringBuilder();   result.Append("callback(");  result.Append(JsonConvert.SerializeObject(FigureManager.Figures));  result.Append(")"); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result.ToString()) };  }  public IEnumerable<Figure> GetFigureNoCors()  { return FigureManager.Figures;  }  //[EnableCors(origins:"*",headers: "*",methods:"*")] [EnableCors(origins: "http://localhost:64299,http://www.baidu.com", headers: "GET,POST", methods: "*")] public IEnumerable<Figure> GetFigureByCors()  { return FigureManager.Figures;  }  }

 

 

 

 

在API_15.Web項目中只定義了一個頁面,通過jQuery的AJAX去調用API_15中三個Action。

 

 

 

源碼

   

Github: https://github.com/BarlowDu/WebAPI(API_15,API_15.Web)

 

ASP.NET WebAPI 15 CORS

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.