jsonp的簡單封裝


一、demo情景

  1、通過gulp在本地開啟兩個服務器;

  2、服務器協議相同、端口或者域名不同(通過gulp-connect設置)

  3、后台用js文件模擬后台返回數據。(僅僅只是簡單的執行前台傳入的函數)

二、為封裝代碼寫法

  1、服務器一中的 test1.js 文件

//4、jsonp跨域
//先定義一個callback函數,函數名要與后台一致
    function jsonp(res){
        console.log(res)
    }
//js構建一個script標簽。並將src設置為請求地址url,且通過地址欄傳參格式將定義好的函數名作為參數傳入后台
    var script = document.createElement("script");
        script.src = "http://localhost:8080/js/index.js?callback=jsonp";
    document.getElementsByTagName('head')[0].appendChild(script);

  2、服務器二中的 test1.js 文件

//后台js直接執行回調函數,並將數據當作參數(只是模擬后台返回)
//實際后台真正返回情況,並不是執行函數,而是將其拼接,用括號包裹參數類似於:callback+"("+$data+")"
  callback("我是后台數據")

三、jsonp封裝

  1、服務器一中的 test1.js 文件

    //5、jsonp封裝
    function jsonpPakeage(obj) {
        //寫入url地址中的函數名稱,動態創建
        var callbackName = "fn"+Math.random().toString().split("\.")[1];
        
        //創建一個script標簽
        var scriptObj = document.createElement("script");
        
        obj.parames = obj.parames || '';
        if (typeof obj.parames == 'object') {
            var arr = new Array();
            for (var key in obj.parames) {
                arr.push(key + '=' + obj.parames[key])
            }
            obj.parames = arr.join('&');
        }
        //設置標簽的請求路徑
        //像這樣:http://localhost:3000/api?callback=fn153498520409635392&id=1
        scriptObj.src = obj.url + '?' + 'callback=' + callbackName + '&' + obj.parames;
        //將創建好的帶請求的script標簽添加到html的body中
        document.getElementsByTagName('head')[0].appendChild(scriptObj);

        //這里必須這樣寫window[callbackName];
        //如果寫window.callbackName會報錯沒有定義
        //var one = true;
        window[callbackName] = function (res) {
            //if(one){
                obj.success(res);
                //刪除的時候可以這樣寫
                //由於請求一次會創建一個script標簽和一個函數,所以每次獲取到結果后就刪除
                delete window.callbackName;
                document.getElementsByTagName('head')[0].removeChild(scriptObj);
                // one = false
            //}
        }
    }
    //調用
    jsonpPakeage({
        url:"http://localhost:8080/js/index.js",
        parames:"",
        success:function(res){
            console.log(res)
        }
    })

  2、服務器二中的 test1.js 文件,但這里由於是用js模擬的后台,所以拿不到服務器一傳過來的動態創建的callback函數名。所以測試的時候,我是將服務器一里面的callback函數名寫死。(后台在測試環境下拿不到動態函數名,所以內容不變)

//后台js直接執行回調函數,並將數據當作參數(只是模擬后台返回)
//實際后台真正返回情況,並不是執行函數,而是將其拼接,用括號包裹參數類似於:callback+"("+$data+")"
callback("我是后台數據")

 

四、參考

  1、https://www.jianshu.com/p/0bad94e15d34

五、測試問題

  1、測試的時候window[callback]會執行兩次,測試了幾次,問題有可能出在后台使用js模擬的,導致后台會執行一次callback函數。

  2、如果后台不用js模擬還出現二次執行問題,可通過設置一個變量one並判斷從而禁止二次執行。(見測試代碼)

六、jsonp優劣

  優點:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都 可以運行,不需要XMLHttpRequest或ActiveX的支持;並且在請求完畢后可以通過調用callback的方式回傳結果。

  缺點:它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題。

 


免責聲明!

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



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