本文转自:http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

 

前言:

 

说到AJAX就会不可防止的面临七个难点,第三个是AJAX以何种格式来交流数据?第二个是跨域的急需如何化解?那多少个难题最近都有例外的缓解方案,比如数据足以用自定义字符串或者用XML来叙述,跨域能够透过服务器端代理来化解。

但到近来停止最被正视恐怕说首要选取的方案依旧用JSON来传数据,靠JSONP来跨域。而那就是本文将要讲述的情节。

 

JSON和JSONP纵然只有贰个假名的差距,但其实他们一直不是二遍事儿:JSON是一种数据沟通格式,而JSONP是一种依靠开发人士的才智成立出的一种违规跨域数据交互协议。大家拿近年来可比火的谍战片来打个假如,JSON是违法党们用来书写和置换情报的“暗号”,而JSONP则是把用暗号书写的音讯传递给协调同志时行使的知情格局。看到没?一个是描述音信的格式,贰个是消息传递双方约定的主意。

 

既是随便聊聊,那大家就不再选取机械的形式来叙述,而是把关爱宗旨放在辅助开发人士精晓是还是不是应该选拔接纳以及哪些接纳上。

 

 什么是JSON?

 

前方简单说了刹那间,JSON是一种基于文本的数据调换格局,只怕叫做数据描述格式,你是不是该选取他先是肯定要关切它所持有的长处。

 

JSON的优点:

壹 、基于纯文本,跨平台传递极其简单;

② 、Javascript原生协理,后台语言差不多一切支撑;

③ 、轻量级数据格式,占用字符数量极少,特别适合网络传递;

肆 、可读性较强,纵然不比XML那么一目掌握,但在创造的各种缩进之后依然很不难辨认的;

伍 、简单编写和分析,当然前提是你要精通数据结构;

JSON的症结当然也有,但在小编眼里实在是嗤之以鼻的事物,所以不再单独表达。

 

JSON的格式可能叫规则:

JSON能够以卓殊简单的点子来讲述数据结构,XML能做的它都能做,因而在跨平台方面相互完全不分伯仲。

一 、JSON唯有三种数据类型描述符,大括号{}和方括号[],别的英文冒号:是映射符,英文逗号,是分隔符,英文双引号””是定义符。

贰 、大括号{}用来讲述一组“分裂类型的冬季键值对聚集”(种种键值对能够清楚为OOP的属性描述),方括号[]用来叙述一组“相同档次的有序数据集合”(可对应OOP的数组)。

三 、上述二种集合中若有两个子项,则经过英文逗号,实行分隔。

四 、键值对以英文冒号:实行分隔,并且建议键名都增加英文双引号””,以便于不相同语言的解析。

⑤ 、JSON内部常用数据类型无非正是字符串、数字、布尔、日期、null
这么几个,字符串必须用双引号引起来,其他的都休想,日期类型比较奇特,那里就不举办叙述了,只是提议一旦客户端从未按日期排序功能须要的话,那么把日虎时间一贯当做字符串传递就好,能够节省很多劳动。

 

JSON实例:

图片 1😉

// 描述一个人

var person = {
    "Name": "Bob",
    "Age": 32,
    "Company": "IBM",
    "Engineer": true
}

// 获取这个人的信息

var personAge = person.Age;

// 描述几个人

var members = [
    {
        "Name": "Bob",
        "Age": 32,
        "Company": "IBM",
        "Engineer": true
    },
    {
        "Name": "John",
        "Age": 20,
        "Company": "Oracle",
        "Engineer": false
    },
    {
        "Name": "Henry",
        "Age": 45,
        "Company": "Microsoft",
        "Engineer": false
    }
]

// 读取其中John的公司名称

var johnsCompany = members[1].Company;

// 描述一次会议

