模仿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’]中的名字,前端須保持和後端一緻,以後端為準;