日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Web API 实现JSONP或者安装配置Cors跨域

發布時間:2024/9/20 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web API 实现JSONP或者安装配置Cors跨域 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

照理來說本節也應該講Web API原理,目前已經探討完了比較底層的Web API消息處理管道以及Web Host寄宿管道,接下來應該要觸及控制器、Action方法,以及過濾器、模型綁定等等,想想也是心痛不已,水太深了,摸索原理關鍵是太枯燥和乏味了,但是呢,從情感上還是挺樂意去摸索原理,而情緒上不太樂意去探究原理,于是乎,本文就由此誕生了,借此文緩解下枯燥的心情和壓抑的情緒。后續繼續摸索原理。

接下來我們要講的就是利用JSONP和利用Cors這兩種方式來實現跨域,請看下文。。。。。

JSONP實現跨域

Web API并沒有提供JSONP ?Formatter,但是這并不能影響我們前進的腳步,我們可以自定義Formatter來實現JSONP功能。既然是利用JSONP跨域,那么就得簡單介紹下JSONP。

為什么需要JSONP?

瀏覽器都是基于同源策略,使其腳本不能跨站點來獲得服務器端數據,但是辦法總是人想出來的,這個時候就需要JSONP了,當然也可以用別的辦法實現,JSONP是一種能實現讓基于JavaScript的客戶端程序繞過跨站點腳本的限制從而從非當前的服務器上來獲得數據的方式。默認情況下,應用程序利用Ajax是不允許訪問遠程跨域,但是我們可以利用<script>標簽加載JSONP來實現這種跨站點限制。這也不失為一種好的解決方案。JSONP的工作原理是當JSON數據返回時通過組合JSON數據,并將其包裹到一個函數中進行調用,利用JQuery更能很好的去實現這點。

假如有這樣如下的一個URL:

http://www.cnblogs.com/CreateMyself/WebAPI/xpy0928

但我們利用Ajax發出GET請求來獲取服務器端數據時那將是輕而易舉,但是,但是,但是,重要的前提說三遍,前提是在相同域下,若是不同的域下,利用Ajax來訪問數據估計不是這么輕松了吧。但是,但是,但是,重要的話再說三遍,此時我們就利用JSONP來實現跨域,此時將會變成如下請求模式:

http://www.cnblogs.com/CreateMyself/WebAPI/xpy0928?callback=?

發出如下URL請求通過一個callback回調,這樣得到的結果是和同一站點的結果是一致的,JQuery會反序列會這些數據并將其推入到函數中。

JSONP數據是怎樣的?

它主要就是通過調用函數將返回的JSON數據進行包裹,類似于如下形式:

Query7d59824917124eeb85e5872d0a4e7e5d([{"Id":"123","Name":"xoy0928"},{......}])

JSONP的工作原理是怎樣的呢?

在JavaScript客戶端發出請求后,當響應數據時,將其數據作為執行要調用函數的參數,并在其內部將JSON數據進行反序列化

下面我們就原理來進行演示,請看如下代碼:

