美文网首页
JSONP实现跨域请求的原理

JSONP实现跨域请求的原理

作者: 小龙虾Julian | 来源:发表于2018-08-27 09:14 被阅读0次
    1、什么事JSONP?同源策略?

    为了保证用户访问的安全,现代浏览器使用了同源策略(协议、域名、端口号不一致就不是同源策略),即不允许访问非同源的页面,在ajax请求中,不允许请求非同源的url,比如www.abc.com下的一个页面,其中的ajax请求是不允许访问www.cba.com/c.php这样一个页面的。

    2、JSONP的原理?

    ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。

    3、如果ajax请求跨域资源会怎么样呢?

    前端代码在域www.a.com下面,使用ajax发送了一个跨域的get请求,如下:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Ajax跨域请求的问题</title>
    </head>
    <body>
    <script type="text/javascript">
        function ajaxFucn(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(){
            $.ajax({
                type : "get",
                async: false,
                url : "http://www.b.com/data.php?id=1",
                type: "json",
                success : function(data) {
                    ajaxFucn(data);
                }
    
            });
        });
    </script>
    </body>
    </html>
    

    后端代码放在域www.b.com下,简单的输出一段json格式的数据,如下:

    ajaxFucn({
        "age" : 30,
        "name": "Ajax",
    })
    

    当运行代码之后会报错:提示了不同源的URL禁止访问

    4、接下来使用JSONP,将前端代码中的ajax请求去掉,添加了一个script标签,标签的src指向了另一个域www.b.com下的jsonp.js脚本,代码如下:
    <!DOCTYPE html>
    <html>
    <head>
    <title>JSONP实现跨域请求</title>
    </head>
    <body>
    <script type="text/javascript">
     function jsonpFunc(data){
            alert("age:" + data.age + "name:" + data.name);
    }
    </script>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript" src="http://www.b.com/jsonp.js"></script>
    </body>
    </html>
    

    这里调用了跨域的jsonp.js脚本,jsonp.js代码如下:

    jsonhandle({
        "age" : 30,
        "name": "JSONP",
    })
    

    结果:这段远程的js代码执行了上面定义的函数,弹出了提示框

    5、将前端代码再进行修改,代码如下:
    <!DOCTYPE html>
    <html>
    <head>
    <title>JSONP实现跨域请求</title>
    </head>
    <body>
    <script type="text/javascript">
    function jsonhandle(data){
            alert("age:" + data.age + "name:" + data.name);
    }
    </script>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            var url = "http://www.b.com/student.php?id=1&callback=jsonpFunc";
            var obj = $('<script><\/script>');
            obj.attr("src",url);
            $("body").append(obj);
        });
    </script>
    </body>
    </html>
    

    这里动态的添加了一个script标签,src指向跨域的一个php脚本,并且将上面的js函数名作为callback参数传入,PHP代码如下:

    <?php
    $data = array(
        'age' => 20,
        'name' => '张三',
    );
    
    $callback = $_GET['callback'];
    
    echo $callback."(".json_encode($data).")";
    return;
    

    PHP代码返回了一段JS语句,即:

    jsonpFunc({
        "age" : 30,
        "name": "JSONP",
    })
    

    此时访问页面时,动态添加了一个script标签,src指向PHP脚本,执行返回的JS代码,成功弹出提示框。
    所以JSONP将访问跨域请求变成了执行远程JS代码,服务端不再返回JSON格式的数据,而是返回了一段将JSON数据作为传入参数的函数执行代码。

    6、jQuery提供了方便使用JSONP的方式,代码如下:
    <!DOCTYPE html>
    <html>
    <head>
    <title>JSONP实现跨域请求</title>
    </head>
    <body>
    <script type="text/javascript" src="jquery.min.js">
    </script>
    <script type="text/javascript">
        $(document).ready(function(){
            $.ajax({
                type : "get",
                async: false,
                url : "http://www.b.com/student.php?id=1",
                dataType: "jsonp",
                jsonp:"callback", //请求php的参数名
                jsonpCallback: "jsonpFunc",//要执行的回调函数
                success : function(data) {
                    alert("age:" + data.age + "name:" + data.name);
                }
    
            });
        });
    </script>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:JSONP实现跨域请求的原理

          本文链接:https://www.haomeiwen.com/subject/lkeiiftx.html