如何跨域获取json数据源?我们都知道要有callback,具体callback是如何工作的呢?如果服务器端不接收callback,我们是不是就没有办法处理了呢?读完本文后相信你会有一个大体的了解。
我们先来看一个例子:http://www.darlingbank.com/cutpage/index.php/promote/edit/getfun/json/
如果查看源码,你会发现,根本看不到页面里面的图片和文字。这是你会想应该是ajax异步获取的数据,但是打开FF,查看
你会发现也没有请求,这是怎么回事呢?
再细心的攻城狮们会发现,页面底部多了三个js:
这是在查看源码时没发现的。但是,在页面源码里面,你能看到
<ul class="cf" dataurl="http://www.paipai.com/sinclude/xml/tjw/tjw2014/tjw4/tjw179255804475.js" commlen="4" commsta="1" commtpl=‘<li><a href="{#recmdReason#}" target="_blank">{#recmdRegName#}</a></li>‘>
类似这样的html标签。随便打开其中的一个js文件,你能发现,它其实就是一个规则的、静态的json格式的文件,也不能接收callback,这是如何做到的呢?
【注】如果是能接收calllback的,一般是动态语言,如php,$_get[‘callback‘]之类,然后生成的json对象名就为callback之后的参数值。
相信我们理解了jsonp的原理,就很容易做到了:
简单理解jsonp:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。
Jsonp整个执行过程是这样的:
首先在客户端注册一个callback (如:‘callback‘), 然后把callback的名字(如:tjw179464084474)传给服务器。注意:服务端得到callback的数值后,要用tjw179464084474({......})把将要输出的json内容包括起来,此时,服务器生成 json 数据才能被客户端正确接收。然后以 javascript 语法的方式,生成一个function, function 名字就是传递上来的参数 ‘callback‘的值tjw179464084474。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数, 传入到了客户端预先定义好的 callback 函数,如该例子的function tjw179464084474(){}。
再回到我们的例子:毋庸置疑,那三个请求的js是通过下面的代码解析出来的:
var J_data = {
debug : true,
log : function(s){
this.debug && (window.console ? console.log(s) : alert(s));
},
create_script : function(src){
var Scrip=document.createElement(‘script‘);
Scrip.charset="gbk";
Scrip.src=src;
document.body.appendChild(Scrip);
},
get : function(){
var thats=this;
$("[dataurl]").each(function () {
var that=this;
dataurl=$(this).attr("dataurl"),
tpl_tmp=$(this).attr("commtpl");
if(typeof tpl_tmp===‘undefined‘ || tpl_tmp===‘‘){
thats.log(‘请填写模板‘);
}else{
var c_str=dataurl.slice(dataurl.lastIndexOf(‘/‘)+1).split(‘.‘)[0];
window[c_str]=function(j){
var d=j.data.adList,html=‘‘,
len=parseInt($(that).attr("commlen")) || d.length,
start=parseInt($(that).attr("commsta")) || 0,
tpl=$(that).attr("commtpl");
if(start>0 && len<d.length){
len +=start;
}
for(var i=start;i<len;i++){
html += tpl.replace(/{#recmdReason#}/g,d[i].recmdReason).replace(/{#recmdRegName#}/g,d[i].recmdRegName).replace(/{#image#}/g,d[i].image).replace(/{#adSentence#}/g,d[i].adSentence);
}
$(that).html(html);
}
// $.getScript(dataurl+"?callback="+c_str); //亦可以用jquery方法
thats.create_script(dataurl+"?callback="+c_str);
}
});
}
}
$(function(){
J_data.get();
})
我们看得出来,这里服务器端js文件是没办法接收callback参数的,但是我们发现另外一个特点:每个json对象名都是跟js文件名有关的。如果理解了上述jsonp原理,我们知道之所以要有callback,是为了返回生成对象的对象名是什么,以至于知道返回到客户端的方法名,这是就可以注册全局的方法,所以我们能看到这段代码:
window[c_str]=function(j){
就已经获取到callback的方法名了。接下来的事就顺理成章了,只是解析json对象里面的值,拼成html插入dom,大功告成!