ajax 和jsonp 不是一码事 细读详解

因为Sencha Touch 2这类开辟情势的特征,基础决议了它原生的数据交互行动险些只能经由过程AJAX来完成。
固然了,经由过程挪用壮大的PhoneGap插件然后打包,你可以完成100%的Socket通信和当地数据库功用,又或许经由过程HTML5的WebSocket也可以完成与效劳器的通信和效劳端推功用,但这两种体式格局都有其局限性,前者须要PhoneGap支撑,后者要求用户装备必需支撑WebSocket,因而都不能算是ST2的原生处置惩罚计划,原生的只需AJAX。

说到AJAX就会不可避免的面临两个题目,第一个是AJAX以何种花样来交换数据?第二个是跨域的需求怎样处置惩罚?这两个题目如今都有差异的处置惩罚计划,比如数据可以用自定义字符串或许用XML来形貌,跨域可以经由过程效劳器端代办来处置惩罚。
但到如今为止最被推重或许说首选的计划照样用JSON来传数据,靠JSONP来跨域。而这就是本文将要报告的内容。

JSON和JSONP虽然只需一个字母的差异,但着实他们基础不是一回事儿:JSON是一种数据交换花样,而JSONP是一种依托开辟人员的智慧才智创造出的一种非官方跨域数据交互协定。我们拿近来比较火的谍战片来打个比如,JSON是地下党们用来誊写和交换谍报的“暗号”,而JSONP则是把用暗号誊写的谍报通报给自身同道时运用的讨论体式格局。看到没?一个是形貌信息的花样,一个是信息通报两边商定的要领。

既然随便聊聊,那我们就不再采纳教条的体式格局来报告,而是把关注重心放在协助开辟人员明白是不是应当挑选运用以及怎样运用上。
小小的广告一下,该篇文章是在自身群里与Sencha Touch 2的开辟者们一同讨论ST2数据交互模子时有感而发写出来的,因而假如您对Mobile Web App开辟有兴致的话,迎接到场Sencha Touch 交换 QQ 群 213119459 。

什么是JSON?

前面简朴说了一下,JSON是一种基于文本的数据交换体式格局,或许叫做数据形貌花样,你是不是该选用他起首肯定要关注它所具有的长处。

JSON的长处:
1、基于纯文本,跨平台通报极为简朴;
2、JavaScript原生支撑,背景言语险些悉数支撑;
3、轻量级数据花样,占用字符数目少少,迥殊合适互联网通报;
4、可读性较强,虽然比不上XML那末一览无余,但在合理的顺次缩进以后照样很轻易辨认的;
5、轻易编写和剖析,固然条件是你要晓得数据结构;
JSON的瑕玷固然也有,但在作者看来着实是可有可无的东西,所以不再零丁申明。

JSON的花样或许叫划定规矩:
JSON可以以异常简朴的体式格局来形貌数据结构,XML能做的它都能做,因而在跨平台方面二者完整不分伯仲。
1、JSON只需两种数据范例形貌符,大括号{}和方括号[],其他英文冒号:是映照符,英文逗号,是分开符,英文双引号””是定义符。
2、大括号{}用来形貌一组“差异范例的无序键值对鸠合”(每一个键值对可以明白为OOP的属性形貌),方括号[]用来形貌一组“雷同范例的有序数据鸠合”(可对应OOP的数组)。
3、上述两种鸠合中如有多个子项,则经由过程英文逗号,举行分开。
4、键值对以英文冒号:举行分开,而且发起键名都加上英文双引号””,以便于差异言语的剖析。
5、JSON内部经常使用数据范例不过就是字符串、数字、布尔、日期、null 这么几个,字符串必需用双引号引起来,其他的都不必,日期范例比较特别,这里就不睁开报告了,只是发起假如客户端没有按日期排序功用需求的话,那末把日期时候直接作为字符串通报就好,可以省去许多贫苦。

