1. 程式人生 > >JSONP跨域請求原理及示例

JSONP跨域請求原理及示例

Jsonp的跨域問題,再講之前先說明一下什麼是同源策略。

來自百度的介紹
同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支援JavaScript 的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,埠相同。當一個瀏覽器的兩個tab頁中分別開啟來 百度和谷歌的頁面。當瀏覽器的百度tab頁執行一個指令碼的時候會檢查這個指令碼是屬於哪個頁面的,即檢查是否同源,只有和百度同源的指令碼才會被執行。如果非同源,那麼在請求資料時,瀏覽器會在控制檯中報一個異常,提示拒絕訪問。

如下:下表引自網路其他部落格大牛

JSON和JSONP

    Json 和jsonp看起來好像啊,那麼他們之間有什麼聯絡嗎?
    JSON(JavaScript Object Notation)是一種輕量級的資料交換格式,其具體格式及用法,我的這篇文章有介紹

XML與JSON比較,並用AJAX傳輸XML/JSON資料
    JSONP 是JSON with Padding的簡稱,它是一個非官方的協議,它允許在伺服器端整合Script tags返回客戶端,通過javascript callback的形式實現跨域訪問。(這是百度的說法,不懂沒關係,我細細講解)

        html頁面

<div id="bdlog">
    <img src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png">
</div
>

        結果展示:

這裡寫圖片描述
        看到了吧,<img>中的src屬性既可以請求本地圖片,也可以請求網上資源。也就是說html中的src屬性是支援跨域的。同理jsonp跨域請求也是利用src屬性,只不過用的是<script></script>標籤。
來看個jsonp的小例子
        jsonp.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp請求資源</title
>
</head> <body> </body> </html> <script type="text/javascript" src="js/data.js

        data.js

console.log("我被jsonp請求了!");

        開啟控制檯,看一下:
這裡寫圖片描述
        看,jsonp實現了本地資料的請求。如果我想請求伺服器的資料該是怎樣去實現呢?

JSONP的原理解析

jsonp.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp請求伺服器資料</title>
</head>
<body>

</body>
</html>
<script type="text/javascript" src="http://127.0.0.1/2017_06_26/jsonp/02jsonp.php"></script>

        jsonp.php

<?php
    echo "成功請求伺服器!";
?>

        結果如下:

這裡寫圖片描述
        我們會發現頁面請求了 jsonp.php頁面,並且使用的是get方法。也就是說jsonp請求資料預設使用的是get方法。剛才我們再介紹jsonp的時候,說了一下 允許在伺服器端整合Script tags返回客戶端,通過javascript callback的形式實現跨域訪問。
        那麼我們繼續改進html頁面,在請求的url中新增一個?callback=test引數.其中test是寫在html中的js函式
        jsonp.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp請求伺服器資料</title>
</head>
<body>

</body>
</html>
<script>
    function test(data) {
        console.log("測試能否呼叫我這個test()函式");
         console.log(data);

    }
</script>
<script type="text/javascript" src="http://127.0.0.1/2017_06_26/jsonp/jsonp.php?callback=test"></script>

        jsonp.php

<?php

   // 獲取到了 test.()   
返回的是 test({"name":"jsonp","color":"green"});
   echo $_GET['callback'].'({"name":"jsonp","color":"green"})';
 ?>

結果是:
這裡寫圖片描述
        通過script標籤引入一個js檔案,這個js檔案載入成功後會執行我們在url拼接一個callback引數,通過get方式請求伺服器,伺服器返回的資料若是json字串將自動轉化為js物件。所以jsonp是需要伺服器端和客戶端相互配合的。

        看圖也許會明瞭一些:
這裡寫圖片描述
        但是每次寫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jQuery傳送jsonp請求</title>
</head>
<body>
    <input type="button" value="jQuery傳送jsonp請求" id="jq_jsonp">

</body>
</html>
<!--匯入jQuery-->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script>

    $(function () {
        $('#jq_jsonp').click(function () {
            $.ajax({
                url:'jQ_jsonp.php',
                success:function (data) {
                    console.log(data);
                },
                dataType:'jsonp'
           })
        })
    })
</script>

這裡寫圖片描述
        可以發現,我們並沒有寫callback方法,jQuery自動幫我們封裝了一個callback方法。
如果想要設定 自己的 回撥函式 可以通過jsonpCallback 來設定 自己的名字

<script>
    function myJSONPCallback(data) {
        console.log("自己寫的callback函式"+data);
    }


    $(function () {
        $('#jq_jsonp').click(function () {
            $.ajax({
                url:'jQ_jsonp.php',
                success:function (data) {
                    console.log(data);
                },
                dataType:'jsonp',
                jsonpCallback:"myJSONPCallback"
            })
        })
    })
</script>

        jQ_jsonp.php

<?php
   echo $_GET['callback'].'("哈哈哈")';
 ?>

這裡寫圖片描述
這裡寫圖片描述

        總結:JSONP(JSON with Padding)其本質是利用了<script src=""></script>標籤具有可跨域的特性,由服務端返回一個預先定義好的Javascript函式的呼叫,並且將伺服器資料以該函式引數的形式傳遞過來,此方法需要前後端配合完成。**
只能以GET方式請求.**