Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别
为什么要用jsonp?
相信大家对跨域一定不陌生,对同源策略也同样熟悉。什么,你没听过?没关系,既然是深入浅出,那就从头说起。
假如我写了个index页面,页面里有个请求,请求的是一个json数据(不知道json数据的猛戳JSON简介以及用法汇总),简单思考写下如下代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<script type="text/javascript"> $.ajax({ dataType: "json", success: function (data) { console.log(data); } })</script> { "name": "hanzichi", "age": 10} |
楼主把两个文件都放在wamp下的www文件夹下,ajax请求没有跨域,完美得到结果:

但是如果我的json文件和index文件不在一个域下,即跨域(不懂跨域的可参考JavaScript 的同源策略)了呢?
试着在wamp下新开个apache端口(不知道怎么开的可参考WampServer下使用多端口访问),将json文件放到该服务端口的文件夹下(楼主设置的端口号为8080,默认的是80端口),试着发送请求:
|
1
2
3
4
5
6
7
8
9
10
|
<script type="text/javascript"> $.ajax({ dataType: "json", success: function (data) { console.log(data); } })</script> |

很显然,提示跨域了!怎么搞?这时jsonp就要出马了!
神奇的script标签
与jsonp息息相关的是script标签,而xhr或者说传统意义上的ajax与之没有半毛钱关系!
接着看上面的index.html代码,我们看到页面引用了百度cdn的jquery路径,对于这样的方式我们似乎已经习以为常,但是仔细一想,script标签可是完完全全的跨域的啊...没错,jsonp的实现核心就是利用script标签的跨域能力!于是我们灵机一动,似乎可以这么搞,动态生成一个script标签,把json的url赋值给script的src属性,然后再把这个script标签插入dom里...
|
1
2
3
4
5
6
7
8
|
<body> <script type="text/javascript"> var s = document.createElement('script'); document.body.appendChild(s); </script></body> |
我们创建了一个script标签,而标签内包裹的内容正是需要的json数据,但是报错如下:

原因是因为json数据并不是合法的js语句,把上面的json数据放在一个回调函数中是最简单的方法:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<body> <script type="text/javascript"> function jsonpcallback(json) { console.log(json); } var s = document.createElement('script'); document.body.appendChild(s); </script></body> jsonpcallback({ "name": "hanzichi", "age": 10}); |

当然,这时的a.json文件并不一定要这样命名,改成a.js也不会有一点问题。
而如果是与服务端交互也是一样的道理,比如和php:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<body> <script type="text/javascript"> function jsonpcallback(json) { console.log(json); } var s = document.createElement('script'); document.body.appendChild(s); </script></body> <?php $jsondata = '{ "name": "hanzichi", "age": 10 }'; echo $_GET['callback'].'('.$jsondata.')';?> |
需要注意的是,jsonp提供的url(即动态生成的script标签的src),无论看上去是什么形式,最终生成返回的都是一段js代码。
JQuery对jsonp的封装
为了便于开发,jq对jsonp也进行了封装,封装在了ajax方法中。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<script type="text/javascript"> $.ajax({ dataType: 'jsonp', jsonpCallback: 'CallBack', success: function (data) { console.log(data); } });</script> CallBack({ "name": "hanzichi", "age": 10}); |
以上代码是针对请求文件中写死了callback函数名的情况。因为请求的是json文件,json不是服务器端的动态语言不能进行解析,如果是php或者其他的服务器端语言,则不用写死函数名,比如下面这样:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script type="text/javascript"> $.ajax({ dataType: 'jsonp', success: function (data) { console.log(data); } });</script> <?php $jsondata = '{ "name": "hanzichi", "age": 10 }'; echo $_GET['callback'].'('.$jsondata.')';?> |
当然类似的封装好的方法还有几种:
|
1
2
3
4
5
6
7
8
|
// 1 console.log(data);});// 2 console.log(data);}, 'jsonp'); |
需要注意的是getJSON方法的请求地址url需要带上callback=?,因为jq对该方法进行封装的时候并没有默认回调函数变量名为callback,于是php中$_GET['callback']就找不到变量值了。
而一般的jq方法url 中不用指定 callback 参数。对于 jQuery 中的 jsonp 来说,callback 参数是自动添加的。默认情况下,jQuery 生成的 jsonp 请求中 callback 参数是形如 callback=jQuery200023559735575690866_1434954892929 这种根据看似随机的名字,对应的就是 success 那个处理函数,所以一般不用特意处理。二如果要写死callback名的话,可以参照上文。

