JavaScript的跨域的跨域问题,是众多新手首要遇见的问题。网上解决跨域的方案有很多,本文就前面我写过的《JavaScript简单模拟HTTP请求比Ajax方便》延伸到JSONP跨域方案。
JSONP原理
为什么叫JSONP呢?其实这种跨域实现方式跟JSON一点关系也没有,所以不要局限于这种跨域方式一定跟JSON有关系。JSONP实现的原理是通过<script>
标签的src跨域访问,被访问页把最终结果通过回调本地一个JavaScript函数从而达到跨域功能。然而从正常的表面上看,也可以当作是包含一个JavaScript文件,只不过这个JavaScript文件是主要用来传输数据而已。
DEMO
本地JavaScript通过<script>
请求一个某IP上的一个PHP文件,PHP文件通过date()函数获取当前的服务器时间并通过调用本地的JavaScript函数call_date()
接收到服务器传回的值,从而实现JSONP跨域请求。
JavaScript代码
/**
* JSONP跨域请求
* 琼台博客 www.qttc.net
*/
//json.php处理回调函数
function call_date(data){
alert(data);
}
//发起jsonp请求函数
function get(){
var o = document.createElement("script");
o.src="http://192.168.5.149/jsonp.php";
o.type="text/javascript";
document.body.appendChild(o);
}
json.php
/**
* JSONP处理回调页面
* 琼台博客 www.qttc.net
*/
$date = '当前服务器时间:'.date('Y-m-d H:i:s').' | 琼台博客';
// 调用请求源JS函数call_date
echo 'call_date("'.$date.'");';
// Output: call_date("当前服务器时间:2012-08-29 09:55:15 | 琼台博客");
json.php只是输出了一行JavaScript代码,调用call_date函数,并且传入一个字符串。于是我们在本地请求json.php页面的时候会调用call_date()函数。
测试
我们通过本地发起get()请求http://192.168.5.149/jsonp.php页面,jsonp.php处理结果通过call_date回调回来。
没有请求之前
请求之后
多出的这一段正是点击按钮请求以后被填充到页面的,并且在不刷新的情况下点击一次就填充一个,但不影响页面的正常功能。
从执行结果来看,jsonp.php页面回调的call_date()
函数已经成功并且返回相关数据,而call_date()
函数里的alert()
已经把结果弹出来。这样就实现了一个简单的jsonp跨域请求。
也可以返回JSON格式
既然是json是目前异步请求里使用最多的数据格式,我们在以上DEMO的基础上,实现json数据的回传。
jsonp.php
/**
* JSONP处理回调页面
* 琼台博客 www.qttc.net
*/
// 声明一个空数组
$arr = array();
// 把处理结果放入数组里
$arr['msg'] = $date = '这是使用json格式传回的数据:当前服务器时间:'.date('Y-m-d H:i:s').' | 琼台博客';
// 数组转换json格式
$json = json_encode($arr);
// 调用请求源JS函数call_date
echo 'call_date('.$json.');';
JavaScript代码
/**
* JSONP跨域请求
* 琼台博客 www.qttc.net
*/
//json.php处理回调函数
function call_date(data){
alert(data.msg);
}
//发起jsonp请求函数
function get(){
var o = document.createElement("script");
o.src="http://192.168.5.149/jsonp.php";
o.type="text/javascript";
document.body.appendChild(o);
}
看看执行结果
测试通过,结果正常获取到json数据。
注意
- 这种方式只能GET
- 处理页面最好是保证安全,否则容易被人利用漏洞
- 不能跟Ajax做比较