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保留字.关键字详解 来自橙子,万一的博客以及其他地方 保留字:变量等标识符可以再使用: 关键字:有特定含义,不能再次重新定义: 修饰字:类似保留字的功能,也就是说可以重用 ...
随机推荐
- [POI2013]Usuwanka
[POI2013]Usuwanka 题目大意: 一排\(n\)个球,有黑白两种颜色.每取走一个球会在原位置放一个水晶球.求构造一种取球方案,满足: 每次取走\(k\)个白球和\(1\)个黑球: 一次取 ...
- hdu 5195 线段树
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABIgAAABeCAIAAADHZri1AAATWklEQVR4nO3dvU4jTRaA4b2nvgNzBw
- JAVA泛型中的有界类型(extends super)(转)
JDK1.5中引入了泛型(Generic)机制.泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Ja ...
- wap2.0开发
前言 移动通信和互联网的迅速发展,使得互联网从固定向移动转移(即移动互联网)成为一种必然的趋势.由于手机终端本身的限制条件和无线链路的特点,现有无线传送技术的效率和可靠性会越来越难以令用户满意.如何让 ...
- c#调用刀片小票打印机
public static bool Print(int orderId, string orderTime) { bool b = true; string cut = ((char)29).ToS ...
- [译] Go 并发编程基础
原文:Fundamentals of concurrent programming 译者:youngsterxyf 本文是一篇并发编程方面的入门文章,以Go语言编写示例代码,内容涵盖: 运行期并发线程 ...
- TVB三个台
翡翠台http://token.tvb.com/stream/live/hls/mobilehd_jade.smil 高清翡翠,http://token.tvb.com/stream/live/hls ...
- 什么时候用var关键字
C#关键字是伴随这.NET 3.5以后,伴随着匿名函数.LINQ而来, 由编译器帮我们推断具体的类型.总体来说,当一个变量是局部变量(不包括类级别的变量),并且在声明的时候初始化,是使用var关键字的 ...
- SQL Server 2008 安装教程
http://www.downcc.com/tech/4135.html 序列号:Developer: PTTFM-X467G-P7RH2-3Q6CG-4DMYB
- 教你调用数据库读取短信 记事本 通讯录文件,让ios5的短信恢复到ios4
由于高版本的ios固件向下恢复到低版固件时无法通过itunes恢复备份,所以一些数据,比如SMS需要通过提取文件的方式单独进行备份恢复特别是ios5的短信,之前很是头痛,直接将文件恢复到指定目录修改权 ...