JSONP詳解


1.什么是ajax跨域請求
當通過ajax異步請求其他域名的服務時,存在跨域無權限訪問的問題。
此時,可以通過JSONP來實現跨域請求。

2.JSONP原理
ajax異步請求無權限訪問。但我們發現,web頁面調用js文件時不存在跨域問題(如在我們的頁面中引入百度地圖API, <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=e3ZohdqyB0RL98hFOiC29xqh"></script>),總結發現,凡是擁有“src”屬性的標簽都擁有跨域的能力,如<script>,<img>,<iframe>等。
這種非正式的傳輸協議,就是JSONP。JSONP的一個要點是允許客戶端傳一個callback參數給服務器,然后服務器返回數據時會用這個callback參數作為函數名,包裹住JSON數據,返回客戶端,客戶端執行返回函數。

3.JSONP客戶端具體實現
1)直接執行返回函數
本地服務器local.com下有個jsonp.html頁面代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://remote.com/remote.js"></script>
</head>
<body>
</body>
</html>

遠程服務器remote.com下有個remote.js文件代碼如下:

alert('我是遠程文件');

運行jsonp.html,會彈出“我是遠程文件”,顯示跨域調用成功。

2)客戶端執行回調函數
jsonp.html頁面代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函數,可以被跨域的remote.js文件調用,遠程js帶來的數據是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>

remote.js文件代碼如下:

localHandler({"result":"我是遠程js帶來的數據"});

運行jsonp.html,會彈出“我是遠程js帶來的數據”,顯示跨域調用成功。

3)客戶端傳遞回調函數
jsonp.html頁面代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查詢結果后的回調函數
    var flightHandler = function(data){
        alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 張。');
    };
    // 提供jsonp服務的url地址(不管是什么類型的地址,最終生成的返回值都是一段javascript代碼)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 創建script標簽,設置其屬性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script標簽加入head,此時調用開始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

flightResult.aspx的頁面生成了一段這樣的代碼提供給jsonp.html

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

運行jsonp.html,成功彈出提示窗口。

4)JSONP封裝了3)中的代碼,以方便客戶端使用。
jsonp.html頁面代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" >
 <head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"></script>
      <script type="text/javascript">
     jQuery(document).ready(function(){ 
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//傳遞給請求處理程序或頁面的,用以獲得jsonp回調函數名的參數名(一般默認為:callback)
             jsonpCallback:"flightHandler",//自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名,也可以寫"?",jQuery會自動為你處理數據
             success: function(json){
                 alert('您查詢到航班信息:票價: ' + json.price + ' 元,余票: ' + json.tickets + ' 張。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
     </script>
     </head>
  <body>
  </body>
 </html>

示例中沒有定義flightHandler函數,但代碼成功運行了。
這是因為jquery自動把success屬性方法作為了回調函數。

4.JSONP總結
由上面的講解可知,ajax和jsonp兩種技術看起來很像,但實質上是完全不同。

5.JSON格式數據優點補充
1)基於純文本,跨平台傳遞簡單
2)javascript原生支持,后台語言幾乎全部支持
3)可讀性強
4)容易編寫和解析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM