【转】json与jsonp区别浅析(json才是目的,jsonp只是手段)
一言以蔽之,json返回的是一串数据;而jsonp返回的是脚本代码(包含一个函数调用);
JSON其实就是JavaScript中的一个对象,跟var obj={}在质上完全一样,只是在量上可以无限扩展。简单地讲,json其实就是JavaScript中的对象(Object)和数组(Array,其实也是对象)这倆好基友在那儿你嵌我我嵌你地套上n多层,以此模拟出许多复杂的数据结构。
json易于人阅读和编写,也易于机器解析和生成,相对网络传输速率较高,功能型网站前后端往往要频繁大量交换数据,而json凭借其强大的表现力和高颜值渐渐地成为理想的前后端数据交换语言。那xml前辈呢,我觉得应该会像微软的xp那样功成身退。
同源(不懂同源策略的童鞋请自行百度)下的前后端数据交换格式确定使用json了,那么问题来了,如果我想获取别人网站上提供的数据肿么做到呢?也就是跨域读取数据问题(不要钻牛角说你不需要读取其他网站的数据,相信我,你早晚得需要),json行不行呢?答案是No Way,为什么呢,因为json只是普通的文本格式,能让你这样就轻松拿到那服务端就没有任何安全和保密性可言了,这样的话互联网世界非乱套不可,这个问题那些牛X的规范制定者早就想到了,所以使用了同源策略来限制文件获取。最后的结果就是只有像img、script、iframe这类可以指定src属性的标签有跨域获取别人网站上数据(图片,脚本,源文件其实都是数据)的能力。比如:
<!--京东商品图片-->
<img src="http://img30.360buyimg.com/jgsq-productsoa/jfs/t2407/323/1635505465/47386/f2d89d88/56615e00N7a475ee6.jpg" />
<!--百度CDN-->
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
看来直接获取json是行不通了,那有没有其他方法能拿到数据呢?于是乎jsonp就这样被聪明的开发者给发现了,为什么说是发现而不是发明呢,因为并没有涉及到任何新技术,就像发现ajax一样。
jsonp原理是这样的,网站A需要获取网站B的数据,网站B说我给你们一个方法,【1. 你们使用<script src="http://www.B.com/open.js"></script>标签先获取到open.js文件(网站B的责任),这里边有你们需要的数据。2. 你们获取数据后处理数据(总得处理数据吧)的方法名必须命名为foo(数据请求者的责任和义务)】,这里相当于B网站和请求获取数据者之间建立了一个协议,要求请求者务必按照规则办事,如果请求者不能同时遵守上面两条就不能按预期获取数据。额..,这也算相当于建立了一个潜规则吧
open.js内容
foo({"name":"B","age":23}); //为什么不直接写成json数据{"name":"B","age":23}呢,原因很简单,在js文件总得合乎js语法吧
//这也是为什么协议中明确规定处理数据的方法名必须命名为foo,因为B网站是在假定请求者的脚本中已经定义了数据处理方法foo的情况下返回数据;
//不然就会报foo is not defined错误
网站A脚本须有
function foo(data){
console.log(data);
//ToDo..
}
啊!虽然拐了个弯,但数据总算得到了,网站A,网站B都非常高兴,那么问题又来了,网站C说也需要获取网站B的数据,网站B把协议甩给它,网站C拿过来一看,草泥马啊,foo这个名字已经在自己的脚本文件的6868行用过了,而且已经使用在脚本的各个角落,批量替换会导致很多潜在bug啊,网站B情急之下决定把foo改成fool,网站A立马蹦起来,因为自己的网站已经在很多地方使用foo引用了数据。
为了避免上面情况发生,那些牛X哄哄的开发者使用了动态生成js文件的方法,php版本如下:
open.php

<?php
header('Content-type: application/javascript');
$jsonCallback = htmlspecialchars($_REQUEST ['callback']); //获取请求者自定义的回调函数名
$jsonData ='{"name":"B","age":23}'; //待返回的json数据
echo $jsonCallback . "(" . $jsonData . ")"; //输出jsonp格式的数据,即一行函数调用语句
?>

额 ..,至于php为什么能返回js格式文件,自行百度。
于是网站A用<script src="http://www.B.com/open.php?callback=foo"></script>来请求数据,不需要修改任何变量,返回给A的脚本文件内容是:
foo({"name":"B","age":23}); //所谓的jsonp,就是一句函数调用,数据都被包裹传递到参数中了,千万别穿个马甲就不认识了
网站C就用<script src="http://www.B.com/open.php?callback=blah"></script>来请求数据,返回给C的脚本文件内容是:
blah({"name":"B","age":23});
网站N就用<script src="http://www.B.com/open.php?callback=what"></script>来请求数据,返回给N的脚本文件内容是:
what({"name":"B","age":23});
Problem Solved,大家都取到了期望的数据,并且避免了命名冲突。
jsonp全名叫做json with padding,很形象,就是把json对象用符合js语法的形式包裹起来以使其它网站可以请求得到,也就是将json数据封装成js文件;
json是理想的数据交换格式,但没办法跨域直接获取,于是就将json包裹(padding)在一个合法的js语句中作为js文件传过去。这就是json和jsonp的区别,json是想要的东西,jsonp是达到这个目的而普遍采用的一种方法,当然最终获得和处理的还是json。所以说json是目的,jsonp只是手段。json总会用到,而jsonp只有在跨域获取数据才会用到。
理解了json和jsonp的区别之后,其实ajax里的跨域获取数据就很好理解和实现了,同源时候并没有什么特别的,直接取就行,跨域时候需要拐个弯来达到目的。
附上jquery中ajax请求json数据实例:
(同源):

