导航

跨域获取json一些理解[腾讯电商数据的拉取方式]

Posted on 2014-04-25 10:48  jaycie  阅读(2135)  评论(1编辑  收藏  举报

如何跨域获取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,大功告成!

深圳本土web前端技术交流群:125776555

欢迎探讨前端最新技术、跳槽经验

深圳web前端