亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳細分析jsonp的原理和實現方式

2019-11-19 14:54:02
字體:
來源:轉載
供稿:網友

針對跨域問題,本文主要給大家詳細分析一下jsonp的原理,希望能夠給你提供到幫助。

詳細分析jsonp的原理和實現方式

一:跨域問題。

二,跨域產生的原因

Js是不能跨域請求。出于安全考慮,js設計時不可以跨域。

什么是跨域:

1、域名不同時。

2、域名相同,端口不同。

只有域名相同、端口相同時,才可以訪問。

可以使用jsonp解決跨域問題。

三,跨域失敗的案例 3.1,同源策略

首先基于安全的原因,瀏覽器是存在同源策略這個機制的,同源策略阻止從一個源加載的文檔或腳本獲取或設置另一個源加載的文檔的屬性??雌饋聿恢朗裁匆馑?,實踐一下就知道了。

3.2,隨便建兩個網頁

一個端口是2698,一個2701,按照定義它們是不同源的。

3.3,用jQuery發起不同源的請求

在2698端口的網頁上添加一個按鈕,Click事件隨便發起兩個向端口為2701域的請求。

$("#getOtherDomainThings").click(function () {$.get("http://localhost:2701/Scripts/jquery-1.4.4.min.js", function (data) {console.log(data)})$.get("http://localhost:2701/home/index", function (data) {console.log(data)})})

根據同源策略,很明顯會悲劇了。瀏覽器會阻止,根本不會發起這個請求。(not allowed by Access-Control-Allow-Origin)

OK,原來jsonp是要解決這個問題的。

換句話就是說在一個src中或者一個url中直接去請求了另一個項目的json數據。

例如在端口是8080的項目中的頁面的url中直接去請求了一個http://localhost:8081/category.json這個語句,而這個category.json就在8081的webapp的目錄下,就會產生跨域請求的提示。

四,跨域的解決方法 4.1,啟發

我們有時候在項目中經常能看到這樣的代碼

<script type="text/javascript" src="https://com/seashell/weixin/js/jquery.js"></script>

這樣即使不在同一個項目中,也可以請求成功。就是利用了這個漏洞,或者說是技術吧,來實現的寬裕的請求。

4.2,方法(案例一) 4.2.1,利用script獲取不同源的json

既然它叫jsonp,很明顯目的還是json,而且是跨域獲取。根據上面的分析,很容易想到:利用js構造一個script標簽,把json的url賦給script的scr屬性,把這個script插入到dom里,讓瀏覽器去獲取。實踐:

function CreateScript(src) { $("<script><//script>").attr("src", src).appendTo("body")}

添加一個按鈕事件來測試一下:

$("#getOtherDomainJson").click(function () { $.get('http://localhost:2701/home/somejson', function (data) {  console.log(data) })})

首先,第一個瀏覽器,http://localhost:2701/home/somejson這個Url的確是存在一個json的,而且在 2698網頁上用script標簽來請求這個2701這個Url也是200OK的,但是最下面報js語法錯誤了。原來用script標簽加載完后,會立即 把響應當js去執行,很明顯{"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"}不是合法的js語句。

4.2.2,利用script獲取異域的jsonp

顯然,把上面的json放到一個回調方法里是最簡單的方法。例如,變成這樣:

如果存在jsonpcallback這個方法,那么jsonpcallback({"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"})就是合法的js語句。

在這里需要注意的就是在原來的json格式的數據{"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"}要封裝成jsonpcallback({"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"})這樣一個腳本,這樣才會被回調的時候解析到,否則解析也是失敗的。

由于服務器不知道客戶端的回調是什么,不可能hard code成jsonpcallback,所以就帶一個QueryString讓客戶端告訴服務端,回調方法是什么,當然,QueryString的key要遵從服務端的約定,上面的是”callback“。

添加回調函數:

function jsonpcallback(json) { console.log(json)}

