JsonP的就是JSON Padding的缩写,它的原理也是非常简单的,利用了script标签的src属性可以链接任何域下的文件的方法,来链接服务器端的一个代理,从而实现了跨域调用数据的方式,下面是它的一个简单的应用:
[javascript]
//首先编写一个用于执行的方法体,这个方法就是将要在服务器端的代理输出执行的函数
//obj就是获取的跨域数据
<script type="text/javascript">
var callback = function(obj){
document.getElementById("div").innerHTML = obj.message;
}
</script>
//接下来就需要再声明一个script标签,将它的src属性链接到异域名的代理来获取数据
<script type="text/javascript" src="http://www.ilovejs.net/lab/test.php?method=callback"></script>
[/javascript]
上面提及的代理就是test.php文件,它的代码就是生成Javascript格式的执行函数命令:
[php]
<?php
$method=$_GET["method"];
echo($method."({message:’message come from server www.ilovejs.net’});");
?>
[/php]
上面就是一个简单的JsonP的应用例子,不过值得说明的是,因为已经把链接到代理的script标签静态的声明了,所以它只能是随页面加载的时候获取异域数据,想要重新获取数据,只能是刷新页面,这个是上面那种方式的其中的一个缺点。要解决这个问题的方法就是动态生成链接到代理的script标签,这样就可以实现局部刷新获取数据,不过这里也有一个小问题,就是动态生成的这个script标签,需要在下次用户重复局部刷新这个异域获取数据的组件的时候能及时的remove掉,否则head就会囤积了很多丢弃的script标签,造成性能问题。下面是这种方式的实现方式:
[javascript]
//将要执行的函数
var callMethod = function(obj){
document.getElementById("div").innerHTML = obj.message;
}
var getJSONP = function(data, callback){
var script = document.getElementById("jsonp");
var head = document.getElementsByTagName("head")[0];
//如果已经存在了id为jsonp的script标签,先remove掉,这一步非常重要
if (script) {
head.removeChild(script);
}
script = document.createElement("script");
script.type = "text/javascript";
script.id = "jsonp";
//在参数中传递客户端的数据以及将要执行的函数名,再加一个时间戳,可以解除浏览器缓存问题
script.src = "http://www.ilovejs.net/lab/test.php?method=callMethod&jsonp=" + data + "&date=" + new Date().getTime();
head.appendChild(script);
script.onload = function(){
callback(script);
}
script.onreadystatechange = function(){
if (this.readyState == ‘loaded’) {
callback(script);
}
}
}
[/javascript]
上面展示的代码基本说明了JsonP的基本原理和实现方式,更多利用JsonP实现跨域的复杂的操作都是基于这些基础原理的。