解决跨域问题,就一定会说JSONP方法。JSONP到底是怎么实现的,一起看一下。
先制造一个跨域的情况,我是用Hbuilder新建一个html文件,然后点击上方的浏览器logo就可以在浏览器中打开了,Hbuilder回自己启动一个服务。然后要创建一个接口,我用的是php。我的电脑上有phpStudy,会有一个php的继承环境,只要启动phpStudy它也会启动一个服务。这两个服务的地址是不一样的,所以就会出现跨域的情况。
我的html页面如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script src="http://192.168.0.73/php/test.php?callback=jsonp"></script>
<script>
function jsonp(data){
console.log(data)
}
</script>
</body>
</html>
就是用script标签的src去请求一个接口(http://192.168.0.73/php/test.php
)。然后在接口的后面的加上一个参数callBack=jsonp
。所以拼接后就如上面的代码。
然后是php的代码
<?php
$callBack = $_GET['callback']; // 1.获取参数
$json = "{\"name\":\"zhangsan\"}"; // 2.定义一个json
echo $callBack . "(" . $json . ")"; // 3.返回数据
php的逻辑是这样的:
- 获取我们请求的参数callback,因为
callback=jsonp
, 所以参数值是jsonp
。 - 定义一个json数据。
- 拼接第一步获得的参数值和第二部不定义的json,其实这时候就相当于拼接成了
jsonp({"name":"zhangsan"})
。然后在用echo
将它返回给客户端。
客户端拿到请求结果后逻辑是这样的:
- script标签拿到结果
jsonp({"name":"zhangsan"})
。 - 因为是script标签,所以会把请求拿到的东西看成一个js文件。
- 既然是js文件,那么拿到后肯定会执行。
- 我们的结果是
jsonp({"name":"zhangsan"})
, 这不就是一个函数名为jsonp的函数调用吗,还传了参数。 - 既然是函数执行,就回去作用域寻找这个函数,结果就是我们预先定义好的函数jsonp啊。
- jsonp函数执行了,我们就可以在这个函数中处理我们的数据了。
所以总结来说,JSONP方法跨域就是相当于script标签去请求一个js文件,请求完成执行js。而这个js文件的内容就是后台拼接的一个函数调用语句jsonp({"name":"zhangsan"})
,并且函数的参数是直接将值放在函数括号里的(这里是一个json)。这里的函数就是我们之前定义好的一个全局函数。