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函数,使获取到的数据展示在页面中。