WebApi中跨域解決辦法
在做Web開發中,常常會遇到跨域的問題,到目前為止,已經有非常多的跨域解決方案。由於時間有限,本文不會深入。
筆者遇到的問題是Js呼叫WebAPI中的資料進行跨域的場景。涉及若干跨域方案:
方案1:jsonp+回撥
方案2:Microsoft.AspNet.WebApi.Cors提供的跨域屬性
方案3:利用ACAO編寫自定義Filter實現
一、關於方案一
方案1是同事提出來的,已經經過論證,並且自己研究過,是可行的。本質上是通過script標籤動態載入js,還有callback機制。
但是,我個人覺得這個方案有些不足:
-
實現細節複雜,技術複雜性增大了不少,並且不好理解(伺服器端、Web前端兩頭忙活)
-
只支援單向跨域
-
只支援Get,不支援Post等Http請求
-
擴充套件性不強
-
我在讀參考文章時,感覺思路不清晰(至於是作者思路不清晰,還是寫作思路不清晰,還是我個人理解能力不到位這個不好說。)
二、關於方案二
首先,我提出了方案2。當時在我看來,這個是比較合適的一個方案,接近完美。但是,它不可行。
原因在於:Microsoft.AspNet.WebApi.Cors的framework版本是4.5,而我們現有專案是4.0。我們的時間有限,幾乎沒有時間做深入研究。
三、關於方案三
我受方案2的啟發,個人實現了方案3。方案3實現的最終效果接近方案2。支援:Global級別、Controller級別、Action級別。
方案三的缺點:因為“Access-Control-Allow-Origin”是HTML5中新增的特性,所以IE10以下瀏覽器不支援。
程式碼如下:
using System.Web.Http.Filters; namespace MvcApplication1.CustomFilter { public class CrossSiteAttribute : ActionFilterAttribute { private const string Origin = "Origin"; private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin"; private const string originHeaderdefault = "*"; public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, originHeaderdefault); } } }
伺服器端程式碼示例:
[CrossSite] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; }
伺服器端只需要把過濾器的標籤[CrossSite]寫上,伺服器端就支援跨域了。省去了Web前端的處理和伺服器端回撥的處理。
當然,它很容易進行擴充套件。