zoukankan      html  css  js  c++  java
  • 跨域解决方案之JSONP

    跨域解决方案之JSONP

    同源策略

    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

    同源策略,它是由Netscape提出的一个著名的安全策略。

    现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。

    例如:

    http://www.baidu.com 和 http://www.baidu.com:8080 二者是不同源的。
    http://www.baidu.com和https://www.baidu.com 同样是不同源的。

    当请求不同源的数据的时候,浏览器就会在控制台报出一个异常,并且提示拒绝访问。同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

    JSONP介绍

    JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML<script>元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

    JSONP基本原理

    上面简单的理解了JSONP的功能之后,下面来一点一点的了解JSONP的具体使用方式。

    首先通过script标签引入一个指定的文件。

    例如1.txt中有一个数组。

    ["hello","world"]

    为了使用这个数组,我们通过JSONP的逻辑,使用script标签引入这个文件

    <script src="01.txt"></script>

    上面我们虽然引入了这个文件,但是我们发现引入后我们并没有办法使用。我们之前曾经做过类似于下面的行为,就是给数据前面添加一个变量名。类似于下面:

    var a = ["hello","world"]

    这样我们在网页里面就可以使用这个文件中的数据了。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="01.txt"></script>
        <script>
            alert(a); 
        </script>
    </head>
    <body>
        
    </body>
    </html>

    上面的代码顺利的读取了文件中的数据。

    但是程序开发当中,我们如果采取类似于像上面的写法,又可能造成变量的污染。

    既要解决读取数据的问题,又要避免变量污染,我们可以采取函数的形式。

    将01.txt改成下面的形式:

    fn(["hello","world"])

    在网页文件中如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <script>
            function fn(data){
                alert(data);
            }
        </script>
        <script src="01.txt"></script>
    </body>
    </html>

    上面的代码中,当文件被加载进来的时候,就相当于调用了我们定义好的函数fn,而文件中的数据也自动的被传入到了函数中。

    上面的逻辑就是JSONP的核心逻辑。

    添加请求参数

    在上面的代码中,我们简单的体验了JSONP的基本逻辑。下面我们来将基本的使用方式进行一下升级,让我们的请求能够添加参数。

    例如,我们现在在服务端中有两组数组,一组存储的是歌名,一组存储的是电影名,点击不同的按钮显示不同的数据。

    首先我们先来完成html的代码:

    <button id="btn1">音乐排行</button>
    <ul id="list1">
        
    </ul>
    <button id="btn2">电影排行</button>
    <ul id="list2">
        
    </ul>

    我们的需求是点击两个按钮分别显示不同的数据,下面是服务端的代码:

    <?php 
    header("Content-type:text/html;Charset=utf-8");
    
    // 接收数据 
    $parm = $_GET['parm'] ? $_GET['parm'] : 'music';
    $callback = $_GET['callback'];
    
    // 模拟数据库存储的数组 
    $arr_music = ['残酷月光','孤身','Come back','情深深雨蒙蒙','救赎'];
    $arr_movie = ['肖申克的救赎','流浪地球','盗梦空间','我不是药神','阿甘正传'];
    
    // 判断传输的数据是什么
    if($parm === "music") {
        $data = $arr_music;
    }else {
        $data = $arr_movie;
    }
    
    // 传输数据 
    echo $callback . "(" . json_encode($data) . ")"; // 将数据传输之前转换成json

    JS代码:

    // 点击按钮请求数据  
    let oBtn1 = document.getElementById('btn1');
    let oBtn2 = document.getElementById('btn2');
    
    // 创建回调函数 
    function getdata1(data) {
        // 获取元素赋值 
        let list1 = document.getElementById('list1');
        html = '';
        for(let i=0;i<data.length;i++){
            html += "<li>" + data[i] + "</li>";
        }
        list1.innerHTML = html;
    
    }
    function getdata2(data) {
        // 获取元素赋值 
        let list2 = document.getElementById('list2');
        html = '';
        for(let i=0;i<data.length;i++){
            html += "<li>" + data[i] + "</li>";
        }
        list2.innerHTML = html;
    
    }
    
    oBtn1.onclick = ()=> {
        // 创建script标签 ,动态插入 
        let script = document.createElement('script'); // 创建
        let url = "02.jsonp.php?parm=music&callback=getdata1";
        script.src = url;
        document.getElementsByTagName('body')[0].appendChild(script);
    };
    
    oBtn2.onclick = ()=> {
        // 创建script标签 ,动态插入 
        let script = document.createElement('script'); // 创建
        let url = "02.jsonp.php?parm=movie&callback=getdata2";
        script.src = url;
        document.getElementsByTagName('body')[0].appendChild(script);
    };
    

    这样,我们就通过JSONP的形式读取到了后台文件的数据。

    JSONP因为通过src属性,所以只能通过get传输数据。

  • 相关阅读:
    配置WepApi默认支持JSON数据格式的返回 人工智能
    让人HOLD不住的新闻,Windows8将何去何从?Windows8的开发何去何从? 人工智能
    MVC开发的小问题及解决方案记录 人工智能
    在埋头写程序学技术的同时,有没有想到你们的老板和上司在搞什么? 人工智能
    Func与Action, delegate, event, var, dynamic, 匿名方法,lambda, 大量的关键都使用相同功能,大大增加C#复杂性 人工智能
    畅想(2)计算机发展与教育的关系 人工智能
    函数式编程学习之路(二) 人工智能
    C++关键字(1)——const
    怎样在阻塞模式下设置recv()函数的阻塞时间
    队列
  • 原文地址:https://www.cnblogs.com/jhflyfish/p/11569229.html
Copyright © 2011-2022 走看看