坚持
  • 微信

当前位置:首页 > 前端技术 > JS >

jsonp跨域

作者:管理员 时间:2022-12-03 阅读数: 4692人阅读

    工作中我们经常会请求其他域下的资源(因为同源策略),这个时候就遇到了跨域(协议,端口,域名任何一个不同就算是跨域)。解决跨域的一种常用办法就是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>

    效果图:    

1.png

    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>

    说明:

2跨域.png

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

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