天天看點

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

前言:上篇總結了下WebApi的接口測試工具的使用,這篇接着來看看WebAPI的另一個常見問題:跨域問題。本篇主要從執行個體的角度分享下CORS解決跨域問題一些細節。

WebApi系列文章

<a href="http://www.cnblogs.com/landeanfen/p/5210356.html">C#進階系列——WebApi接口測試工具:WebApiTestClient</a>

<a href="http://www.cnblogs.com/landeanfen/p/5177176.html">C#進階系列——WebApi 跨域問題解決方案:CORS</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html">C#進階系列——WebApi身份認證解決方案:Basic基礎認證</a>

<a href="http://www.cnblogs.com/landeanfen/p/5337072.html">C#進階系列——WebApi接口傳參不再困惑:傳參詳解</a>

<a href="http://www.cnblogs.com/landeanfen/p/5501487.html">C#進階系列——WebApi接口傳回值不困惑:傳回值類型詳解</a>

C#進階系列——WebApi異常處了解決方案

C#進階系列——WebApi區域Area使用小結

同源政策:出于安全考慮,浏覽器會限制腳本中發起的跨站請求,浏覽器要求JavaScript或Cookie隻能通路同域下的内容。

正是由于這個原因,我們不同項目之間的調用就會被浏覽器阻止。比如我們最常見的場景:WebApi作為資料服務層,它是一個單獨的項目,我們的MVC項目作為Web的顯示層,這個時候我們的MVC裡面就需要調用WebApi裡面的接口取資料展現在頁面上。因為我們的WebApi和MVC是兩個不同的項目,是以運作起來之後就存在上面說的跨域的問題。

CORS全稱Cross-Origin Resource Sharing,中文全稱跨域資源共享。它解決跨域問題的原理是通過向http的請求封包和響應封包裡面加入相應的辨別告訴浏覽器它能通路哪些域名的請求。比如我們向響應封包裡面增加這個Access-Control-Allow-Origin:http://localhost:8081,就表示支援http://localhost:8081裡面的所有請求通路系統資源。其他更多的應用我們就不一一列舉,可以去網上找找。

 下面我就結合一個簡單的執行個體來說明下如何使用CORS解決WebApi的跨域問題。

我們建立兩個項目,一個WebApi項目(下圖中WebApiCORS),一個MVC項目(下圖中Web)。WebApi項目負責提供接口服務,MVC項目負責頁面呈現。如下:

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

其中,Web與WebApiCORS端口号分别為“27239”和“27221”。Web項目需要從WebApiCORSS項目裡面取資料,很顯然,兩個項目端口不同,是以并不同源,如果使用正常的調用方法肯定存在一個跨域的問題。

簡單介紹下測試代碼,Web裡面有一個HomeController

對應的Index.cshtml

Index.js檔案

WebApiCORS項目裡面有一個測試的WebApi服務ChargingController

配置WebApi的路由規則為通過action調用。WebApiConfig.cs檔案

 IE浏覽器:

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

谷歌浏覽器:

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

這個結果另部落客也很吃驚,不做任何跨域處理,IE10、IE11竟然可以直接請求資料成功,而同樣的代碼IE8、IE9、谷歌浏覽器卻不能跨域通路。此原因有待查找,應該是微軟動了什麼手腳。

首先介紹下CORS如何使用,在WebApiCORS項目上面使用Nuget搜尋“microsoft.aspnet.webapi.cors”,安裝第一個

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

然後在App_Start檔案夾下面的WebApiConfig.cs檔案夾配置跨域

我們暫定三個“*”号,當然,在項目中使用的時候一般需要指定對哪個域名可以跨域、跨域的操作有哪些等等。這個在下面介紹。

IE10、IE11

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

谷歌浏覽器

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

IE8、IE9

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

這個時候又有新問題了,怎麼回事呢?我都已經設定跨域了呀,怎麼IE8、9還是不行呢?這個時候就有必要說說CORS的浏覽器支援問題了。網上到處都能搜到這張圖:

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

上圖描述了CORS的浏覽器支援情況,可以看到IE8、9是部分支援的。網上說的解決方案都是Internet Explorer 8 、9使用 XDomainRequest 對象實作CORS。是不是有這麼複雜?于是部落客各種百度尋找解決方案。最後發現在調用處指定 jQuery.support.cors = true; 這一句就能解決IE8、9的問題了。具體是在Index.js裡面

這句話的意思就是指定浏覽器支援跨域。原來IE9以上版本的浏覽器、谷歌、火狐等都預設支援跨域,而IE8、9卻預設不支援跨域,需要我們指定一下。你可以在你的浏覽器裡面列印jQuery.support.cors看看。這樣設定之後是否能解決問題呢?我們來看效果:

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

問題完美解決。至于網上說的CORS對IE8、9的解決方案XDomainRequest是怎麼回事,有待執行個體驗證。

上文我們使用

這一句解決了跨域問題,上面說了,這種*号是不安全的。因為它表示隻要别人知道了你的請求url,任何請求都可以通路到你的資源。這是相當危險的。是以需要我們做一些配置,限制通路權限。比如我們比較常見的做法如下:

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

然後在WebApiConfig.cs檔案的Register方法裡面

C#進階系列——WebApi 跨域問題解決方案:CORS一、跨域問題的由來二、跨域問題解決原理三、跨域問題解決細節四、總結

配置方法二、如果你隻想對某一些api做跨域,可以直接在API的類上面使用特性标注即可。

以上就是一個簡單的CORS解決WebApi跨域問題的執行個體,由于部落客使用WebApi的時間并不長,是以很多理論觀點未必成熟,如果有說的不對的,歡迎指出。部落客在此多謝啦。

繼續閱讀