JSONP和AJAX
首先二者是完全不同的東西防嗡,AJAX是通過XMLHttpRequest來發(fā)起請(qǐng)求德澈,而JSONP是利用script標(biāo)簽動(dòng)態(tài)添加src屬性以及附加callback函數(shù)來請(qǐng)求數(shù)據(jù)齐蔽,在jQUery中的$.ajax可以發(fā)送JSONP請(qǐng)求是因?yàn)閖Query對(duì)ajax進(jìn)行了封裝注服,把JSONP封裝進(jìn)了他的ajax函數(shù)里面
// jQuery封裝的JSONP源碼
<script>
function ajax(option){
var defalus = {
jsonp:'callback' //默認(rèn)發(fā)送請(qǐng)求的值是函數(shù)名的值
}
// 覆蓋默認(rèn)參數(shù)
for(var attr in option){
defalus[attr] = option[attr];
}
var p = '';
if(defalus.data){
for(var key in defalus.data){
p += key+ '='+ defalus.data[key] + '&'
}
}
var cbName ;
if(defalus.jsonpCallback){
cbName = defalus.jsonpCallback;
}else{
// 回調(diào)函數(shù)名稱
cbName = 'jQuery' + ('v1.11.1' + Math.random()).replace(/\D/g,'') + '_' + new Date().getTime();
}
window[cbName] = function (data){
defalus.success(data);
}
// 所以jsonpCallback這個(gè)參數(shù)并不是一個(gè)需要自己實(shí)現(xiàn)的函數(shù)舆驶,只是給出一個(gè)名字拓轻,jQuery會(huì)幫我們利用success來實(shí)現(xiàn)這個(gè)函數(shù)并掛載在window下面
var srcipt = document.createElement('script');
srciptt.src = defalus.url + '?' + p + defalus.jsonp + '=' + defalus.jsonpCallback
var head = document.getElementsByTagName('head')[0];
head.appendChild(srciptt);
}
ajax({
url: 'http://lp.com/jsonp/data1.php',
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'hi',
data: {flag:1,abc:'hi'},
success: function(data){
console.log(data)
}
});
</script>
JSONP原理
- script標(biāo)簽的src不受跨域限制
- script標(biāo)簽可以把返回的字符串當(dāng)做代碼來執(zhí)行
JSONP后端代碼的實(shí)現(xiàn)瞬铸,需要約定好callback的key批幌,此處使用的key就是‘callback’
var http = require('http');
var url = require('url');
var querystring = require('querystring');
var server = http.createServer();
server.on('request',function(req, res){
var urlPath = url.parse(req.url).pathname;
var qs = querystring.parse(req.url.split('?')[1]);
if(urlPath === '/jsonp' && qs.callback){
res.writeHead(200,{'Content-Type':'application/json;charset=utf-8'});
var data = {
"name": "Monkey"
};
data = JSON.stringify(data);
var callback = qs.callback+'('+data+');';
// 發(fā)送過來的請(qǐng)求的callback名字為show,則返回的數(shù)據(jù)就是'show(...)'
res.end(callback);
}
else{
res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});
res.end('Hell World\n');
}
});
server.listen('8080');
console.log('Server running!');