在学习面试题Jsonp劫持漏洞时,不太懂Jsonp,所以学习了一下Jsonp,记录一下我自己理解Jsonp的跨域请求

什么是Jsonp?

在我们使用Ajax请求普通文件时不同域数据是没有权限访问的

其实有几个标签是可以跨域访问的,例如:<img> <script> <frame>,比如我们引用js文件时就可以跨域请求访问

其实Jsonp很好理解,如果客户端需要跨域访问服务端数据,我们可以在服务端将数据装入js格式文件里,供客户端进行调用

所以Jsonp需要客户端和服务端的配合,两者缺一不可

Jsonp客户端实现

1
2
3
4
5
6
<script>
function callback(result){
alert(result.name);
}
</script>
<script src="http://study.io/index.php?jsoncallback=callback"></script>

http://study.io/index.php?jsoncallback=callback 我们通过传入参数形式,将我们客户端的回调函数名请求发送给服务端,这样服务端就可以根据客户端的函数名封装数据成js格式的文件供客户端调用

Jsonp服务端实现

1
2
3
4
5
6
7
8
<?php 
header("Content-type: application/json");

$jsoncallback = $_GET['jsoncallback'];

$json_data = '{"id":1,"name":"hello"}';

echo $jsoncallback . "(" . $json_data . ")";

服务端的 echo $jsoncallback . "(" . $json_data . ")"; 执行结果就是
callback({"id":1,"name":"hello"}) 成功的将数据装入js格式文件里供客户端调用

callback({"id":1,"name":"hello"}) 其实就是一个函数,里面有参数 {"id":1,"name":"hello"}

Jsonp客户端调用

1
2
3
function callback(result){
alert(result.name);
}

客户端调用回调函数时,result 就是js格式化后文件里面的 {"id":1,"name":"hello"}

此时浏览器将弹出对话框输出了 hello,成功跨域请求获取数据

如果想让Ajax支持跨域请求,我们可以在Ajax中加入参数 dataType: "jsonp" 即可