1. 程式人生 > >WebApi中跨域解決辦法

WebApi中跨域解決辦法

在做Web開發中,常常會遇到跨域的問題,到目前為止,已經有非常多的跨域解決方案。由於時間有限,本文不會深入。

筆者遇到的問題是Js呼叫WebAPI中的資料進行跨域的場景。涉及若干跨域方案:

方案1:jsonp+回撥

方案2:Microsoft.AspNet.WebApi.Cors提供的跨域屬性

方案3:利用ACAO編寫自定義Filter實現

一、關於方案一

方案1是同事提出來的,已經經過論證,並且自己研究過,是可行的。本質上是通過script標籤動態載入js,還有callback機制。

但是,我個人覺得這個方案有些不足:

  1. 實現細節複雜,技術複雜性增大了不少,並且不好理解(伺服器端、Web前端兩頭忙活)

  2. 只支援單向跨域

  3. 只支援Get,不支援Post等Http請求

  4. 擴充套件性不強

  5. 我在讀參考文章時,感覺思路不清晰(至於是作者思路不清晰,還是寫作思路不清晰,還是我個人理解能力不到位這個不好說。)

二、關於方案二

首先,我提出了方案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前端的處理和伺服器端回撥的處理。

當然,它很容易進行擴充套件。