JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

简单理解

利用<script>标签可以跨域,让服务器端返回可执行的Javascript函数,参数为要回发的数据。

像这样

<script>
    function foo(res) {
        console.log(res); // {name: "tom", age: 23}
    }
</script>
<script src="http://localhost:8080/test/demo.php?bar=foo"></script>

php代码

<?php
header('content-type: application/json');
$a = array('name'=>'tom','age'=>23);
echo $_GET['bar'].'('.json_encode($a).')';

下面以 $.ajax 的 jsonp 为例:

function foo(res) {
    console.log(res);
}
$.ajax({
    type: 'get',
    url: 'demo.php',
    dataType: 'jsonp',
    jsonp: 'bar', // jsonp参数名
    jsonpCallback: 'foo', // 自定义回调函数名称
    data: {"firstname": "tom"}
});

看下请求及返回结果

图片描述

不难看出,返回的是一个有实参的函数调用。

foo({"name":"tom","age":23})

而这个函数是已经在js里声明好的。

处理过程就是$.ajax动态创建script添加src,完事再删除一个过程。

另外不声明jsonpCallback函数,使用success也能拿到返回值。

$.ajax({
    type: 'get',
    url: 'demo.php',
    dataType: 'jsonp',
    jsonp: 'bar',
    jsonpCallback: 'foo',
    data: {"firstname": "tom"},
    success: function(res) {
        console.log(res);
    }
});
注意:因为jsonp是通过动态添加script标签,在src中添加查询参数callback,再利用js运行机制实现的,所以jsonp只适合GET请求。

附加一种后端的处理跨域的方式:

header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept');

如果request的Accept和response的Content-Type不匹配的话也会报错。


anchovy
1.9k 声望89 粉丝

« 上一篇
canvas事件