var conference = {
    "Conference": "Future Marketing",
    "Date": "2012-6-1",
    "Address": "Beijing",
    "Members": 
    [
        {
            "Name": "Bob",
            "Age": 32,
            "Company": "IBM",
            "Engineer": true
        },
        {
            "Name": "John",
            "Age": 20,
            "Company": "Oracle",
            "Engineer": false
        },
        {
            "Name": "Henry",
            "Age": 45,
            "Company": "Microsoft",
            "Engineer": false
        }
    ]
}

// 读取参会者Henry是否工程师

var henryIsAnEngineer = conference.Members[2].Engineer;

图片 2😉

 

有关JSON,就说那样多,更加多细节请在开发进程中查阅资料深切学习。

 

 什么是JSONP?

 

先说说JSONP是怎么发生的:

骨子里网上关于JSONP的教学有许多,但却千篇一律,而且云里雾里,对于众多刚接触的人来注脚白起来有些劳碌,小可不才,试着用自个儿的办法来演讲一下那几个标题,看看是不是有赞助。

① 、四个明显的题材,Ajax直接呼吁普通文书存在跨域无权力访问的难题,甭管您是静态页面、动态网页、web服务、WCF,只若是跨域请求,一律禁止;

二 、但是我们又发现,Web页面上调用js文件时则不受是不是跨域的影响(不仅如此,大家还发现凡是拥有”src”这一个本性的竹签都抱有跨域的能力,比如<script>、<img>、<iframe>);

叁 、于是能够断定,当前阶段即使想经过纯web端(ActiveX控件、服务端代理、属于现在的HTML5之Websocket等艺术不算)跨域访问数据就唯有一种只怕,那正是在长途服务器上设法把多少装进js格式的文书里,供客户端调用和越来越处理;

四 、恰巧大家早已通晓有一种叫做JSON的纯字符数量格式能够简单的描述复杂数据,更妙的是JSON还被js原生补助,所以在客户端大致能够随便的处理那种格式的数量;

五 、那样子消除方案就有声有色了,web客户端通过与调用脚本一模一样的主意,来调用跨域服务器上动态变化的js格式文件(一般以JSON为后缀),综上可得,服务器之所以要动态生成JSON文件,目标就在于把客户端要求的数额装入进去。

六 、客户端在对JSON文件调用成功之后,也就获得了友好所需的数额,剩下的就是根据自身必要开始展览处理和显示了,那种获取远程数据的法门看起来非凡像AJAX,但实质上并不相同等。

⑦ 、为了有利于客户端接纳数据,逐步形成了一种非正式传输协议,人们把它称作JSONP,该协议的二个要义正是同意用户传递多少个callback参数给服务端,然后服务端重回数据时会将以此callback参数作为函数名来包裹住JSON数据,那样客户端就能够无限制定制自个儿的函数来机关处理回来数据了。

如若对于callback参数怎样选取还有个别模糊的话,大家前面会有实际的实例来上课。

 

JSONP的客户端具体落到实处:

不管jQuery也好,extjs也罢,又也许是其余帮衬jsonp的框架,他们背后所做的劳作都以如出一辙的,上面小编来循途守辙的认证一下jsonp在客户端的达成:

 

① 、大家驾驭,哪怕跨域js文件中的代码(当然指符合web脚本安全策略的),web页面也是能够无条件履行的。

长途服务器remoteserver.com根目录下有个remote.js文件代码如下:

alert('我是远程文件');

地面服务器localserver.com下有个jsonp.html页面代码如下:

图片 3😉

<!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></title>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>

图片 4😉

必然,页面将会弹出1个提示窗体,展现跨域调用成功。

 

二 、以后我们在jsonp.html页面定义1个函数,然后在远程remote.js中盛传数据开展调用。

jsonp.html页面代码如下:

图片 5😉

<!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></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>

图片 6😉

remote.js文件代码如下:

localHandler({"result":"我是远程js带来的数据"});

运维之后查看结果,页面成功弹出提醒窗口,显示本地函数被跨域的长途js调用成功,并且还收纳到了远程js带来的数量。很欣喜,跨域远程获取数据的指标基本落到实处了,不过又两个难题出现了,小编怎么让长途js知道它应该调用的地方函数叫什么名字吧?毕竟是jsonp的服务者都要直面不少劳务目的,而那个劳务对象分别的本地函数都不等同啊?大家跟着往下看。

 