把前面的方法稍微改改參數:

$("#getJsonpByHand").click(function () { CreateScript("http://localhost:2701/home/somejsonp?callback=jsonpcallback")})

200OK,服務器返回jsonpcallback({"Email":"zhww@outlook.com","Remark":"我來自遙遠的 東方"}),我們也寫了jsonpcallback方法,當然會執行。OK順利獲得了json。沒錯,到這里就是jsonp的全部。

4.2.3,利用jQuery獲取jsonp

上面的方式中,又要插入script標簽,又要定義一個回調,略顯麻煩,利用jQuery可以直接得到想要的json數據,同樣是上面的jsonp:

$("#getJsonpByJquery").click(function () {
$.ajax({
url: 'http://localhost:2701/home/somejsonp',
dataType: "jsonp",
jsonp: "callback",
success: function (data) {
console.log(data)
}
})
})

得到的結果跟上面類似。

4.2.4,總結

一句話就是利用script標簽繞過同源策略,獲得一個類似這樣的數據,jsonpcallback是頁面存在的回調方法,參數就是想得到的json。

jsonpcallback({"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"})

4.3,案例二 4.3.1,簡單應用

程序A中sample的部分代碼:

<script type="text/javascript">
//回調函數
function callback(data) {
alert(data.message);
}
</script>
<script type="text/javascript" src="http://localhost:20002/test.js"></script>

程序B中test.js的代碼:
1 //調用callback函數,并以json數據形式作為闡述傳遞,完成回調
2 callback({message:"success"});
這其實就是JSONP的簡單實現模式,或者說是JSONP的原型:創建一個回調函數,然后在遠程服務上調用這個函數并且將JSON 數據形式作為參數傳遞,完成回調。

將JSON數據填充進回調函數,這就是JSONP的JSON+Padding的含義吧。

一般情況下,我們希望這個script標簽能夠動態的調用,而不是像上面因為固定在html里面所以沒等頁面顯示就執行了,很不靈活。我們可以通過javascript動態的創建script標簽,這樣我們就可以靈活調用遠程服務了。

4.3.2,簡單應用的升級以一

程序A中sample的部分代碼:

<script type="text/javascript">function callback(data) {alert(data.message);}//添加<script>標簽的方法function addScriptTag(src){var script = document.createElement('script');script.setAttribute("type","text/javascript");script.src = src;document.body.appendChild(script);}window.onload = function(){addScriptTag("http://localhost:20002/test.js");}</script>

程序B的test.js代碼不變,我們再執行下程序,是不是和原來的一樣呢。如果我們再想調用一個遠程服務的話,只要添加addScriptTag方法,傳入遠程服務的src值就可以了。這里說明下為什么要將addScriptTag方法放入到window.onload的方法里,原因是addScriptTag方法中有句document.body.appendChild(script);,這個script標簽是被添加到body里的,由于我們寫的javascript代碼是在head標簽中,document.body還沒有初始化完畢呢,所以我們要通過window.onload方法先初始化頁面,這樣才不會出錯。

這樣這個http://localhost:20002/test.js路徑就可以動態的變化了。

4.3.3,簡單應用的升級二

上面的例子是最簡單的JSONP的實現模型,不過它還算不上一個真正的JSONP服務。我們來看一下真正的JSONP服務是怎么樣的,比如Google的ajax搜索接口:http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=?&callback=?

q=?這個問號是表示你要搜索的內容,最重要的是第二個callback=?這個是正如其名表示回調函數的名稱,也就是將你自己在客戶端定義的回調函數的函數名傳送給服務端,服務端則會返回以你定義的回調函數名的方法,將獲取的json數據傳入這個方法完成回調。有點羅嗦了,還是看看實現代碼吧:

