1. 程式人生 > >瞭解jsonp跨域並實現自己的jsonp

瞭解jsonp跨域並實現自己的jsonp

為什麼會有jsonp

javascript有一個安全限制—-同源策略, 即js只能訪問與包含它的文件在同一個域的內容 . 那麼這對於ajax影響是 , 通過XMLHttpRequest實現ajax請求不能向不同域提交請求 . 但是隨著程式設計深入 , 會不可避免使用跨域進行請求資源 .

可以實現跨域請求資源的方式 :

  1. 使用img標籤, 因為img標籤在頁面渲染階段會向src中的url請求資源 . 以前的系統在統計網站訪問量時候會在網頁某個地方放一個小圖片 , 通過每次圖片渲染向伺服器傳送請求 , 從而能判斷網站是否被訪問 .
    這裡寫圖片描述
  2. iframe請求服務端, 並接受返回資料 . 可以通過隱藏iframe標籤 , 接收返回資料並進行處理 , 但是這種方式處理比較複雜 .
    這裡寫圖片描述
  3. 使用link標籤, rel是stylesheet , 也就是類似於請求css檔案的方式 , 但是這種方式會使頁面在渲染過程出現css錯誤 .
    這裡寫圖片描述

  4. 使用script方式, 類似於請求js檔案 .
    這裡寫圖片描述

分析script這種方式

  • 如果我們本地定義一個全域性函式如下:
    這裡寫圖片描述
  • 那麼當script請求到資料之後,我們本地的func函式就會執行,而data也就是script返回資料func的引數
  • 如何讓其他系統返回 func(name:zhangsan,age:22) 這種資料 ,注意到我們的url有一個引數 : callback , 其他系統會根據這個引數對應的值,拼出對應的資料 , 並返回給我們.當然豆瓣API只識別callback引數, 其他系統可能有其他形式引數 .

手寫自己的jsonp

  1. html程式碼 :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="result"></div>
</body>
<script type="text/javascript" src="jsonp.js"></script>
<script type="text/javascript"> $jsonp("https://api.douban.com/v2/movie/in_theaters",{count:10},function (data) { document.getElementById("result").innerHTML = JSON.stringify(data); }); </script> </html>

2.js程式碼(jsonp.js)

/**
 1. Created by 張延 on 2017/1/18.
 */
(function (window, document, undefined) {
    /**
     *
     * @param url 請求的資料
     * @param data 需要傳遞的資料
     * @param callback 回撥執行的函式
     */
    var jsonp = function(url, data, callback) {
        // 1.自定義一個函式名
        var callBackFuncName = "jsonp_callback_"+Math.random().toString().replace(".","");
        // 2.將這個函式防止到window全域性上
        window[callBackFuncName] = callback;
        // 3.定義一個queryString字串,將data變為字串
        var queryString = url.indexOf("?") == -1 ? "?" : "&";
        for(var key in data) {
            queryString += key + "=" + data[key] + "&" ;
        }
        // callback : 取決呼叫API規範的引數名
        queryString += "callback=" + callBackFuncName;
        // 4.建立script節點, 並將url+queryStirng設定為src
        var scriptElement = document.createElement("script");
        scriptElement.src = url + queryString;
        // 將這個script節點拼接到body中
        document.body.appendChild(scriptElement);
    }
    window.$jsonp = jsonp;
})(window, document);
 3. 頁面效果(將請求到json資料渲染到頁面)

這裡寫圖片描述