前言:
说到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 示例:
// 描述一个人
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、但是我们也发现,在网页上调用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页面代码如下:
xmlns="http://www.w3.org/1999/xhtml">
<script type="text/javascript" src="http://remoteserver.com/remote.js"></script><body>