WebAPI Ajax 跨域請求解決方案(CORS實現)

來源:互聯網
上載者:User

標籤:das   jsonp   防止   就是   hit   action   bundle   .com   windows   

概述

 

ASP.NET Web API 的好用使用過的都知道,沒有複雜的設定檔,一個簡單的ApiController加上需要的Action就能工作。

 

但是在使用API的時候總會遇到跨域請求的問題,特別各種APP萬花齊放的今天,API的跨域請求是不能避免的。

 

在預設情況下,為了防止CSRF跨站的偽造攻擊(或者是 javascript的同源策略(Same-Origin Policy)),一個網頁從另外一個域擷取資料時就會收到限制。

 

有一些方法可以突破這個限制,那就是大家熟知的JSONP, 當然這隻是眾多解決方案中一種,由於JSONP只支援GET的請求,如今的複雜業務中已經不能滿足需求。

 

而CORS(Cross Origin Resource Sharing https://www.w3.org/wiki/CORS)跨域資源共用,是一種新的header規範,可以讓伺服器端放鬆跨域的限制,可以根據header來切換限制或者不限制跨域請求。重要的是它支援所有http請求方式。

 

問題

 

XMLHttpRequest 跨域 POST或GET請求 ,請求方式會自動變成OPTIONS的問題。

 

由於CORS(cross origin resource share)規範的存在,瀏覽器會首先發送一次options嗅探,同時header帶上origin,判斷是否有跨域請求許可權,伺服器響應access control allow origin的值,供瀏覽器與origin匹配,如果匹配則正式發送post請求,即便是伺服器允許程式跨域訪問,若不支援 options 請求,請求也會死掉。

 

原因

 

瀏覽器為了安全起見,會Preflighted Request的透明伺服器驗證機制支援開發人員使用自訂的頭部、GET或POST之外的方法,以及不同類型的主題內容,也就是會先發送一個 options 請求,問問伺服器是否會正確(允許)請求,確保請求發送是安全的。

 

出現 OPTIONS 的情況一般為:

 

1、非GET 、POST請求

 

2、POST請求的content-type不是常規的三個:application/x- www-form-urlencoded(使用 HTTP 的 POST 方法提交的表單)、multipart/form-data(同上,但主要用於表單提交時伴隨檔案上傳的場合)、text/plain(純文字) 

 

3、POST請求的payload為text/html 

 

4、設定自訂頭部

 

OPTIONS要求標頭部中會包含以下頭部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers,發送這個請求後,伺服器可以設定如下頭部與瀏覽器溝通來判斷是否允許這個請求。

Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers

 

解決方案

 

此方法功能強大,可以解決ASP.NET Web API複雜跨域請求,攜帶複雜頭部資訊,本文內容和授權驗證資訊

 

方法一

  1 public class CrosHandler:DelegatingHandler  2   3 {  4   5     private const string Origin = "Origin";  6   7     private const string AccessControlRequestMethod = "Access-Control-Request-Method";  8   9     private const string AccessControlRequestHeaders = "Access-Control-Request-Headers"; 10  11     private const string AccessControlAllowOrign = "Access-Control-Allow-Origin"; 12  13     private const string AccessControlAllowMethods = "Access-Control-Allow-Methods"; 14  15     private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; 16  17     private const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials"; 18  19     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 20  21     { 22  23         bool isCrosRequest = request.Headers.Contains(Origin); 24  25         bool isPrefilightRequest = request.Method == HttpMethod.Options; 26  27         if (isCrosRequest) 28  29         { 30  31             Task<HttpResponseMessage> taskResult = null; 32  33             if (isPrefilightRequest) 34  35             { 36  37                 taskResult = Task.Factory.StartNew<HttpResponseMessage>(() => 38  39                 { 40  41                     HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); 42  43                     response.Headers.Add(AccessControlAllowOrign, 44  45                         request.Headers.GetValues(Origin).FirstOrDefault()); 46  47                     string method = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault(); 48  49                     if (method != null) 50  51                     { 52  53                         response.Headers.Add(AccessControlAllowMethods, method); 54  55                     } 56  57                     string headers = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders)); 58  59                     if (!string.IsNullOrWhiteSpace(headers)) 60  61                     { 62  63                         response.Headers.Add(AccessControlAllowHeaders, headers); 64  65                     } 66  67                     response.Headers.Add(AccessControlAllowCredentials, "true"); 68  69                     return response; 70  71                 }, cancellationToken); 72  73             } 74  75             else 76  77             { 78  79                 taskResult = base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t => 80  81                 { 82  83                     var response = t.Result; 84  85                     response.Headers.Add(AccessControlAllowOrign, 86  87                         request.Headers.GetValues(Origin).FirstOrDefault()); 88  89                     response.Headers.Add(AccessControlAllowCredentials, "true"); 90  91                     return response; 92  93                 }); 94  95             } 96  97             return taskResult; 98  99         }100 101         return base.SendAsync(request, cancellationToken);102 103     }104 105 }

 

使用方式,在Global.asax檔案添加

 

 1 protected void Application_Start() 2  3 { 4  5     IOCConfig.RegisterAll(); 6  7     AreaRegistration.RegisterAllAreas(); 8  9     WebApiConfig.Register(GlobalConfiguration.Configuration);10 11     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);12 13     RouteConfig.RegisterRoutes(RouteTable.Routes);14 15     BundleConfig.RegisterBundles(BundleTable.Bundles);16 17     GlobalConfiguration.Configuration.MessageHandlers.Add(new CrosHandler());18 19 }

 

 

方法二

 

設定檔中添加如下配置,此方法簡單,應對簡單的跨域請求

 

<system.webServer>    <httpProtocol>      <customHeaders>        <add name="Access-Control-Allow-Origin" value="*" />        <add name="Access-Control-Allow-Headers" value="Content-Type" />        <add name="Access-Control-Allow-Methods" value="GET, POST,OPTIONS" />      </customHeaders>    </httpProtocol><system.webServer>

原文:簡玄冰.com/jianxuanbing/p/7324929.html

參考文獻:https://code.msdn.microsoft.com/windowsdesktop/Implementing-CORS-support-a677ab5d#content

WebAPI Ajax 跨域請求解決方案(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.