JSON实例:
复制代码
// 形貌一个人

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;
复制代码

关于JSON,就说这么多,更多细节请在开辟过程当中查阅材料深切进修。

什么是JSONP?

先说说JSONP是怎样发生的:
着实网上关于JSONP的解说有许多,但却如出一辙,而且云里雾里,关于许多刚打仗的人来说明白起来有些难题,小可鄙人,试着用自身的体式格局来阐释一下这个题目,看看是不是有协助。
1、一个尽人皆知的题目,Ajax直接要求平常文件存在跨域无权限接见的题目,甭管你是静态页面、动态网页、web效劳、WCF,只如果跨域要求,一概不准;
2、不过我们又发明,Web页面上挪用js文件时则不受是不是跨域的影响(不仅如此,我们还发明通常具有”src”这个属性的标签都具有跨域的才能,比如<script>、<img>、<iframe>);
3、因而可以推断,当前阶段假如想经由过程纯web端(ActiveX控件、效劳端代办、属于将来的Html5之Websocket等体式格局不算)跨域接见数据就只需一种能够,那就是在长途效劳器上想法把数据装进js花样的文件里,供客户端挪用和进一步处置惩罚;
4、碰巧我们已晓得有一种叫做JSON的纯字符数据花样可以简约的形貌庞杂数据,更妙的是JSON还被js原生支撑,所以在客户端险些可以为所欲为的处置惩罚这类花样的数据;
5、这模样处置惩罚计划就呼之欲出了,web客户端经由过程与挪用剧本如出一辙的体式格局,来挪用跨域效劳器上动态天生的js花样文件(平常以JSON为后缀),不言而喻,效劳器之所以要动态天生JSON文件,目标就在于把客户端须要的数据装入进去。
6、客户端在对JSON文件挪用胜利以后,也就取得了自身所需的数据,剩下的就是根据自身需求举行处置惩罚和展示了,这类猎取长途数据的体式格局看起来异常像AJAX,但着实并不一样。
7、为了便于客户端运用数据,逐步形成了一种非正式传输协定,人们把它称作JSONP,该协定的一个要点就是许可用户通报一个callback参数给效劳端,然后效劳端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,如许客户端就可以随便定制自身的函数来自动处置惩罚返回数据了。
假如关于callback参数怎样运用另有些隐约的话,我们背面会有详细的实例来解说。

JSONP的客户端详细完成:
不论jQuery也好,extjs也罢,又或许是其他支撑jsonp的框架,他们幕后所做的事情都是一样的,下面我来循规蹈矩的申明一下jsonp在客户端的完成:

1、我们晓得,哪怕跨域js文件中的代码(固然指相符web剧本安全策略的),web页面也是可以无条件实行的。
长途效劳器remoteserver.com根目录下有个remote.js文件代码以下:
alert(‘我是长途文件’);
当地效劳器localserver.com下有个jsonp.html页面代码以下:
复制代码
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”” target=”_blank”>http://www.w3.org/1999/xhtml&…
<head>

<title></title>
<script type="text/javascript" src="http://remoteserver.com/remote.js"></script>

</head>
<body>

</body>
</html>
复制代码
毫无疑问,页面将会弹出一个提醒窗体,显现跨域挪用胜利。

2、如今我们在jsonp.html页面定义一个函数,然后在长途remote.js中传入数据举行挪用。
jsonp.html页面代码以下:
复制代码
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”” target=”_blank”>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>
复制代码
remote.js文件代码以下:
localHandler({“result”:”我是长途js带来的数据”});
运转以后检察效果,页面胜利弹出提醒窗口,显现当地函数被跨域的长途js挪用胜利,而且还吸收到了长途js带来的数据。很欣喜,跨域长途猎取数据的目标基础完成了,然则又一个题目涌现了,我怎样让长途js晓得它应当挪用的当地函数叫什么名字呢?毕竟是jsonp的效劳者都要面临许多效劳对象,而这些效劳对象各自的当地函数都不雷同啊?我们接着往下看。

