彻底理解json和jsonp

json

基本概念

  • JSON 是轻量级的文本数据交换格式
  • Javascript原生支持,后台语言几乎全部支持
  • 容易编写和解析

格式和规则

  • JSON只有两种数据类型描述符,大括号{}和方括号[],其余英文冒号:是映射符,英文逗号,是分隔符,英文双引号""是定义符
  • 大括号{}用来描述一组“不同类型的无序键值对集合”(每个键值对可以理解为OOP的属性描述),方括号[]用来描述一组“相同类型的有序数据集合”(可对应OOP的数组)
  • 上述两种集合中若有多个子项,则通过英文逗号,进行分隔
  • 键值对以英文冒号:进行分隔,并且建议键名都加上英文双引号"",以便于不同语言的解析
  • JSON内部常用数据类型无非就是字符串、数字、布尔、日期、null 这么几个,字符串必须用双引号引起来,其余的都不用

实例

{
    "sites": [
    { "name":"百度" , "url":"www.baidu.com" }, 
    { "name":"Bing" , "url":"www.bing.com" },
    ]
}

jsonp

jsonp的起源

要讨论jsonp是如何产生的就离不开浏览器的同源策略,那么什么是同源策略呢。
同源指的是协议,主机(IP)以及端口相同,通过下面的表格能够比较直观的了解同源的判断规则。
http://example.com/test/dir1为例

URL结果原因
http://example.com/test/dir2同源只有路径不同
http://example.com/同源只有路径不同
http://example.com:81/tset不同源端口不同
https://example.com/tset不同源协议不同(https)
http://en.example.com不同源主机不同

在同源策略的约束下,一个页面的脚本不可以访问不同源页面的资源。这个策略可以阻止一个页面上的恶意脚本通过页面的DOM对象获得访问另一个页面上敏感信息的权限。设想一下如果没有同源策略,你在访问恶意网站evil.com同时也在访问网银的页面,evil页面上的js脚本就可以访问到网银页面的资源例如Dom对象,可能会窃取cookie发送至攻击者服务器导致财产损失,所以同源策略可以看做现代浏览器安全的基石。
但同源策略在保护页面的前提下也牺牲了网页的拓展性,如果是稍微大一些的应用就很难把html,js,css,图片等资源完全放置在同一台服务器上。所以现在浏览器在例如img,script,style等有src属性的标签中允许去引用跨域的资源。因为script可以跨域读取js在浏览器执行,又由于json被js原生支持于是jsonp就诞生了。

jsonp的过程

jsonp用一句话概括就是定义好callback(回调函数)并传送至服务端,服务端采用callback为函数名包裹json数据返回浏览器并执行。
在这里插入图片描述
可能只说明定义还是不太好理解,下面用几个实例来进一步阐述这个过程。

jsonp代码实例

下面精彩举例来自于随便说说json和jsonp

远端js可以执行

首先远端的js代码在浏览器中被加载是可以正常执行的,即js文件的域是加载页面所处的域而不是储存js文件的域!!!
服务端js代码:(remote.com/remote.js)

alert('remote data')

用户浏览器中js代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript" src="http://remote.com/remote.js"></script>
</body>
</html>

此代码会正常弹窗

回调函数执行

然后我们在客户端页面中加入一个回调函数
用户浏览器中js代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
	var callback = function (data){
		alert('我是本地函数 被服务端传来的函数调用 远程js带来的数据是' + data.result)
	}
</script>
<script type="text/javascript" src="http://remote.com/remote.js"></script>
</body>
</html>

服务端js代码:

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

运行后发现正常弹窗 服务端的数据被带来前端且正常调用了客户端定义的回调函数,此时跨域获取数据的目的终于实现,最后一个问题,如何让服务端知道该调用的客户端函数名字叫什么,解决办法就是将回调函数名传给客户端.。

服务端动态调用回调函数

此时用户浏览器的代码变为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
	var callbackName = function (data){
		alert('我是本地函数 被服务端传来的函数调用 远程js带来的数据是' + data.result)
	}
</script>
<script type="text/javascript" src="http://remote.com/remote.js?callback=callbackName"></script>
</body>
</html>

此时远程服务器上运行的代码会接受客户端传来的请求,提取出callback的名字,将查询数据封装为

callbackName(
{远程数据}
)

运行后浏览器收到了服务端的数据且执行callbackName函数。

客户端动态生成js标签

一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。
客户端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>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>

远程服务器返回的数据形式:

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

此时就完成了完整的远程资源调用,客户端可以定义一个形如提交查询航班信息的button绑定动态添加js的函数。用户输入航班信息后动态生成一个js标签,访问带有航班信息的服务器,获得数据后返回callback包裹的航班信息到客户端,客户端执行callback弹出航班的价格。

参考文章:
说说json和jsonp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值