zoukankan      html  css  js  c++  java
  • 跨域详解之jsonp,底层的实现原理

    分享一下跨域,不仅是因为现在的工作中遇到的越来越多,而且在面试中也经常被问到。

    那么什么是跨域呢,我们来看官方给出的解释:浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的(所谓同源是指,域名,协议,端口均相同,只要有一个不相同即为跨域),是浏览器对javascript施加的安全限制。这里不做重点介绍,网上有很多这方面的介绍,本篇主要详解jsonp的底层实现原理。

    虽然,浏览器在这方面做了限制,但是我们可以通过script标签,巧妙的避开同源策略,“偷梁换柱”,我们来看一段代码

    <script>
        function fn(data){
            console.log(data);    
        }
    </script>
    <script>
        fn("我是后端的数据");
    </script>

    纳尼???这不就是一个普通的不能再普通的函数调用吗?很多小伙伴一定以为我把代码贴错了吧,开什么玩笑,这不就是一个普通的不能在普通的函数调用吗?这和你说的jsonp有半毛钱关系吗?我想说不仅有关系,而且非常有关系,甚至可以说这就是jsonp的底层实现原理。疯了吧!!!别急。。。咱们接着往下看

     咱来看一下百度提示中使用的的跨域,他就是用的是jsonp的形式,https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=hello,(接口后面的参数我会在下面讲解)这个就是百度提示的一个接口,我们放到浏览器的地址栏打开

    是不是很熟悉,这不就是一个函数调用的方式吗?他把数据当作参数给传进去了,继续往下看

    <script>
        function hello(data){
            console.log(data);  
        }
    </script>
    <script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/suwd=a&cb=hello"></script>

    在浏览器中打印出来,我们发现我们已经拿到了百度给的接口的数据,终于可以长舒一口气。

    但是,好像有点问题,假如我们不是想页面一加载的时候就去拿数据,而是在需要的时候再去加载数据怎么办(也就是按需加载),这时候该怎么办呢?

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
        </body>
            <input type="button" value="点击加载百度接口数据" id="input"/>
        <script>
            function hello(data){
                console.log(data);
            }
            var oInp = document.getElementById('input');
            oInp.onclick = function(){
                var oScript = document.createElement('script');
                oScript.src = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=hello";
                document.body.appendChild(oScript);
            }
        </script>
    </html>

    以上代码就完美的解决了这个问题,实现了按需加载,有木有很像ajax,哈哈,可以在自己的编辑器中运行一下,看一下效果。

    小结:jsonp的底层实现原理,其实就是函数调用,只不过调用的方式有些特别,调用的接口是从后端传过来的。

    再来看一下jquery中jsonp的用法

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
        </body>
        <script src="js/jquery.min.js"></script>
        <script type="text/javascript">
            $.ajax({
                type : "get",
                data : {wd:"a"},
                url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",
                dataType: "jsonp",    //请求类型为jsonp
                jsonp:"cb",            //与后端约定好的函数调用的key值(也就是参数名)
                jsonpCallback: "hello",   //要执行的回调函数名
                success : function(data) {
                    console.log(data);
               }
            })
        </script>    
    </html>

    对比一下前面我写的代码,我想你一定会有所收获!

  • 相关阅读:
    JUC基础(三):ConcurrentHashMap 锁分段机制
    JUC基础(二):原子变量 CAS算法
    JUC基础(一):volatile 关键字 内存可见性
    JAVA多线程(十):线程创建使用 (四)JDK5.0新增线程创建方式
    JAVA多线程(九):线程通信(二)线程的通信经典例题:生产者/消费者问题
    JAVA多线程(八):线程通信(一)线程的通信基础
    JAVA多线程(七):线程同步(三)线程的同步代码练习
    JAVA多线程(六):线程同步(二)线程的同步代码实现
    JAVA多线程(五):线程同步(一)线程的同步
    JAVA多线程(四):线程创建使用 (三)线程的生命周期
  • 原文地址:https://www.cnblogs.com/chenzhiyu/p/7843758.html
Copyright © 2011-2022 走看看