3、智慧的开辟者很轻易想到,只需效劳端供应的js剧本是动态天生的就好了呗,如许挪用者可以传一个参数过去通知效劳端“我想要一段挪用XXX函数的js代码,请你返回给我”,因而效劳器就可以根据客户端的需求来天生js剧本并相应了。
看jsonp.html页面的代码:
复制代码
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”” target=”_blank”>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>
复制代码
此次的代码变化比较大,不再直接把长途js文件写死,而是编码完成动态查询,而这也恰是jsonp客户端完成的中心部份,本例中的重点也就在于怎样完成jsonp挪用的全过程。
我们看到挪用的url中通报了一个code参数,通知效劳器我要查的是CA1998次航班的信息,而callback参数则通知效劳器,我的当地回调函数叫做flightHandler,所以请把查询效果传入这个函数中举行挪用。
OK,效劳器很智慧,这个叫做flightResult.aspx的页面天生了一段如许的代码供应给jsonp.html(效劳端的完成这里就不演示了,与你选用的言语无关,说究竟就是拼接字符串):
flightHandler({

"code": "CA1998",
"price": 1780,
"tickets": 5

});
我们看到,通报给flightHandler函数的是一个json,它形貌了航班的基础信息。运转一下页面,胜利弹出提醒窗口,jsonp的实行全过程顺利完成!

4、到这里为止的话,相信你已可以明白jsonp的客户端完成道理了吧?剩下的就是怎样把代码封装一下,以便于与用户界面交互,从而完成屡次和反复挪用。
什么?你用的是jQuery,想晓得jQuery怎样完成jsonp挪用?好吧,那我就大好人做究竟,再给你一段jQuery运用jsonp的代码(我们依旧相沿上面谁人航班信息查询的例子,假定返回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>
复制代码
是不是是有点新鲜?为何我此次没有写flightHandler这个函数呢?而且居然也运转胜利了!哈哈,这就是jQuery的劳绩了,jquery在处置惩罚jsonp范例的ajax时(照样不由得吐槽,虽然jquery也把jsonp归入了ajax,但着实它们真的不是一回事儿),自动帮你天生回调函数并把数据取出来供success属性要领来挪用,是不是是很爽呀?

好啦,写到这里,我已无力再写下去,又困又累,得赶忙睡觉。朋友们如果看这不错,以为有启示,给点个“引荐”呗!因为着实比较简朴,所以就不再供应demo源码下载了。

这里针对ajax与jsonp的异同再做一些补充申明:
1、ajax和jsonp这两种手艺在挪用体式格局上“看起来”很像,目标也一样,都是要求一个url,然后把效劳器返回的数据举行处置惩罚,因而jquery和ext等框架都把jsonp作为ajax的一种情势举行了封装;
2、但ajax和jsonp着实本质上是差异的东西。ajax的中心是经由过程XmlHttpRequest猎取非本页内容,而jsonp的中心则是动态增加<script>标签来挪用效劳器供应的js剧本。
3、所以说,着实ajax与jsonp的区分不在因而不是跨域,ajax经由过程效劳端代办一样可以完成跨域,jsonp自身也不排挤同域的数据的猎取。
4、另有就是,jsonp是一种体式格局或许说非强制性协定,犹如ajax一样,它也不一定非要用json花样来通报数据,假如你情愿,字符串都行,只不过如许不利于用jsonp供应公然效劳。
总而言之,jsonp不是ajax的一个惯例,哪怕jquery等巨子把jsonp封装进了ajax,也不能改变着一点!

著作权归作者一切。贸易转载请联络作者取得受权,非贸易转载请说明出处。互联网+时期,时候要坚持进修,联袂千锋PHP,Dream It Possible。

    原文作者:风吹白杨树
    原文地址: https://segmentfault.com/a/1190000009462159
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