天天看點

模仿jQuery封裝JSONP

模仿jQuery封裝JSONP

之前已經了解過JSONP的本質,就直接貼上代碼,就不一步一步分析了。

目的在于,了解jQuery中的jsonp實作跨域的底層代碼;

JSONP封裝的關鍵點在于向window中添加一個cbName的變量。

封裝的代碼如下:

function ajax(obj){
    // jsonp僅僅支援get請求
    var defaults = {
        url : '#',
        dataType : 'jsonp',
        jsonp : 'callback',
        data : {},
        success:function(data){console.log(data);}
    }

    for(var key in obj){
        defaults[key] = obj[key];
    }
    // 這裡是預設的回調函數名稱
    // expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),jQuery底層有對version進行處理
    var cbName = 'jQuery' + ('1.12.2' + Math.random()).replace(/\D/g,"") + '_' + (new Date().getTime());
    if(defaults.jsonpCallback){
        cbName = defaults.jsonpCallback;
    }

    // 這裡就是回調函數,調用方式:伺服器響應内容來調用
    // 向window對象中添加了一個方法,方法名稱是變量cbName的值
    window[cbName] = function(data){
        defaults.success(data);//這裡success的data是實參
    }

    var param = '';
    for(var attr in defaults.data){
        param += attr + '=' + defaults.data[attr] + '&';
    }
    if(param){
        param = param.substring(0,param.length-1);
        param = '&' + param;
    }
    var script = document.createElement('script');
    script.src = defaults.url + '?' + defaults.jsonp + '=' + cbName + param;
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);

    // abc({"username":"zhangsan","password":"123"})
}
           

特别需要注意的是:

上面的代碼中,

defaults.success(data);

success的data為實參,形參為執行個體的js中的data,可回顧JSONP的本質

舉個執行個體,進行驗證封裝的代碼的合理性:

html檔案部分:

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" src="./jsonp.js"></script>
    <script type="text/javascript">
        ajax({
            url:"http://xxx.com/jsonp.php",
            dataType:'jsonp',
            data:{username:'zhangsan',password:'123'},
            jsonp:'cb',
            jsonpCallback:'abc',
            success:function(data){//這裡的data是形參
                console.log(data.username,data.password);
            }
        });
    </script>
</head>
<body>
    
</body>
</html>
           

注意,跨域的位址為虛拟的伺服器,自己配置多個伺服器進行測試

jsonp.php代碼部分:

<?php 
  $cb = $_GET['cb'];
  $arr = array("username"=>"zs","password"=>"123");
  echo $cb.'('.json_encode().')';
 ?>
           

$_GET[‘cb’]中的名字,前端須保持和後端一緻,以後端為準;

繼續閱讀