$.ajax({
url:"persons.json",
success:function(data){
console.log(data);
//ToDo..
}
});

(跨域)

$.ajax({
url:"http://www.B.com/open.php?callback=?",
dataType:"jsonp",
success:function(data){
console.log(data);
//ToDo..
}
});

jquery已把jsonp封装进ajax,很合理,因为毕竟绝大多数的jsonp请求都是ajax,关于jquery的ajax具体用法请自行百度,另外要注意的一点就是不同的网站提供的数据接口的$_REQUEST ['callback']中不一定绝对是callback也可能是cb,cbk等,具体使用时务必阅读服务端提供的有关接口使用的详细文档。
摘自:http://www.cnblogs.com/iovec/p/5312464.html
【转】json与jsonp区别浅析(json才是目的,jsonp只是手段)的更多相关文章
- json与jsonp区别浅析(json才是目的,jsonp只是手段)
一言以蔽之,json返回的是一串数据:而jsonp返回的是脚本代码(包含一个函数调用): JSON其实就是JavaScript中的一个对象,跟var obj={}在质上完全一样,只是在量上可以无限扩展 ...
- json与jsonp区别浅析(json才是目的,jsonp只是手段) (转)
一言以蔽之,json返回的是一串数据:而jsonp返回的是脚本代码(包含一个函数调用): JSON其实就是JavaScript中的一个对象,跟var obj={}在质上完全一样,只是在量上可以无限扩展 ...
- eval()和JSON.parse()的区别
我们将一个josn字符串解析为对象的时可以使用两种方法: 假设有一个json字符串: '{ "student" : [ {}, {}, {} ] }' 然后解析为对象: 1.eva ...
- PHP serialize 和 JSON 解析与区别
PHP serialize 和 JSON 解析与区别 对于JSON(JavaScript Object Notation)大家应该不陌生,它是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器 ...
- JSON对象获取指定元素以及JSON.parse() 与 JSON.stringify() 的区别
利用 JSON.parse(param) 实现 例: var param = { "name" : "张三", "text" : { &qu ...
- JSON和JSONP区别和联系
由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...
- 说说JSON和JSONP区别
前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socke ...
- js 对象 / json / jsonb / jsonp 区别
一.JSON vs JS 对象 1.区别 区别 Javascript 对象 Json 含义 对象的实例 一种数据格式(序列化格式) 传输 不能传输 可以跨平台传输,轻量级 格式 1.键不加引号.加单引 ...
- 说说JSON和JSONP,浅析JSONP解决AJAX跨域问题
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服 ...
随机推荐
- P1852 [国家集训队]跳跳棋
P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...
- Tomcat8.5 升级tomcat版本导致出现异常,Base64不存在
Tomcat8.5 升级tomcat版本导致出现异常,Base64不存在 原因分析: 由于tomcat由7升级到8.5导致Base64的引用路径错误,默认引用为8.5中的jar, 解决方案: 修改引用 ...
- 20145101《Java程序设计》第三周学习总结
20145101 <Java程序设计>第3周学习总结 教材学习内容总结 本周进行的是第四章和第五章的学习.本阶段的学习难度有所提升,无论是在知识的量还是深度都开始增加,内容很丰富,也很有趣 ...
- 20145105 《Java程序设计》实验四总结
实验四 Android开发基础 一.实验内容 基于Android Studio开发简单的Android应用并部署测试 了解Android组件.布局管理器的使用: 掌握Android中事件处理机制 二. ...
- C++使用Socket 邮箱登录服务器验证
转载:http://blog.csdn.net/zengraoli/article/details/36866241 转载:http://blog.csdn.net/alger_magic/artic ...
- 使用PopupWindow弹窗提醒
一.新建view.xml 注意里面的控件要一个一个的定义离上一个控件的距离,即margin_top,不然最后的效果是紧缩的 二.在java中定义两个变量 1.View view=null: 2.pop ...
- 分析redis key大小的几种方法
当redis被用作缓存时,有时我们希望了解key的大小分布,或者想知道哪些key占的空间比较大.本文提供了几种方法. 一. bigKeys 这是redis-cli自带的一个命令.对整个redis进行扫 ...
- redhat 7.2更新yum源时踩的坑
一.update yum .先查看redhat7.2中yum的包版本 [root@localhost jiayimeng]# rpm -qa | grep yum -.el7.noarch -.el7 ...
- C#学习笔记(十八):数据结构和泛型
数据结构 只有这四种 a.集合:数据之间没有特定的关系 b.线性结构:数据之间有一对一的前后联系 c.树形结构:数据之间有一对多的关系,一个父节点有多个子节点,一个子节点只能有一个父节点 d.图状结构 ...
- ZOJ 3869 Ace of Aces
There is a mysterious organization called Time-Space Administrative Bureau (TSAB) in the deep univer ...