JSONP是干嘛的
提到JSONP,首先想到的就是AJAX,因为人们时常将它们放在一起说。那么,它们到底是什么关系呢?
其实它们本身并没有实质的关系,只是JSONP可以解决AJAX一件办不到的事情。哪件事情是AJAX办不到的?就是跨域!
简单来说,JSONP就是一种跨域的手段。
跨域:意思是说,在当前网址去获取另一个域下的数据。浏览器有一个“同源策略”——两个页面的域名必须在同域的情况下,才能允许通信。
所谓同源是指,域名,协议,端口相同。
浏览器的“同源策略”有效地阻止了很多危险行为,因为在没有“同源策略”的情况下,网站的信息可以被所有人任意获取,那么用户的隐私就受不到保护了,这是很可怕的。但事情有利有弊,“同源策略”也带来了麻烦,这时如果我们想从信任的网站获取数据,显然也做不到了。
JSONP怎么用
可能JSONP听起来很高大上,但其实其原理很简单,是我们每天都接触的。”同源策略”虽然很厉害,阻止了一个页面到另一个页面的通信,可是src指向的路径它放过了。提到src,我们再熟悉不过了,<img>
、<script>
和<iframe>
都有src属性。JSONP就是利用<script>
标签来实现跨域通信的。
讲一个简单的小例子:
现在假设有两个域,需要互相通信,分别是:www.aaa.com
和www.bbb.com
www.aaa.com
中:1
2
3
4
5
6
7
8<script src='http://www.bbb.com/abc.js'></script>
<script>
function abc(data){
alert(data['name']);
}
</script>
www.bbb.com/abc.js
中:1
abc({'name':'wungjyan','age':23});
结果页面弹出了wungjyan
。
JSONP工作过程:通过<script>
标签,获取到www.bbb.com/abc.js
,里面有一个函数abc
,函数会被加载到www.aaa.com
。加载完成后,就执行abc
函数,而在www.aaa.com
中已经定义好了一个abc
函数,函数里写了一些处理数据的语句。这样就简单地实现了跨域访问数据了,这也就是JSONP的原理了。
JSONP实例
运用JSONP做一个类似百度搜索下拉框。
在这之前,先取到百度的接口。
打开百度首页,在输入框随便输入点什么,比如,输入a,
打开Network,点击all,找到地址
这个地址是:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&json=1&p=3&sid=23534_1436_21084&req=2&csor=1&cb=jQuery110206731850454839907_1506167060552&_=1506167060555
只取本次实例需要的参数,精简为:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=jQuery110206731850454839907_1506167060552&_=1506167060555
其中wd是关键字,即输入的内容,cb是回调函数,百度内定的,cb后面的是函数名,可以修改,相当于上面小例子中的abc
函数。
现在就修改为abc,并输入到浏览器地址栏中,看看得到什么内容:
可以看到,这个abc函数里的参数是一个json数据,其中s就是我们需要的数据。
完整代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>百度下拉菜单</title>
<style type="text/css">
#text{
width: 300px;
height: 30px;
border:1px solid #6495ED;
line-height: 30px;
font-size: 16px;
}
#ul1{
margin: 0;
padding:0;
border:1px solid #6495ED;
border-top: none;
width: 300px;
display: none;
}
#ul1 li{
list-style: none;
margin-top: 5px;
}
#ul1 li a{
font-size: 16px;
color: #696969;
text-decoration: none;
}
</style>
</head>
<body>
<input type="text" id="text">
<ul id="ul1">
</ul>
<script>
//定义abc函数,添加数据处理程序
function abc(data){
var oUl=document.getElementById('ul1');
var html='';
if (data.s.length) {
oUl.style.display='block';
for(var i=0;i<data.s.length;i++){
html+="<li><a target='_blank' href='https://www.baidu.com/s?wd="+data.s[i]+"'>"+data.s[i]+"</a></li>";
}
oUl.innerHTML=html;
}else{
oUl.style.display='none';
}
}
var oT=document.getElementById('text');
var oBtn=document.getElementById('btn');
var oUl=document.getElementById('ul1');
oT.onkeyup=function(){
if (oT.value!='') {
var aScript=document.createElement('script');
aScript.src='https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd='+oT.value+'&cb=abc';
document.body.appendChild(aScript);
if(aScript){ //避免过多script标签
document.body.removeChild(aScript);
}
}else{
oUl.style.display='none';
}
}
</script>
</body>
</html>
代码中,动态添加<script>
标签,加载完成后就执行abc
函数,使获取到的数据展示在页面中。