总结
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求,这就是jsonp的核心。
jsonp原理:
1.首先在客户端注册一个callback, 然后把callback的名字传给服务器。
2.服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
3.客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
json和jsonp的区别,ajax和jsonp的区别
json和jsonp虽然只有一个字母的区别,但是它们之间扯不上关系。
json是一种轻量级的数据交换格式。
jsonp是一种跨域数据交互协议。
json的优点:(1)基于纯文本传递极其简单,(2)轻量级数据格式适合互联网传递,(3)容易编写和解析。
ajax和jsonp的区别:
相同点:都是请求一个url
不同点:ajax的核心是通过xmlHttpRequest获取内容
jsonp的核心则是动态添加<script>标签来调用服务器 提供的js脚本。
Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别的更多相关文章
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- python关键字详解
今天依旧在啃:<笨方法学python>,其中习题37是复习各种关键字.我本想百度一下记一下就ok了,但是百度出来第一个就Hongten的博客.我才意识到我也有博客,我应该学习他,把这些积累 ...
- Java面试题04-final关键字详解
Java面试题04-final关键字详解 本篇博客将会讨论java中final关键字的含义,以及final用在什么地方,感觉看书总会有一些模糊,而且解释的不是很清楚,在此做个总结,以备准备面试的时候查 ...
- Objective-C 实用关键字详解1「面试、工作」看我就 🐒 了 ^_^.
在写项目 或 阅读别人的代码(一些优秀的源码)中,总能发现一些常见的关键字,随着编程经验的积累大部分还是知道是什么意思 的. 相信很多开发者跟我当初一样,只是基本的常用关键字定义属性会使用,但在关键字 ...
- java continue break 关键字 详解 区别 用法 标记 标签 使用 示例 联系
本文关键词: java continue break 关键字 详解 区别 用法 标记 标签 使用 示例 联系 跳出循环 带标签的continue和break 嵌套循环 深入continue ...
- mysql中文、英文别名排序问题,order by 关键字详解
order by 关键字详解: SELECT intcode AS 商品编码, product_title AS 名称, retailprice AS 零售价, purchaseprice AS ...
- Java多线程(三)—— synchronized关键字详解
一.多线程的同步 1.为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资 ...
- java关键字详解----static
Java Static关键字详解 提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... ...
- Delphi、Lazarus保留字、关键字详解
Delphi.Lazarus保留字.关键字详解 来自橙子,万一的博客以及其他地方 保留字:变量等标识符可以再使用: 关键字:有特定含义,不能再次重新定义: 修饰字:类似保留字的功能,也就是说可以重用 ...
随机推荐
- JAVA线程和进程区别
1,JAVA线程和进程区别? (1)简单来讲一个运行的程序就是一个进程,一个进程中可以有多个线程(线程是程序执行的最小单元). (2)线程有四种状态:运行,就绪,挂起,结束 (3)使用多线程的好处 使 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation 动态规划
E. Goods transportation 题目连接: http://codeforces.com/contest/724/problem/E Description There are n ci ...
- JDK 动态代理的简单理解
动态代理 代理模式是 Java 中的常用设计模式,代理类通过调用被代理类的相关方法,提供预处理.过滤.事后处理等服务,动态代理及通过反射机制动态实现代理机制.JDK 中的 java.lang.refl ...
- LinkedIn实时低延迟数据抓取系统Databus开源
http://www.infoq.com/cn/news/2013/03/linkedin-databus
- 【精选】Jupyter Notebooks里的TensorFlow图可视化
[精选]Jupyter Notebooks里的TensorFlow图可视化 https://mp.weixin.qq.com/s?src=11×tamp=1503060682&a ...
- perl数组高级
1 去除一个数组中的重复元素: 使用grep函数代码片段: 代码: my @array = ( 'a', 'b', 'c', 'a', 'd', 1, 2, 5, 1, 5 ); my %count; ...
- 体验h5离线缓存
摘要 Application Cache是浏览器自己的一种机制,随着移动互联网时代的到来,如果我们已经将需要的文件缓存下下来,一旦网络无法访问,也能继续访问.不仅能提高用户体验,而且在有网络时,也能直 ...
- [vs2013]远程服务器调试
摘要 有时遇到比较奇葩的问题,比如本地程序正常运行,在服务器上不可以,如果日志也不起作用,那么远程调试就非常必要了,在服务器上安装vs,是比较费力费时的. 步骤 1.找到vs安装目录,一般默认安装在c ...
- iOS内存管理策略和实践
转:http://www.cocoachina.com/applenews/devnews/2013/1126/7418.html 内存管理策略(memory Management Policy) N ...
- Netty Pipeline、channel、Context之间的数据流向
以下所绘制图形均基于Netty4.0.28版本. 一.connect(outbound类型事件) 当用户调用channel的connect时,会发起一个outbound类型的事件,该事件将在pipe ...