阿喆的博客空间 > 技术分享 > javascript >

jsonp跨域

 作者:阿喆 时间:2018-08-03

    工作中我们经常会请求其他域下的资源(因为同源策略),这个时候就遇到了跨域(协议,端口,域名任何一个不同就算是跨域)。解决跨域的一种常用办法就是jsonp,虽然他有局限性(只支持get请求),不过优点是兼容老式浏览器(不过现在好像很少有人在意老式浏览器了)。jsonp的基本原理:就是通过动态创建script标签,script标签的src是没有跨域限制的(可以请求txt、php)。

    原生javascript使用jsonp:

<!DOCTYPE html>

     <html>

         <head>

             <meta charset="UTF-8">

            <title>Title</title>

            <style>

           *{      margin: 0;      padding: 0;    }   

            input{      width:300px;      height:30px;      border:1px solid lightgray;      margin-top: 150px;      margin-left: 200px;      padding-left: 5px;    }

             ul{      width:307px;      list-style: none;      margin-left: 200px;      display: none;    }    li{      height:30px;      border: 1px solid lightgray;      line-height: 30px;      padding-left: 5px;    }

          </style>

           <script>

            function callbackD(response){

                var oUl = document.getElementById('ulList');

                 var html='';

                if(response.s.length !=0){

                    oUl.style.display='block';

                    for(var i = 0;i<response.s.length;i++){

                        html+='<li>'+response.s[i]+'</li>'

                    }

                 }

               oUl.innerHTML = html;    }

             window.onload = function(){

             var oData = document.getElementById('inputSearch');

             var oUl = document.getElementById('ulList');

            oData.onkeyup = function(){

                if(oData.value != ''){

                    var script = document.createElement("script");

                     script.src='http://unionsug.baidu.com/su?wd='+this.value+'&p=3&cb=callbackD';         

                    //添加给body的(成为body包涵的孩子)        

                     document.body.appendChild(script);

                }else{

                    oUl.style.display='none';

                }

                }

        };

            </script>

     </head>

    <body>

        <input type="text" id="inputSearch">

         <ul id="ulList"> </ul>

        </body>

    </html>

    效果图:

    

    jquery使用jsonp跨域请求

<html>

<head>

<title>跨域测试</title>

<script src="js/jquery-1.7.2.js"></script>

<script>

    function showData (data) {

        //console.info("调用showData");

     var result = JSON.stringify(data);

    $("#text").val(result);

    }

    $(document).ready(function () {

        $("#btn").click(function () {

            $.ajax({

                 url: "json请求地址",

                 type: "GET",

                dataType: "jsonp",  //指定服务器返回的数据类型

                jsonp: "theFunction",   //指定参数名称

                jsonpCallback: "showData",  //指定回调函数名称(绿色部分可省略,默认毁掉函数是success)

                success: function (data) {

                //console.info("调用success");

                }

             });

        });

    });

</script>

</head>

<body>

    <input id="btn" type="button" value="跨域获取数据" />

    <textarea id="text" style="width: 400px; height: 100px;"></textarea>

</body>

</html>

    说明:

    看上图,指定特定的回调函数(红色部分),回调函数你可以写到<script>下(默认属于window对象),或者指明写到window对象里,看jquery源码,可以看到jsonp调用回调函数时,是调用的window.theFunction(jsonp: "theFunction"可不写,默认是callback)。然后看调用结果,发现,请求时带的参数是:callback=showData;调用回调函数的时候,先调用了指定的showData,然后再调用了success。所以,success是返回成功后必定会调用的函数,就看你怎么写了。

    总结:jQuery ajax方式以jsonp类型发起跨域请求,其原理跟<script>脚本请求一样,因此使用jsonp时也只能使用GET方式发起跨域请求。跨域请求需要服务端配合,设置callback,才能完成跨域请求。