jsonp 跨域问题

javascript 遵循同源策略,一般不支持跨域访问数据,但有时候我们需要进行跨域获取数据,这时候我们就可以通过script标签的特性来进行跨域获取数据。

  /*
     * 全局变量在局部可以调用,但是局部变量在全局无法调用
     * */
    /*
     * 1.script标签可以获取非本服务器的内容
     * 2.加载的内容,会直接执行
     * 百度:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=h&cb=jQuery110206284093848166905_1470127107499
     * */
  <!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="text" id="txt1" />
    </body>
    <script type="text/javascript">
     * 百度:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=h&cb=jQuery110206284093848166905_1470127107499
     * */
    </script>
    <script src="jsonp.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">

        var txt1 = document.getElementById("txt1");

        txt1.oninput = function (){
            var txtValue = this.value;
            var url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su";
            var data = {
                wd:txtValue
            }
            jsonp(url,data,function (json){
                console.log(json);
            });
        }
    </script>
</html>

上面实现了输入框输入内容后返回百度api获取的数据,其中jsonp()为我们包装的函数,

var jsonpScriptObj = null;
function toData(obj){
            if (obj == null){
                return obj;
            }
            var arr = [];
            for (var i in obj){
                var str = i+"="+obj[i];
                arr.push(str);
            }
            return arr.join("&");
        }
function jsonp(url,data,succ){
    //1.不重样的函数名
    var fnName = "jsonp"+String(Math.random()).replace("0.","")+"_"+new Date().getTime();
    //将传递过来的成功回调函数命名为fnName并添加到全局里面
    window[fnName] = succ;

    data.cb = fnName;
    var url = url+"?"+toData(data);
    if (jsonpScriptObj){
        document.getElementsByTagName("head")[0].removeChild(jsonpScriptObj);
    }
    jsonpScriptObj = document.createElement("script");
    jsonpScriptObj.src = url;
    document.getElementsByTagName("head")[0].appendChild(jsonpScriptObj);
}

在jsonp()中我们传进来三个参数,第一个为百度api 第二个为前端输入框输入的值,第三个为返回数据的回调函数。
首先我们生成一个不重复的函数名,然后把该函数名给传进来的函数参数赋值(这样我们就可以在前端获取到返回来的对象),而且这个函数一定是全局的(因为函数实际上是在script标签中调用的,如果该函数不是全局的则script访问不到)。之后我们把该生成的函数名作为一个属性赋值给data,这时候data对象里存储着wd和cb,将该data对象通过toData()函数格式化为规定的格式,再将生成的url传递给新生成的script标签的src属性,这样我们就可以在回调函数中访问到返回的数据,实现跨域访问数据。

注意:script标签只能返回一次数据,我们要访问多次就需要多次生成script标签,生成的过程中要将不用的script标签删除掉。

参考文档:
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容