<script type="text/javascript">//添加<script>標簽的方法function addScriptTag(src){ var script = document.createElement('script');script.setAttribute("type","text/javascript");script.src = src;document.body.appendChild(script);}window.onload = function(){//搜索apple,將自定義的回調函數名result傳入callback參數中addScriptTag("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=apple&callback=result");}//自定義的回調函數resultfunction result(data) {//我們就簡單的獲取apple搜索結果的第一條記錄中url數據alert(data.responseData.results[0].unescapedUrl);}</script>

這個result方法是自己定義的,可能服務器上有千千萬萬個類似于result 的回調函數,但是我現在要的就是result而不是其它的方法,所以在這里自己定義回調方法。而不是寫死的??赡芟乱淮挝揖透某蓃esult1,result2,result3,等了只要自己把回調方法的名稱改一下就行了。

4.4.4,jquery對jsonp的支持

jQuery框架也當然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法(詳細可以參考http://api.jquery.com/jQuery.getJSON/)。那我們就來修改下程序A的代碼,改用jQuery的getJSON方法來實現(下面的例子沒用用到向服務傳參,所以只寫了getJSON(url,[callback])):

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$.getJSON("http://localhost:20002/MyService.ashx?callback=?",function(data){
alert(data.name + " is a a" + data.sex);
});
</script>

結果是一樣的,要注意的是在url的后面必須添加一個callback參數,這樣getJSON方法才會知道是用JSONP方式去訪問服務,callback后面的那個問號是內部自動生成的一個回調函數名。這個函數名大家可以debug一下看看,比如jQuery17207481773362960666_1332575486681。

當然,加入說我們想指定自己的回調函數名,或者說服務上規定了固定回調函數名該怎么辦呢?我們可以使用$.ajax方法來實現(參數較多,詳細可以參考http://api.jquery.com/jQuery.ajax)。先來看看如何實現吧:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$.ajax({
url:"http://localhost:20002/MyService.ashx?callback=?",
dataType:"jsonp",
jsonpCallback:"person",
success:function(data){
alert(data.name + " is a a" + data.sex);
}
});
</script>

沒錯,jsonpCallback就是可以指定我們自己的回調方法名person,遠程服務接受callback參數的值就不再是自動生成的回調名,而是person。dataType是指定按照JSOPN方式訪問遠程服務。

