写点什么

JSON 和 JSONP 对比

  • 2022 年 5 月 13 日
  • 本文字数:2843 字

    阅读完需:约 9 分钟

// 描述几个人


var members = [


{


"Name": "Bob",


"Age": 32,


"Company": "IBM",《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】"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,就说这么多,更多细节请在开发过程中查阅资料深入学习。


<table border="0" cellpadding="2" style="border:0px solid white; border-collapse:collapse; word-break:break-word; width:1564px; height:40px; color:rgb(255,255,255); font-size:20px; font-family:微软雅黑; background-color:rgb(39,105,152)"><tbody><tr><td style="border:1px solid silver; border-collapse:collapse; padding:3px"> <span style="font-size:18pt">什么是 JSONP?</span></td></tr></tbody></table>


先说说 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="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="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="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 调用的全过程。

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
JSON和JSONP对比_Java_爱好编程进阶_InfoQ写作社区