jsonp跨域请求原理

责编:menVScode 2018-01-16 22:38 阅读(811)

        JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。

        下表给出了相对http://store.company.com/dir/page.html同源检测的结果:

15184525-747de461b3b14f938b443e72ea25b25a

        jsonp原理

        在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。

        而JSONP就是通过script节点src调用跨域的请求。

        当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用客户端回调函数。

        利用在页面中创建<script>节点的方法向不同域提交HTTP请求的方法称为JSONP,这项技术可以解决跨域提交Ajax请求的问题。

        比如,有个a.html页面,它里面的代码需要利用ajax获取一个不同域上的json数据,假设这个json数据地址是 http://example.com/data.php,那么a.html中的代码就可以这样:

<script>
  function dosomething( jsondata ){
    //处理获得的json数据
  }
</script>
<script src="http://example.com/data.php?callback=dosomething"></script>

        我们看到获取数据的地址后面还有一个callback参数,按惯例是用这个参数名,但是你用其他的也一样。当然如果获取数据的jsonp地址页面不是你自己能控制的,就得按照提供数据的那一方的规定格式来操作了。

        script标签的src指向跨域的一个php脚本,并且将上面的js函数名作为callback参数传入,所以这个页面的php代码可能是这样的:

<?php
  $callback = $_GET['callback']; //得到回调函数名
  $data = array( 'a','b','c'); //要返回的数据
  echo $callback.'('.json_encode().')'; //晒出
?>

        最终那个页面输出的结果是:

dosomething( ['a','b','c'] )

        这样jsonp的原理就很清楚了,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。

        知道jsonp跨域的原理后我们就可以用js动态生成script标签来进行跨域操作了,而不用特意的手动的书写那些script标签。如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。

<!DOCTYPE html>
<html>
<head><title>GoJSONP</title></head>
<body>
<script type="text/javascript">
    function jsonhandle(data){
        alert("age:" + data.age + "name:" + data.name);
    }
</script>
<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        var url = "http://www.practice-zhao.com/student.php?id=1&callback=jsonhandle";
        var obj = $('<script><\/script>');
        obj.attr("src",url);
        $("body").append(obj);
    });
</script>
</body>
</html>

        最后jQuery提供了方便使用JSONP的方式,代码如下:

!DOCTYPE html>
<html>
<head><title>GoJSONP</title></head>
<body>
<script type="text/javascript" src="jquery-1.8.3.min.js">
</script>
<script type="text/javascript">
    $(document).ready(function(){
        $.ajax({
            type : "get",
            async: false,
            url : "http://www.practice-zhao.com/student.php?id=1",
            dataType: "jsonp",
            jsonp:"callback", //请求php的参数名
            jsonpCallback: "jsonhandle",//要执行的回调函数
            success : function(data) {
                alert("age:" + data.age + "name:" + data.name);
            }

        });
    });
</script>
</body>
</html>

        或者那么通过jquery封装的方法就能很方便的来进行jsonp操作了;

<script>
  $.getJSON('http://example.com/data.php?callback=?',function(){
    //处理获取到的json数据
  })
</script>

        原理是一样的,只不过我们不需要手动的插入script标签以及定义回掉函数。jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

        jsonp的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

标签: jsonp 跨域
前端交流群: MVC前端网(menvscode.com)-qq交流群:551903636

邮箱快速注册

忘记密码