webapi地址:wapapi.ebcbuy.com
web地址:wapweb.ebcbuy.com
在默認情況下這兩個域名屬於兩個不同的域,他們之間的交互存在跨域的問題,但因為他們都同屬於一個二級域名下,所以通過簡單的設置就能實現跨域行為,但是考慮到實際生產環境中往往會出現兩個域名
完全不同的情況,所以這里不考慮這種特殊的情況,使用更通用的方法來解決跨域的問題。
首先在webapi上有如下所示一個接口

我們需要在我們的web站點下通過ajax方式調用這個接口

此時我們可以看到如下的結果

通過分析上述的監視結果可以看到,這個ajax請求是成功的,但是因為響應頭中沒有告訴瀏覽器這個接口可以跨訪問,瀏覽器就拒絕了將請求結果返回給用戶。
通過在Action上進行斷點,也可以看出,服務器已經收到請求並成功執行了

甚至瀏覽器本身也已經接收到了響應結果,因為跨域問題所以拒絕返回給用戶

所以根據上述的錯誤提示,我們很容易就能解決跨域這個問題,就是需要在響應頭中添加
Access-Control-Allow-Origin
這個響應數據。在IIS中我們可以在配置文件中直接配置這個響應頭,讓所有
的請求都能返回這個響應頭,當然也可以使用代碼對需要的接口進行單獨返回相應的響應頭,下面是web.config的配置

通過配置上述的配置,指定
Access-Control-Allow-Origin
響應頭的值返回“*”,則表示任何域名都可以訪問這個webapi
此時再次訪問,可以看到訪問成功,並輸出了返回結果

在實際應用中,我們可能需要手動設置一些請求頭發送給WebApi服務器,如下所示

此時再次訪問webapi可以看到不一樣的情況

從上圖看到,這個請求不僅僅被終止了,而且不是以我們期望的post方式進行請求的,而是使用了options的方式。
了解http協議的同學可能會知道,options方法只是對服務器的一個探測,不會返回相應體。
這里就是瀏覽器對於跨域發送自定義請求頭的一個限制,如果請求跨域並且手動設置了請求頭,那么瀏覽器會發起兩次請求,一次是Options的預檢,詢問服務器是否支持當前這個比較敏感的操作,如果服務器返回了期望的響應頭數據,那么瀏覽器才會正在發起我們的請求。
通過上處分析,web網站要能事先跨站發送請求頭,服務器必須支持options的預檢,所以這里必須提供服務器的實現。
在微軟的WebApi框架中我們可以使用
Microsoft
.
AspNet
.
WebApi
.
Cors
這個組件來提供支持。
使用Nuget進行安裝

安裝完畢后再WebApi上對其進行注冊

注冊完畢,最后我們只需要在我們需要跨域的Action使用特性就可以支持Options預檢,進行跨域請求了

再次請求WebApi,我們可能發現請求並不是很成功,不過在IE瀏覽器下,調試工具給了我們很好的錯誤提醒。

從上圖看到,在Options的預檢的響應頭中返回了兩個
Access-Control-Allow-Origin
響應頭,瀏覽器提示不允許這樣的結果。
仔細回想一下上述的操作可以發現這個響應頭其實是我們自己在webconfig中指派服務器自動發送了,這邊的操作與之前的配置產生了沖突,刪除剛才在Webconfig
中的配置節點即可

刪除上述的節點后,再次請求服務器,可以發現正常返回結果了

在上述請求中,瀏覽器發起了一下Options預檢與真正的Post請求。
有時候需要跨域向WebApi傳遞Cookie等信息,此時我們可能看到這里雖然成功向瀏覽器寫入了Cookie,但是瀏覽器並不會主動發送Cookie到服務器


如果需要接收到Cookie信息,則需要設置SupportsCredentials屬性為true


參考資料: