对 JSON 和 JSONP 感到困惑吗? 读完这篇文章你可能会恍然大悟(包括jQuery用例)

 2024-02-11 04:02:51  阅读 0

前言:

说到AJAX,我们不可避免地会面临两个问题。 首先是AJAX以什么格式交换数据? 第二个是如何解决跨域需求? 目前针对这两个问题有不同的解决方案。 例如,可以使用自定义字符串或XML来描述数据,可以通过服务器端代理解决跨域问题。

但到目前为止,最推荐或者首选的方案是使用JSON来传输数据,并依靠JSONP来跨域。 这就是本文的主题。

虽然 JSON 和 JSONP 之间只有一个字母的区别,但实际上它们根本不是一回事:JSON 是一种数据交换格式,而 JSONP 是开发者匠心打造的一种非官方的跨域数据交互。 协议。 我们用最近流行的谍战片来打个比方。 JSON是地下党用来写入和交换信息的“代码”,而JSONP则是用于将代码写入的信息传输给战友的连接方式。 你有没有看到? 一是描述信息的格式,二是双方约定的信息传输方式。

由于我们只是随便聊聊,因此我们将不再用教条的方式来讲述它,而是专注于帮助开发者了解是否应该选择使用它以及如何使用它。

什么是 JSON?

正如前面简单提到的,JSON 是一种基于文本的数据交换方法,或者说是一种数据描述格式。 是否应该选择它首先要关注它的优点。

JSON 的优点:

1.基于纯文本,跨平台传输极其简单;

2.原生支持,几乎所有后端语言都支持;

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

4、可读性强。 虽然不像XML那么清晰,但经过合理的缩进后仍然很容易识别;

5.易于编写和解析,当然前提是你需要了解数据结构;

当然,JSON也有缺点,但在笔者看来确实微不足道,所以就不单独解释了。

JSON的格式或规则:

JSON可以用非常简单的方式描述数据结构,并且它可以做XML能做的一切,因此两者在跨平台方面是完全平等的。

1. JSON只有两种数据类型描述符,大括号{}和方括号[]。 其余的英文冒号是映射字符,英文逗号是分隔符,英文双引号“”是定义字符。

2、大括号{}用于描述一组“不同类型的无序键值对”(每个键值对可以理解为一个OOP属性描述),方括号[]用于描述一组“不同类型的无序键值对” “不同类型的无序键值对”。 “有序数据集合”(可以对应OOP的数组)。

3. 如果以上两组中有多个子项,则应以逗号分隔。

4、键值对之间用英文冒号:分隔,建议键名加上英文双引号“”,方便不同语言的解析。

5. JSON中常用的数据类型无非就是字符串、数字、布尔值、日期和null。 字符串必须用双引号括起来,其余的不使用。 日期类型比较特殊,这里不再赘述。 建议如果客户端不需要按日期排序的功能,那么直接将日期和时间作为字符串传递即可,这样可以省去很多麻烦。

JSON 示例:

  1. // 描述一个人

  2. var person = {"Name": "Bob","Age": 32,"Company": "IBM", "Engineer": true}// 获取这个人的信息

  3. var personAge = person.Age;// 描述几个人

  4. var members = [

  5.    {"Name": "Bob", "Age": 32,"Company": "IBM","Engineer": true },

  6.    {"Name": "John",  "Age": 20, "Company": "Oracle","Engineer": false},

  7.    {"Name": "Henry", "Age": 45, "Company": "Microsoft","Engineer": false }

  8. ]// 读取其中John的公司名称

  9. var johnsCompany = members[1].Company;// 描述一次会议

  10. var conference = { "Conference": "Future Marketing","Date": "2012-6-1","Address": "Beijing","Members": [

  11.        {  "Name": "Bob","Age": 32, "Company": "IBM","Engineer": true },

  12.        { "Name": "John","Age": 20, "Company": "Oracle",  "Engineer": false },

  13.        { "Name": "Henry", "Age": 45, "Company": "Microsoft", "Engineer": false}

  14.    ]

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

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

关于 JSON,仅此而已。 更多详情请参考开发过程中深入研究的资料。

什么是 JSONP?

我们先来说一下JSONP是如何生成的:

其实网上关于JSONP的解释有很多,但是都是雷同,而且比较模糊。 对于很多刚接触它的人来说有点难以理解。 这不是一件小事。 尝试用自己的方式解释这个问题,看看是否有效。 有帮助。

1、一个众所周知的问题是普通文件直接Ajax请求存在跨域未授权访问的问题。 无论是静态页面、动态网页、Web服务、WCF,只要是跨域请求,都是不允许的;

2、但是我们也发现,在网页上调用js文件时,并不受是否跨域的影响(不仅如此,我们还发现所有带有“src”属性的标签都具有跨域能力, 例如,,);

3、可以判断,现阶段,如果想通过纯web端(控件、服务器端代理、未来的HTML5等不包括在内)跨域访问数据,只有一种可能,那就是尝试将数据存储在远程服务器上。 加载成js格式的文件,供客户端调用并进一步处理;

4.我们恰好已经知道有一种纯字符数据格式,称为JSON,可以简洁地描述复杂的数据。 更棒的是,js 也原生支持 JSON,所以客户端几乎可以随心所欲地处理这种格式的数据;

5、这样,溶液就准备好了。 Web客户端调用跨域服务器上动态生成的js格式文件(通常以JSON为后缀)的方式与调用脚本完全相同。 很明显,服务器之所以需要动态生成 JSON 文件的目的就是为了加载客户端需要的数据。

6、客户端成功调用JSON文件后,获取到自己需要的数据。 剩下的就是根据自己的需要来处理和显示了。 这种获取远程数据的方法看起来很像AJAX,但实际上并不一样。

7、为了方便客户端使用数据,逐渐形成了一种非正式的传输协议,称为JSONP。 这个协议的关键点之一是允许用户向服务器传递一个参数,然后服务器在返回数据时会使用这个参数。 参数作为函数名来包装JSON数据,以便客户端可以自定义自己的函数来自动处理返回的数据。

如果你对参数的使用方法还有些模糊,我们稍后会用具体的例子来解释。

JSONP客户端具体实现:

不管是extjs还是其他支持jsonp的框架,它们在幕后所做的工作都是一样的。 下面我一步步解释一下jsonp在客户端的实现:

1.我们知道,即使是跨域的js文件中的代码(这当然符合网页脚本安全策略),网页也可以无条件执行。

远程服务器根目录下有一个.js文件,代码如下:

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

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

  1. xmlns="http://www.w3.org/1999/xhtml">

  2.    

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

毫无疑问,页面会弹出一个提示表单,说明跨域调用成功。

2.现在我们在jsonp.html页面定义一个函数,然后通过传入远程.js中的数据来调用它。

jsonp.html页面代码如下:

  1. xmlns="http://www.w3.org/1999/xhtml">

  2.    

  3.    <script type="text/javascript">    var localHandler = function(data){

  4.        alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);

  5.    };    </script>

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

.js文件代码如下:

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

运行后查看结果。 页面成功弹出提示窗口,显示跨域远程js成功调用本地函数,并且也收到了远程js带来的数据。 很高兴跨域远程数据采集的目的基本达到了,但是另一个问题又出现了。 如何让远程js知道它应该调用的本地函数的名称? 毕竟jsonp服务器要面对很多服务对象,而这些服务对象的本地功能又各不相同? 我们往下看。

3、聪明的开发者很容易想到,只要服务器提供的js脚本是动态生成的,调用者就可以传递一个参数告诉服务器“我想要一段调用XXX函数的js代码,请”。 回到我这里”,这样服务器就可以根据客户端的需求生成js脚本并响应。

看一下jsonp.html页面的代码:

  1. xmlns="http://www.w3.org/1999/xhtml">

  2.    

  3.    <script type="text/javascript">

  4.    // 得到航班信息查询结果后的回调函数

  5.    var flightHandler = function(data){

  6.        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');

  7.    };    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)

  8.    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";    // 创建script标签,设置其属性

  9.    var script = document.createElement('script');

  10.    script.setAttribute('src', url);    // 把script标签加入head,此时调用开始  

  11.    document.getElementsByTagName('head')[0].appendChild(script);

  12. </script>

  13. <body>

这次代码改变了很多。 它不再直接编写远程js文件,而是编写代码来实现动态查询。 这也是jsonp客户端实现的核心部分。 本例的重点是如何完成jsonp调用。 整个过程。

我们看到调用URL中传入了一个code参数,告诉服务器我要查的是航班信息,而该参数告诉服务器调用的是我本地的回调函数,所以请将查询结果传入到这个函数中叫它。 。

好吧,服务器很聪明。 这个叫.aspx的页面生成了这样一段代码,提供给jsonp.html(服务端实现这里就不演示了,和你选择的语言无关,归根结底就是拼接字符串):

({“代码”:“”,“价格”:1780,“”:5});

我们看到传递给函数的是一个json,它描述了航班的基本信息。 运行页面,会弹出成功的提示窗口,整个jsonp执行过程就顺利完成了!

4、到现在为止,相信你已经能够了解jsonp的客户端实现原理了吧? 剩下的就是如何封装代码,使其能够与用户界面交互,实现多次重复调用。

什么? 你正在使用的是,想知道如何实现jsonp调用? 好吧,那我就做到底,再给大家一段使用jsonp的代码(我们还是用上面的航班信息查询例子,假设返回的jsonp结果不变):

  1. xmlns="http://www.w3.org/1999/xhtml" >

  2.     </span><span class="pln" style="color: rgb(0, 0, 0);">Untitled Page</span><span class="tag" style="color: rgb(0, 0, 136);">

  3.      <script type="text/javascript" src=jquery.min.js"></script>

  4.      <script type="text/javascript">

  5.     jQuery(document).ready(function(){

  6.        $.ajax({

  7.             type: "get",

  8.             async: false,

  9.             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",

  10.             dataType: "jsonp",

  11.             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)            

  12.             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据            

  13.             success: function(json){

  14.                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');

  15.             },

  16.             error: function(){

  17.                 alert('fail');

  18.             }

  19.         });     });

  20.         </script>

  21.    

  22.  <body>

  23.  

是不是有点奇怪? 我这次为什么不写这个函数呢? 而且确实成功了! 哈哈,这是我的功劳。 在处理jsonp类型的ajax时(我还是忍不住吐槽一下,虽然jsonp也被归类为ajax,但它们真的不是一回事),它自动为你生成一个回调函数,拿出来是不是很棒数据并调用属性方法?

好吧,写完这篇,我就没有力气继续写了。 我又困又累,所以我得赶紧上床睡觉。 朋友们,如果您读了这篇文章,觉得有启发,请给我一个“推荐”! 由于比较简单,所以不再提供demo源码下载。

补充:

没想到居然被博客园首页推荐了。 很高兴看到大家对这篇文章的认可和评论。 这里对ajax和jsonp的异同做一些补充说明:

1、Ajax和jsonp是两种从调用方式上“看起来”非常相似、用途相同的技术。 它们都请求一个 URL,然后处理服务器返回的数据。 因此ext、ext等框架都将jsonp视为ajax。 一种形式被封装;

2.但是ajax和jsonp本质上是不同的东西。 ajax的核心是获取非本页内容,而jsonp的核心是动态添加标签来调用服务器提供的js脚本。

3.所以,其实ajax和jsonp的区别并不在于是否跨域。 Ajax还可以通过服务器代理实现跨域,而jsonp本身并不排除获取同域的数据。

4.还有一点就是jsonp是一个方法或者非强制协议。 和ajax一样,不一定非要用json格式来传输数据。 如果你愿意的话,字符串也可以,但是不利于使用。 jsonp 提供公共服务。

总而言之,jsonp并不是ajax的特例。 即使巨人将jsonp封装成ajax,也改变不了什么!

标签: 调用 远程 字符

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码