json和jsonp



为了理解json和jsonp,先提一下ajax;提到ajax就会不可避免的面临两个问题:

   (1)ajax以何种格式来交换数据?

   (2)跨域的需求如何解决?

   ajax不允许跨域,可以用jsonp来解决

    目前有很多方法来解决解决这个问题,但现在比较推崇的方法是,用json来交换数据,并靠jsonp来跨域。

    json:是一种数据交换格式;

优点:1)基于纯文本,跨平台传递极其简单;

   2)JavaScript原声支持,后台语言几乎全部支持;

   3)轻量级数据格式,占用字符数量极少,特别适合互联网传递;

   4)可读性较强,虽然比不上xml那么一目了然,但在合理的依次缩进之后还是很容易识别的;

   5)容易编写和解析,当然前提是你要知道数据结构;

规则:1)json只有两种数据类型描述符,大括号{}和方括号[],其余英文冒火:是映射符,英文逗号','是分隔    符,引文双引号是定义符;

   2)大括号用来描述一组‘不同类型的无序键值对集合’(每个键值对可以理解为oop的属性描述),方   括号[]用来描述一组“相同类型的有序数据集合”(可对应oop的数组);

   3)上述两种集合中若有多个子项,则通过英文逗号,进行分隔;

   4)键值对以英文冒号:进行分隔,并且建议键名都加上英文双引号“”,以便于不同语言解析;

           5)json内部常用的数据类型无非就是字符串,数字,布尔,日期,null这么几个,字符串必须用双    引号引起来,其余的不用,日期类型比较特殊。建议,如果客户端没有按日期排序功能需求的话,    那么把日期时间直接作为字符传递就好,可以省去很多麻烦。

Json代码实例:              

//描述一个人
var person = {
    "Name":"ShenLu",
    "Age":25,
    "Company":"ali",
    "Engineer":true
}
//获取人的信息
var personAge = person.Age;
//描述几个人
var members = [
{
       "Name":"ShenLu",
       "Age":24,
       "Company":"Ali",
       "Engineer":true
},
{
        "Name":"John",
        "Age":24,
        "Company":"Oracle",
        "Engineer":false
}
]
//读取其中John的公司名称
var johnsCompany=members[1].Company;


   

//描述一场会议
var conference = {
"Conference":"Future Marketing",
"Date":"2017-06-18",
"Address":"ShangHai",
"Members":[
{
       "Name":"ShenLu",
       "Age":24,
       "Company":"Ali",
       "Engineer":true
},{
 "Name":"John",
        "Age":24,
        "Company":"Oracle",
        "Engineer":false
}]}


读取参会者Shenlu是否是工程师  
var ShenluEngineer=conference.Members[0].Engineer;


 jsonp:一种非官方跨域数据交互协议;

帮助理解:

1)ajax直接请求普通文件存在跨域无权限访问的问题,无论是你是静态页面,动态网页,只要是跨域要求,一律都不可以;

2)但是web页面上调用js文件时则不受跨域的影响(不仅如此,只要有src这个属性的标签都有跨域的能力,如<script><img><iframe>)

3)目前,如果想通过纯web端跨域访问数据只有一种可能,就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;

4)恰巧有json纯字符数据格式可以整洁的描述负责数据,更妙的是json还被js原声支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;

5)这样,web客户端可以通过调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以接送为后缀),所以服务器之所以要动态生成json文件,目的记载于把客户端需要的数据装进去。

6)客户端对json文件调用成功之后,也就获得了自己需要的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常想ajax,但其实并不一样。

7)为了方便客户端使用数据,逐渐形成了一种非正式传输协议,人们称为jsonp,给协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住json数据,这样客户端可以随意定制自己的函数来自动处理返回数据了。


jsonp是目前主流的实现跨域通信的解决方法;

在jQuery中可以通过$.ajax的对dataType设为jsonp来调用jsonp,但注意jsonp和ajax的实现原理一点关系都没有。。

jquery用ajax实现jsonp跨域的函数方法:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" >
 <head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"></script>
      <script type="text/javascript">
     jQuery(document).ready(function(){
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
             success: function(json){
                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
     </script>
     </head>
  <body>
  </body>
 </html>

jsonp主要是通过script链接远程url来实现跨域请求的。

<script src="http://jsonp.js?callback-XXX"></script>

借用一个他人写的函数

var JSONP = {
// 获取当前时间戳
now: function() {
return (new Date()).getTime();
},
// 获取16位随机数
rand: function() {
return Math.random().toString().substr(2);
},
// 删除节点元素
removeElem: function(elem) {
var parent = elem.parentNode;
if(parent && parent.nodeType !== 11) {
parent.removeChild(elem);
}
},
// url组装
parseData: function(data) {
var ret = "";
if(typeof data === "string") {
ret = data;
}
else if(typeof data === "object") {
for(var key in data) {
ret += "&" + key + "=" + encodeURIComponent(data[key]);
}
}
// 加个时间戳,防止缓存
ret += "&_time=" + this.now();
ret = ret.substr(1);
return ret;
},
getJSON: function(url, data, func) {
// 函数名称
var name;
// 拼装url
url = url + (url.indexOf("?") === -1 ? "?" : "&") + this.parseData(data);
// 检测callback的函数名是否已经定义
var match = /callback=(\w+)/.exec(url);
if(match && match[1]) {
name = match[1];
} else {
// 如果未定义函数名的话随机成一个函数名
// 随机生成的函数名通过时间戳拼16位随机数的方式,重名的概率基本为0
// 如:jsonp_1355750852040_8260732076596469
name = "jsonp_" + this.now() + '_' + this.rand();
// 把callback中的?替换成函数名
url = url.replace("callback=?", "callback="+name);
// 处理?被encode的情况
url = url.replace("callback=%3F", "callback="+name);
}
// 创建一个script元素
var script = document.createElement("script");
script.type = "text/javascript";
// 设置要远程的url
script.src = url;
// 设置id,为了后面可以删除这个元素
script.id = "id_" + name;
// 把传进来的函数重新组装,并把它设置为全局函数,远程就是调用这个函数
window[name] = function(json) {
// 执行这个函数后,要销毁这个函数
window[name] = undefined;
// 获取这个script的元素
var elem = document.getElementById("id_" + name);
// 删除head里面插入的script,这三步都是为了不影响污染整个DOM啊
JSONP.removeElem(elem);
// 执行传入的的函数
func(json);
};
// 在head里面插入script元素
var head = document.getElementsByTagName("head");
if(head && head[0]) {
head[0].appendChild(script);
}
}
};



调用发放和jQuery类似:

var data = {
from: "北京" ,
count: 27,
output: "json" ,
callback: "?"
}
JSONP.getJSON( "http://api.qunar.com/cdnWebservices.jcp" , data, function (json) {console.log(json)});
json是目的,而jsonp是手段。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值