最近更新
阅读排行
读过本文章的之前读了
关注本站

解决跨域问题,聊聊JSONP

阅读:9477 次   编辑日期:2013-11-08

目录:

概述:

跨域这个问题在工作偶尔能够碰到,但是一旦跨域传送数据就成了问题,所以就用到了JSONP,今天我们来聊聊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脚本是可以跨域执行的,比如在页面中插入:
	<script type="text/javascript" src="http://www.pp.com/alert.js">
    </script>
alert.js文件的代码如下:
	function Jsonp(){
		 alert("uw3c")
	}
	Jsonp();
那么就算是来自不同网站的JS文件,页面中也绝对会弹出提示框。
(2) 那么,如果我这个插入在页面中的外站的脚本(alert.js)是个调用函数的方法呢?
	<script type="text/javascript">
		 function Jsonp(){
			 alert("uw3c")
		}
	</script>
	<script type="text/javascript" src="http://www.pp.com/alert.js">
    </script>
alert.js文件的代码如下:
	Jsonp();
就相当于调用了本页面的"Jsonp()"方法。必然会在页面中弹出提示框"uw3c"。
(3) 那么,如果我通过外站的脚本(alert.js)往页面里面传个数据呢?
	<script type="text/javascript">
		 function Jsonp(obj){
			 alert(obj)
		}
	</script>
	<script type="text/javascript" src="http://www.pp.com/alert.js">
    </script>
alert.js文件的代码如下:
	Jsonp("uw3c");
我通过外站脚本,调用页面中的“Jsonp”函数,并且传有实参(uw3c)。页面必然也会弹出提示框"uw3c"。 所以,我们就可以通过这种方法来给页面中传入外站的数据,这就是JSONP的基本原理。
但是,大家肯定会问了,这样的确是可以传送数据,但是每个函数的名称都不一样啊,要是给多个网站传数据岂不是也要写多个文件文件?
有点后台基础的同鞋肯定能想到,根据链接中传递的参数动态生成这个文件,用参数告诉后台这个函数叫什么名字不就行了吗:
	<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调用文件。
		var url = "http://www.pp.com/Jsonp.php?name=uw3cJsonp&type=js01";
		//创建script标签,设置其属性
		var script = document.createElement('script');
		script.setAttribute('src', url);
		//把script标签加入head,此时调用开始
		document.getElementsByTagName('head')[0].appendChild(script);
    </script>
说到这里,应该能理解JSONP的原理了吧,但是有些同鞋平日过度依赖jQuery,看JS有点费劲,那怎么办?
事实证明jQuery的确是个值得依赖的插件:
	<script type="text/javascript">
		$.ajax({
             type: "get",
             async: false,
             url: "http://www.pp.com/Jsonp.php?type=js01",
             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的区别。
将本篇文章分享到:
top