function JSONP(url, callback) {var id = "_" + "Query" + (new Date()).getTime(); //創建一個幾乎唯一的idwindow[id] = function (result) { //創建一個全局回調處理函數if (callback)callback(result);var getId = document.getElementById(id); //移除Script標簽和idgetId.parentNode.removeChild(getId);window[getId] = null;}url = url.replace("callback=?", "callback=" + id);var script = document.createElement("script"); //創建Script標簽并執行window[id]函數script.setAttribute("id", id);script.setAttribute("src", url);script.setAttribute("type", "text/javascript");document.body.appendChild(script);}

簡單進行調用則如下:

function JSONPFunction() {JSONP("http://localhost:23133/api/default?callback=?",function(jsonData){ //將返回的數據jsonData作為調用函數的參數} };

JSONP在Web API中如何實現呢??

上述講了JSONP原理和實現,那么結合Web API是如何實現的呢?我們只能自定義Formatter來手動實現這個功能,既然是有關于JSON,那么自然是繼承于?JsonMediaypeFormatter?了,代碼如下:

第一步

自定義JsonpFormatter并繼承于JsonMediaTypeFormatter:

public class JsonpFormatter : JsonMediaTypeFormatter{//當請求過來是帶有text/javascript時處理JSONP請求public JsonpFormatter(){SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));JsonpParameterName = "callback";}
//查找函數名 public string JsonpParameterName { get; set; }private string JsonpCallbackFunction;public override bool CanWriteType(Type type){return true;}
//重寫此方法來捕獲請求對象public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType){var formatter = new JsonpFormatter(){JsonpCallbackFunction = GetJsonCallbackFunction(request)};
//運用JSON.NET來序列化自定義 formatter.SerializerSettings.Converters.Add(new StringEnumConverter());formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;return formatter;}//重寫此方法寫入到流并返回public override Task WriteToStreamAsync(Type type, object value,Stream stream,HttpContent content,TransportContext transportContext){if (string.IsNullOrEmpty(JsonpCallbackFunction))return base.WriteToStreamAsync(type, value, stream, content, transportContext);StreamWriter writer = null;try{writer = new StreamWriter(stream);writer.Write(JsonpCallbackFunction + "(");writer.Flush();}catch (Exception ex){try{if (writer != null)writer.Dispose();}catch { }var tcs = new TaskCompletionSource<object>();tcs.SetException(ex);return tcs.Task;}return base.WriteToStreamAsync(type, value, stream, content, transportContext).ContinueWith(innerTask =>{if (innerTask.Status == TaskStatus.RanToCompletion){writer.Write(")");writer.Flush();}}, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(innerTask =>{writer.Dispose();return innerTask;}, TaskContinuationOptions.ExecuteSynchronously).Unwrap();}
//從查詢字符串中獲得JSONP Callback回調函數private string GetJsonCallbackFunction(HttpRequestMessage request){if (request.Method != HttpMethod.Get)return null;var query = HttpUtility.ParseQueryString(request.RequestUri.Query);var queryVal = query[this.JsonpParameterName];if (string.IsNullOrEmpty(queryVal))return null;return queryVal;}}

第二步

此時應將此自定義類進行注冊即可:

GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpFormatter());

第三步

給出后臺測試數據:

public class Person{public string Name { get; set; }public int Age { get; set; }public string Gender { get; set; }}public IEnumerable<Person> GetAllPerson(){Person[] Person = new Person[]{new Person{ Name="xpy0928", Age =11, Gender="男"},new Person{ Name="xpy0929", Age =12, Gender="女"},new Person{ Name="xpy0930", Age =13, Gender="男"},};return Person;}

接下來就是進行驗證了。調用上述前臺所寫的JSONP方法:

function getPerson() {JSONP("http://localhost:23133/api/default?callback=?",function (persons) {$.each(persons, function (index, person) {var html = "<li><ul>";html += "<li>Name: " + person.Name + "</li>";html += "<li>Age:" + person.Age + "</li>";html += "<li>Gender: " + person.Gender + "</li>";html += "</ul>";$("#person").append($(html));});});};$(function () {$("#btn").click(function () {getPerson();});});

上述也可自行利用Ajax來請求,以下幾項必不可少:

$.ajax({type: "Get",url: "http://localhost:23133/api/default/?callback=?",dataType: "json",contentType: "application/json; charset=utf-8",
.......
})

點擊加載數據:

<input type="button" value="獲取數據" id="btn" /> <ul id="person"></ul>

既然是跨站點就開兩個應用程序就得了唄,服務器端:localhost:23133,客戶端:localhost:29199,走你,完事:

總結

一切圓滿結束,似乎利用JSONP實現跨域是個不錯的解決方案,但是有的人就問了,JSONP也有局限性啊,只能針對于Get請求不能用于POST請求啊,并且還需要手動去寫這么操蛋的代碼,有點令人發指,恩,是的,確實是個問題,你想到的同時我也替你想到了,請看下文!

Cors實現跨域

使用Cors跨域配置是極其的簡單,但是前提是你得通過NuGet下載程序包,搜索程序包【Microsoft.AspNet.WebApi.Cors】即可,如圖:

下載完成后,有兩種配置跨域的方式

第一

在Web API配置文件中進行全局配置:

var cors = new EnableCorsAttribute("*", "*", "*");config.EnableCors(cors);

第二

若你僅僅只是想某個控制器應用跨域也就是說實現局部控制器跨域,當然你也可以通過添加特性來實現這點:

[EnableCors(origins: "*", headers: "*", methods: "*")]public class HomeController : Controller{}

嘗試(一)

在被請求的服務器端的Web API配置文件中,進行全文配置,接下來發出POST請求如下:

$("#btn").click(function () {$.ajax({type: "POST",url: "http://localhost:23133/api/Default/PostAllPerson",dataType: "json",contentType: "application/json; charset=utf-8",cache: false,success: function (persons) {$.each(persons, function (index, person) {var html = "<li><ul>";html += "<li>Name: " + person.Name + "</li>";html += "<li>Age:" + person.Age + "</li>";html += "<li>Gender: " + person.Gender + "</li>";html += "</ul>";$("#person").append($(html));});}});});

如我們所期望的一樣,測試通過:

嘗試(二)

在控制器上進行局部配置,并發出Get請求,修改如下:

[EnableCors(origins: "*", headers: "*", methods: "*")]public class DefaultController : ApiController{public IEnumerable<Person> GetAllPerson(){}}

發出請求如下:

$.ajax({type: "Get",url: "http://localhost:23133/api/Default",dataType: "json",........})

我們查看其請求報文頭信息以及返回狀態碼便知是否成功,如下(如預期一樣):

經測試利用Cors實現對于Get和POST請求都是來者不拒,都能很友好的返回響應的數據并且配置簡單。當然Cors的功能遠不止如此簡單,更多詳細信息,請參看【Cors-Origin For WebAPI】?

總結?

利用JSONP能較好的實現在Web API上的跨域,但是有兩個嚴重的缺陷,第一:只能是Get請求。第二:你得自定義實現JsonMediaTypeFormatter。在Cors未出世之前你沒有更好的解決方案,你只能忍受,自從Cors出世,我們不再受請求的限制,不再手動去實現,只需稍微配置即可達到我們所需,所以利用Cors實現跨域將是不可替代的方案。

轉:http://www.cnblogs.com/CreateMyself/p/4836628.html

總結

以上是生活随笔為你收集整理的Web API 实现JSONP或者安装配置Cors跨域的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 另类色综合 | 性爱免费在线视频 | 大奶av| 夜夜骑天天操 | 国产免费一区二区三区最新6 | 在线黄网 | 国产日韩在线免费观看 | 亚洲免费av网站 | 女人色极品影院 | 影音先锋中文字幕一区二区 | 午夜手机福利 | 精品欧美一区二区三区成人 | 欧美乱大交xxxxx | 亚洲人成7777 | 日韩欧美三级在线 | 51国产偷自视频区视频 | 亚洲精品一二三 | 黄色国产在线视频 | 蜜桃做爰免费网站 | 国产精品人成在线观看免费 | 中国av一级片 | 欧美爱爱爱 | 亚色视频 | 亚洲免费av网 | 国产又黄又粗的视频 | 国产精品乱码久久久久 | 在线看h网站| 琪琪久久| 青青草视频免费观看 | 亚洲最新av | 日韩精品一区二区三区国语自制 | 国产欧美精品一区二区色综合 | 亚洲久久久久久 | 亚洲一区二区播放 | 扒开美女内裤狂揉下部 | 色综合色婷婷 | 精品成人av一区二区在线播放 | 自拍偷拍免费 | 欧美亚洲国产视频 | 蜜桃网站 | 天天摸天天操天天射 | 精品少妇一区二区三区在线观看 | 亚洲免费黄色片 | 日韩 欧美 综合 | www视频在线观看免费 | 草av| 最近中文字幕在线观看 | 五月深爱婷婷 | 亚洲精品久久久久久久久 | www.在线国产| 欧美性69| 欧美一区二区三区在线 | 久久免费看少妇 | 久久五十路 | 找国产毛片看 | 亚洲中文无码av在线 | 性高潮久久久久久久久 | 男人的天堂在线视频 | 男人天堂亚洲 | 国产又粗又猛又黄又爽的视频 | 久久精品美乳 | 午夜精品福利在线 | 精品91自产拍在线观看二区 | av日韩中文字幕 | 亚洲色图综合在线 | 夜夜夜夜爽 | 久久在线精品 | 国产精品视频久久久久久久 | 日韩熟妇一区二区三区 | 又色又爽又黄gif动态图 | 国产白浆一区二区 | 亚洲国产精品自拍视频 | 欧美v在线 | 国产精品999 | 色姑娘综合网 | 国产在线h| 亚洲av鲁丝一区二区三区 | 金鱼妻日剧免费观看完整版全集 | 粉嫩av在线播放 | 日韩性xxx| 伊人狠狠操 | 加勒比日韩| 国产精品偷伦视频免费观看了 | 91偷拍网站 | 国产youjizz | 91精品一区二区三区在线观看 | 搡老熟女老女人一区二区 | 中文字幕2021| 国产精久久一区二区三区 | 台湾chinesehdxxxx少妇 | av一区二区三区 | 黄色三级免费观看 | 欧美人xxx| 亚洲人精品 | 欧美一区不卡 | 日本视频不卡 | 他揉捏她两乳不停呻吟动态图 | 欧美三级午夜理伦 | 红桃视频一区二区三区免费 |