概述:
跨域这个问题在工作偶尔能够碰到,但是一旦跨域传送数据就成了问题,所以就用到了JSONP,今天我们来聊聊JSONP。
什么是JSONP:
JSONP是一种为了解决跨域的数据交换问题,从而衍生出来的数据交换协议。
为什么会产生JSONP:
因为浏览器的“同源策略“,也就是浏览器限制脚本程序只能和同协议、同域名、同端口的脚本进行交互,但是在数据交换的过程中,经常会产生跨域的数据交换,所以人们想到了一个方法来解决这个问题, 原因是有一些标签是可以跨域执行的,跨域还能执行的标签例如img,script标签,以大家常用img标签为例,就算是别的网站的图片url在咱们的网站也是可以用的,script标签同理。
为什么不用AJAX:
如果是在本站内,我们用Ajax把数据提交给后台就可以了,但是如果不是在本站呢?跨域无权限访问的。例如,www.uw3c.com要直接传送数据给www.baidu.com是不可以的。
JSON和JSONP的关系:
没有半毛钱关系,JSON是一种数据格式而JSONP是一种跨域的数据交换协议,但是目前为止使用JSONP返回的数据格式最推荐使用JSON。
JSONP的原理:
动态的插入一个<script>标签,这个标签的src链接一个存有数据的、调用本地函数的JS脚本。
JSONP的具体实现方法:
(1) 刚刚已经说过了,JS脚本是可以跨域执行的,比如在页面中插入:
1
2
|
</script>
|
alert.js文件的代码如下:
1
2
3
4
|
function
Jsonp(){
alert(
"uw3c"
)
}
Jsonp();
|
那么就算是来自不同网站的JS文件,页面中也绝对会弹出提示框。
(2) 那么,如果我这个插入在页面中的外站的脚本(alert.js)是个调用函数的方法呢?
1
2
3
4
5
6
7
|
<script type=
"text/javascript"
>
function
Jsonp(){
alert(
"uw3c"
)
}
</script>
</script>
|
alert.js文件的代码如下:
1
|
Jsonp();
|
就相当于调用了本页面的"Jsonp()"方法。必然会在页面中弹出提示框"uw3c"。
(3) 那么,如果我通过外站的脚本(alert.js)往页面里面传个数据呢?
(3) 那么,如果我通过外站的脚本(alert.js)往页面里面传个数据呢?
1
2
3
4
5
6
7
|
<script type=
"text/javascript"
>
function
Jsonp(obj){
alert(obj)
}
</script>
</script>
|
alert.js文件的代码如下:
1
|
Jsonp(
"uw3c"
);
|
我通过外站脚本,调用页面中的“Jsonp”函数,并且传有实参(uw3c)。页面必然也会弹出提示框"uw3c"。 所以,我们就可以通过这种方法来给页面中传入外站的数据,这就是JSONP的基本原理。
但是,大家肯定会问了,这样的确是可以传送数据,但是每个函数的名称都不一样啊,要是给多个网站传数据岂不是也要写多个文件文件?
有点后台基础的同鞋肯定能想到,根据链接中传递的参数动态生成这个文件,用参数告诉后台这个函数叫什么名字不就行了吗:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script type=
"text/javascript"
>
//本地JS函数
var
uw3cJsonp =
function
(data){
alert(
'文章名称'
+ data.name +
'文章分类 '
+ data.type);
};
//提供jsonp服务的url地址,地址中带有参数(name,type),
//后台经过处理最终生成的返回值是一段javascript代码,
//js文件里面调用函数的名称是uw3cJsonp,
//后台通过参数type=js01,获取参数,然后到数据库中查找,然后返回,
//从而生成了名称为uw3cJsonp,里面带数据的JS调用文件。
//创建script标签,设置其属性
var
script = document.createElement(
'script'
);
script.setAttribute(
'src'
, url);
//把script标签加入head,此时调用开始
document.getElementsByTagName(
'head'
)[0].appendChild(script);
</script>
|
说到这里,应该能理解JSONP的原理了吧,但是有些同鞋平日过度依赖jQuery,看JS有点费劲,那怎么办?
事实证明jQuery的确是个值得依赖的插件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<script type=
"text/javascript"
>
$.ajax({
type:
"get"
,
async:
false
,
dataType:
"jsonp"
,
//传递给请求处理程序或页面的,
//用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonp:
"callback"
,
//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,
//也可以写"?",jQuery会自动为你处理数据
jsonpCallback:
"uw3cJsonp"
,
success:
function
(json){
alert(
'文章名称'
+ data.name +
'文章分类 '
+ data.type);
},
error:
function
(){
alert(
'传送数据失败'
);
}
});
</script>
|
大家注意到了吗,我在AJAX的参数url中并没有写JS函数的名称uw3cJsonp,这是应为jQuery自动给生成了,怎么样,爽吧!
但是大家注意,在jQuery封装的JSONP中,type只能为"get"。
JSONP与AJAX的区别:
虽然jQuery把JSONP封装到了AJAX中,但是
JSONP跟AJAX根本不是一回事。 AJAX的是通过XmlHttpRequest获取非本页内容,但是JSONP是通过动态插入script标签用JS获取数据,是有本质区别的。
好了,以上就是本片文章的全部内容,希望可以让大家充分的理解JSONP的功能和原理,以及和AJAX的区别。
源引:http://www.uw3c.com/jsviews/js03.html