以上就是本次分享關于jsonp的原理的全部內容和代碼,有問題的朋友在下方留言討論吧。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产999精品久久久| 欧美日韩激情视频| 欧美极品少妇xxxxx| 丝袜亚洲另类欧美重口| 日韩电影第一页| 欧美二区在线播放| 尤物九九久久国产精品的特点| 亚洲精品一区二区在线| 亚洲精品国产品国语在线| 欧美成人激情视频免费观看| 欧美重口另类videos人妖| 国产精品草莓在线免费观看| 日韩久久免费电影| 91精品91久久久久久| 午夜精品蜜臀一区二区三区免费| 亚洲图中文字幕| 欧美激情综合色综合啪啪五月| 日本免费一区二区三区视频观看| 国产精品一区电影| 久久久久这里只有精品| 亚洲欧美日本精品| 日韩综合视频在线观看| 欧美国产中文字幕| 国产美女扒开尿口久久久| 久久中文久久字幕| 欧美激情精品久久久久久久变态| 浅井舞香一区二区| 亚洲国产中文字幕久久网| 久久影视电视剧免费网站| 欧美激情综合亚洲一二区| 不用播放器成人网| 亚洲在线视频观看| 激情久久av一区av二区av三区| 亚洲国产精品va在看黑人| 91九色单男在线观看| 国产午夜精品一区二区三区| 欧美精品videos性欧美| 性色av一区二区三区| 日韩人在线观看| 中文字幕亚洲欧美日韩高清| 国产日产欧美a一级在线| 亚洲va久久久噜噜噜久久天堂| 久久久99久久精品女同性| 日韩精品福利网站| 亚洲精品中文字幕女同| 欧美精品videos另类日本| 亚洲免费高清视频| 欧美最猛性xxxxx(亚洲精品)| 日本亚洲欧美三级| 亚洲欧美在线一区| 91在线视频免费| 欧美大全免费观看电视剧大泉洋| 日韩成人激情影院| 91久久精品久久国产性色也91| 精品中文字幕在线观看| 久久久久久久久久婷婷| 亲爱的老师9免费观看全集电视剧| 久久av在线看| 久久久久久久爱| 66m—66摸成人免费视频| 久久久久久亚洲精品中文字幕| 日韩精品亚洲精品| 欧美日韩久久久久| 欧美成人第一页| 欧美一级大胆视频| 欧美国产日韩在线| 69影院欧美专区视频| 欧美精品一二区| 91精品国产色综合| 国内精品久久久久久久| 久久久精品在线| 91免费精品国偷自产在线| 国产精品视频导航| 亚洲国产精品va在线看黑人| 欧美日韩午夜视频在线观看| 欧美激情2020午夜免费观看| 久久人人看视频| 久久久精品电影| 亚洲国产成人久久| 川上优av一区二区线观看| 亚洲男子天堂网| 日韩色av导航| 亚洲人成五月天| 久久99精品久久久久久琪琪| 精品免费在线观看| 国产精品久久久久久久久久免费| 欧美裸身视频免费观看| 国产婷婷97碰碰久久人人蜜臀| 久久久久九九九九| 欧美激情中文字幕乱码免费| 欧美性videos高清精品| 国产精品一区二区性色av| 欧美午夜丰满在线18影院| 午夜剧场成人观在线视频免费观看| 欧美极品少妇xxxxx| 国产精品黄页免费高清在线观看| 亚洲天堂网在线观看| 国产精品亚洲精品| 亚洲第一精品久久忘忧草社区| 久久亚洲精品小早川怜子66| 国产亚洲一区二区精品| 国产成人精品视频| 日韩午夜在线视频| 亚洲欧美在线x视频| 91产国在线观看动作片喷水| 国产第一区电影| 日韩电影中文字幕在线观看| 国产在线视频不卡| 日韩福利伦理影院免费| 国产精品福利小视频| 国产精品女人网站| 久久成人一区二区| 欧美亚洲伦理www| 国产亚洲美女精品久久久| 亚洲午夜色婷婷在线| 亚洲2020天天堂在线观看| 日韩av影片在线观看| 国产中文字幕日韩| 久久全球大尺度高清视频| 欧美激情国产高清| 97免费中文视频在线观看| 日韩有码视频在线| 日本精品久久中文字幕佐佐木| 91豆花精品一区| 亚洲国产精品资源| 911国产网站尤物在线观看| 欧美一区二三区| 欧美成人精品不卡视频在线观看| 色偷偷888欧美精品久久久| 日韩激情视频在线播放| 欧美激情精品久久久久久免费印度| 欧美大胆a视频| 欧美精品一区二区三区国产精品| 91在线精品视频| 55夜色66夜色国产精品视频| 欧美成人一二三| 国产精品福利片| 国产亚洲精品va在线观看| 久久久久久亚洲精品中文字幕| 高清欧美一区二区三区| 91精品视频播放| 日韩中文字幕在线免费观看| 亚洲激情小视频| 国产视频欧美视频| 国产精品爽爽爽爽爽爽在线观看| 亚洲精品有码在线| 91tv亚洲精品香蕉国产一区7ujn| 亚洲精品自拍视频| 国产原创欧美精品| 在线成人一区二区| 狠狠干狠狠久久| 亚洲黄一区二区| 日本成人免费在线| 国内久久久精品| 亚洲一区二区中文| 亚洲全黄一级网站| 亚洲一区第一页| 国产日产欧美a一级在线| 精品免费在线观看| 国产美女精彩久久| 欧美激情区在线播放| 日韩av综合网| 欧美日韩另类字幕中文| 国产精品极品尤物在线观看|