从简单HTTP请求延伸到JSONP跨域

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回调回来。

没有请求之前

full

请求之后

full

多出的这一段正是点击按钮请求以后被填充到页面的,并且在不刷新的情况下点击一次就填充一个,但不影响页面的正常功能。

从执行结果来看,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);       
}

看看执行结果

full

测试通过,结果正常获取到json数据。

注意

  • 这种方式只能GET
  • 处理页面最好是保证安全,否则容易被人利用漏洞
  • 不能跟Ajax做比较
分享

TITLE: 从简单HTTP请求延伸到JSONP跨域

LINK: https://www.qttc.net/197-javascript-domain-cross-jsonp.html

NOTE: 原创内容,转载请注明出自琼台博客