照理來說本節也應該講Web API原理,目前已經探讨完了比較底層的Web API消息處理管道以及Web Host寄宿管道,接下來應該要觸及控制器、Action方法,以及過濾器、模型綁定等等,想想也是心痛不已,水太深了,摸索原理關鍵是太枯燥和乏味了,但是呢,從情感上還是挺樂意去摸索原理,而情緒上不太樂意去探究原理,于是乎,本文就由此誕生了,借此文緩解下枯燥的心情和壓抑的情緒。後續繼續摸索原理。
接下來我們要講的就是利用JSONP和利用Cors這兩種方式來實作跨域,請看下文。。。。。
Web API并沒有提供JSONP Formatter,但是這并不能影響我們前進的腳步,我們可以自定義Formatter來實作JSONP功能。既然是利用JSONP跨域,那麼就得簡單介紹下JSONP。
浏覽器都是基于同源政策,使其腳本不能跨站點來獲得伺服器端資料,但是辦法總是人想出來的,這個時候就需要JSONP了,當然也可以用别的辦法實作,JSONP是一種能實作讓基于JavaScript的用戶端程式繞過跨站點腳本的限制進而從非目前的伺服器上來獲得資料的方式。預設情況下,應用程式利用Ajax是不允許通路遠端跨域,但是我們可以利用<script>标簽加載JSONP來實作這種跨站點限制。這也不失為一種好的解決方案。JSONP的工作原理是當JSON資料傳回時通過組合JSON資料,并将其包裹到一個函數中進行調用,利用JQuery更能很好的去實作這點。
假如有這樣如下的一個URL:
但我們利用Ajax發出GET請求來擷取伺服器端資料時那将是輕而易舉,但是,但是,但是,重要的前提說三遍,前提是在相同域下,若是不同的域下,利用Ajax來通路資料估計不是這麼輕松了吧。但是,但是,但是,重要的話再說三遍,此時我們就利用JSONP來實作跨域,此時将會變成如下請求模式:
發出如下URL請求通過一個callback回調,這樣得到的結果是和同一站點的結果是一緻的,JQuery會反序列會這些資料并将其推入到函數中。
它主要就是通過調用函數将傳回的JSON資料進行包裹,類似于如下形式:
在JavaScript用戶端送出請求後,當響應資料時,将其資料作為執行要調用函數的參數,并在其内部将JSON資料進行反序列化
下面我們就原理來進行示範,請看如下代碼:
簡單進行調用則如下:
以上是利用原生的JS實作,但是在JQuery中卻對此進行了封裝,如下:
上述callback=?,對于callback中的?而言,JQuery會自動生成我們上述手動建立的全局處理函數,并在調用完函數之後自動銷毀,毫無疑問該回調函數就類似于JS中的代理對象,也就是所謂的臨時代理函數,同時JQuery也會自動去檢測該請求是否是跨域請求,若不是,則以普通Ajax進行請求,否則則以異步加載JS檔案的形式來執行JSONP中的回調函數。
上述講了JSONP原理和實作,那麼結合Web API是如何實作的呢?我們隻能自定義Formatter來手動實作這個功能,既然是有關于JSON,那麼自然是繼承于 JsonMediaypeFormatter 了,代碼如下:
自定義JsonpFormatter并繼承于JsonMediaTypeFormatter:
此時隻需将此自定義類在Web API配置檔案中進行注冊即可:
給出背景測試資料:
接下來就是進行驗證了。調用上述前台所寫的JSONP方法:
上述也可自行利用Ajax來請求,以下幾項必不可少:
點選加載資料:
既然是跨站點就開兩個應用程式就得了呗,伺服器端:localhost:23133,用戶端:localhost:29199,走你,完事:

一切圓滿結束,似乎利用JSONP實作跨域是個不錯的解決方案,但是有的人就問了,JSONP也有局限性啊,隻能針對于Get請求不能用于POST請求啊,并且還需要手動去寫這麼操蛋的代碼,有點令人發指,恩,是的,确實是個問題,你想到的同時我也替你想到了,請看下文!
使用Cors跨域配置是極其的簡單,但是前提是你得通過NuGet下載下傳程式包,搜尋程式包【Microsoft.AspNet.WebApi.Cors】即可,如圖:
下載下傳完成後,有兩種配置跨域的方式
在Web API配置檔案中進行全局配置:
若你僅僅隻是想某個控制器應用跨域也就是說實作局部控制器跨域,當然你也可以通過添加特性來實作這點:
在被請求的伺服器端的Web API配置檔案中,進行全文配置,接下來發出POST請求如下:
如我們所期望的一樣,測試通過:
在控制器上進行局部配置,并發出Get請求,修改如下:
送出請求如下:
我們檢視其請求封包頭資訊以及傳回狀态碼便知是否成功,如下(如預期一樣):
利用JSONP能較好的實作在Web API上的跨域,但是有兩個嚴重的缺陷,第一:隻能是Get請求。第二:你得自定義實作JsonMediaTypeFormatter。在Cors未出世之前你沒有更好的解決方案,你隻能忍受,自從Cors出世,我們不再受請求的限制,不再手動去實作,隻需稍微配置即可達到我們所需,是以利用Cors實作跨域将是不可替代的方案。