③ 、聪明的开发者很不难想到,只要服务端提供的js脚本是动态变化的就行了呗,那样调用者能够传三个参数过去告诉服务端“作者想要一段调用XXX函数的js代码,请您回去给自个儿”,于是服务器就能够遵从客户端的急需来生成js脚本并响应了。

看jsonp.html页面包车型大巴代码:

图片 7😉

<!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></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

图片 8😉

这一次的代码变化相比大,不再直接把远程js文件写死,而是编码达成动态查询,而那也多亏jsonp客户端完成的为主部分,本例中的重点也就在于怎样成功jsonp调用的全经过。

笔者们看出调用的url中传送了二个code参数,告诉服务器本人要查的是CA壹玖玖七回航班的信息,而callback参数则告知服务器,笔者的地头回调函数叫做flightHandler,所以请把询问结果传到这些函数中开始展览调用。

OK,服务器很聪明伶俐,这一个号称flightResult.aspx的页面生成了一段那样的代码提供给jsonp.html(服务端的兑现那里就不演示了,与你选拔的语言无关,说到底正是拼接字符串):

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

小编们见到,传递给flightHandler函数的是多个json,它描述了航班的骨干音讯。运维一下页面,成功弹出提醒窗口,jsonp的履行全经过顺遂达成!

 

④ 、到那边甘休的话,相信你早已能够知道jsonp的客户端完毕原理了啊?剩下的正是何许把代码封装一下,以便于与用户界面交互,从而完结数十二回和重新调用。

哪些?你用的是jQuery,想清楚jQuery怎么着完毕jsonp调用?好啊,那作者就好人做到底,再给你一段jQuery使用jsonp的代码(大家如故沿用上边十分航班消息查询的例证,假定重临jsonp结果不变):

图片 9😉

<!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>

图片 10😉

是否有点奇怪?为啥自个儿这一次没有写flightHandler那么些函数呢?而且居然也运维成功了!哈哈,那便是jQuery的功劳了,jquery在处理jsonp类型的ajax时(照旧不禁吐槽,即便jquery也把jsonp归入了ajax,但实际上它们确实不是2遍事儿),自动帮您转移回调函数并把数据取出来供success属性方法来调用,是还是不是很爽呀?

 

好啊,写到那里,笔者已经无力再写下去,又困又累,得赶紧睡觉。朋友们借使看那毋庸置疑,觉得有启示,给点个“推荐”呗!由于实在比较不难,所以就不再提供demo源码下载了。

 

 4月20日下午的补充:

 

没悟出上了微博的头条推荐。看到大家对这篇作品的承认和评价,照旧很春风得意的,那里针对ajax与jsonp的异议再做一些填补表达:

一 、ajax和jsonp那二种技术在调用格局上“看起来”很像,指标也一如既往,都以呼吁二个url,然后把服务器再次回到的数据实行拍卖,因而jquery和ext等框架都把jsonp作为ajax的一种格局举办了包装;

② 、但ajax和jsonp其实本质上是例外的事物。ajax的核心是经过XmlHttpRequest获取非本页内容,而jsonp的中坚则是动态添加<script>标签来调用服务器提供的js脚本。

③ 、所以说,其实ajax与jsonp的界别不在于是不是跨域,ajax通过服务端代理一样能够完结跨域,jsonp本人也不排外同域的数量的拿走。

四 、还有就是,jsonp是一种艺术或然说非强制性协议,就像ajax一样,它也不肯定非要用json格式来传递数据,若是您愿意,字符串都行,只也就那样不便利用jsonp提供公开服务。

简单的说,jsonp不是ajax的二个特例,哪怕jquery等巨头把jsonp封装进了ajax,也无法改变着一点!

 

瞩目:此作品属博主原创,转载请注解作者音讯和原有链接,多谢同盟。

相关文章

网站地图xml地图