• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    詳細分析jsonp的原理和實現(xiàn)方式

    來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 22:25:14
    文檔

    詳細分析jsonp的原理和實現(xiàn)方式

    詳細分析jsonp的原理和實現(xiàn)方式:針對跨域問題,本文主要給大家詳細分析一下jsonp的原理,希望能夠給你提供到幫助。 詳細分析jsonp的原理和實現(xiàn)方式 一:跨域問題。 二,跨域產(chǎn)生的原因 Js是不能跨域請求。出于安全考慮,js設計時不可以跨域。 什么是跨域: 1、域名不同時。 2、域名相同,
    推薦度:
    導讀詳細分析jsonp的原理和實現(xiàn)方式:針對跨域問題,本文主要給大家詳細分析一下jsonp的原理,希望能夠給你提供到幫助。 詳細分析jsonp的原理和實現(xiàn)方式 一:跨域問題。 二,跨域產(chǎn)生的原因 Js是不能跨域請求。出于安全考慮,js設計時不可以跨域。 什么是跨域: 1、域名不同時。 2、域名相同,

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

    詳細分析jsonp的原理和實現(xiàn)方式

    一:跨域問題。

    二,跨域產(chǎn)生的原因

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

    什么是跨域:

    1、域名不同時。

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

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

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

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

    首先基于安全的原因,瀏覽器是存在同源策略這個機制的,同源策略阻止從一個源加載的文檔或腳本獲取或設置另一個源加載的文檔的屬性。看起來不知道什么意思,實踐一下就知道了。

    3.2,隨便建兩個網(wǎng)頁

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

    3.3,用jQuery發(fā)起不同源的請求

    在2698端口的網(wǎng)頁上添加一個按鈕,Click事件隨便發(fā)起兩個向端口為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)
    })
    })

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

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

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

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

    四,跨域的解決方法 4.1,啟發(fā)

    我們有時候在項目中經(jīng)常能看到這樣的代碼

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

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

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

    既然它叫jsonp,很明顯目的還是json,而且是跨域獲取。根據(jù)上面的分析,很容易想到:利用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網(wǎng)頁上用script標簽來請求這個2701這個Url也是200OK的,但是最下面報js語法錯誤了。原來用script標簽加載完后,會立即 把響應當js去執(zhí)行,很明顯{"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"}不是合法的js語句。

    4.2.2,利用script獲取異域的jsonp

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

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

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

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

    添加回調(diào)函數(shù):

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

    把前面的方法稍微改改參數(shù):

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

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

    4.2.3,利用jQuery獲取jsonp

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

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

    得到的結(jié)果跟上面類似。

    4.2.4,總結(jié)

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

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

    4.3,案例二 4.3.1,簡單應用

    程序A中sample的部分代碼:

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

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

    將JSON數(shù)據(jù)填充進回調(diào)函數(shù),這就是JSONP的JSON+Padding的含義吧。

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

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

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

    4.3.3,簡單應用的升級二

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

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

    <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,將自定義的回調(diào)函數(shù)名result傳入callback參數(shù)中addScriptTag("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=apple&callback=result");}//自定義的回調(diào)函數(shù)resultfunction result(data) {//我們就簡單的獲取apple搜索結(jié)果的第一條記錄中url數(shù)據(jù)alert(data.responseData.results[0].unescapedUrl);}</script>

    這個result方法是自己定義的,可能服務器上有千千萬萬個類似于result 的回調(diào)函數(shù),但是我現(xiàn)在要的就是result而不是其它的方法,所以在這里自己定義回調(diào)方法。而不是寫死的。可能下一次我就改成result1,result2,result3,等了只要自己把回調(diào)方法的名稱改一下就行了。

    4.4.4,jquery對jsonp的支持

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

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

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

    <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就是可以指定我們自己的回調(diào)方法名person,遠程服務接受callback參數(shù)的值就不再是自動生成的回調(diào)名,而是person。dataType是指定按照JSOPN方式訪問遠程服務。

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    詳細分析jsonp的原理和實現(xiàn)方式

    詳細分析jsonp的原理和實現(xiàn)方式:針對跨域問題,本文主要給大家詳細分析一下jsonp的原理,希望能夠給你提供到幫助。 詳細分析jsonp的原理和實現(xiàn)方式 一:跨域問題。 二,跨域產(chǎn)生的原因 Js是不能跨域請求。出于安全考慮,js設計時不可以跨域。 什么是跨域: 1、域名不同時。 2、域名相同,
    推薦度:
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 久久久久国产精品麻豆AR影院| 99精品国产在热久久无毒不卡| 久久99热只有频精品8| 国产精品青草视频免费播放| 99热成人精品热久久669| 亚洲AV永久无码精品水牛影视 | 亚洲国产精品lv| 久久久精品2019免费观看| 欧美 日韩 精品 另类视频| 国产A∨免费精品视频| 欧美精品国产日韩综合在线| 99在线精品免费视频九九视| 久久亚洲日韩精品一区二区三区 | 久久99国产精品成人欧美| 最新国产精品亚洲| 亚洲国产精品一区二区久久| 久久亚洲精品视频| 国产精品福利一区二区| 国产成人精品2021| 国产美女精品一区二区三区| 乱码精品一区二区三区| 日韩精品专区AV无码| 亚洲Av无码精品色午夜| 无码精品国产一区二区三区免费| 亚洲第一区精品观看| 亚洲高清国产拍精品青青草原 | 免费观看四虎精品成人| 精品无码久久久久久久动漫| 亚洲国产第一站精品蜜芽| 午夜精品美女写真福利| 午夜精品视频在线| 国产91精品一区二区麻豆亚洲| 99精品国产一区二区| 国产精品v欧美精品v日韩| 国产精品国产三级在线高清观看| 亚洲国产精品久久久久婷婷老年 | 亚洲精品无码久久毛片| 亚洲无码精品浪潮| 夜夜爽一区二区三区精品| 亚洲av永久无码精品秋霞电影影院| 亚洲精品线路一在线观看|