美文网首页
三种以上跨域的解决方式

三种以上跨域的解决方式

作者: 饥人谷_hfz | 来源:发表于2017-06-17 16:24 被阅读0次

    第一种JSONP

    在html下引入外界地址的script标签是可行的,可以引入jquer库等,那说明说同源策略并没有对script的src进行监测,所以可以通过script的src引入外界的地址,通过script 去后台访问数据,将访问的数据,通过后台的配合,将后台返回的数据当做js去运行。

    代码例子:

     <!DOCTYPE html>
    <html>
      <head>
           <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
          <title>news</title>
    <style>
        .container{
            width: 900px;
            margin: 0 auto;
        }
    </style>
    </head>
    <body>
    <div class="container">
    <ul class="news">
        <li>第11日前瞻:中国冲击4金 博尔特再战</li>
        <li>男双力争会师决赛 </li>
        <li>女排将死磕巴西!</li>
    </ul>
    <button class="change">换一组</button>
    </div>
    
    <script>
    
    $('.change').addEventListener('click', function(){
        var script = document.createElement('script');
        script.src = 'http://127.0.0.1:8080/getNews?callback=appendHtml';
        document.head.appendChild(script);
        document.head.removeChild(script);
    })
    function appendHtml(news){
        var html = '';
        for( var i=0; i<news.length; i++){
            html += '<li>' + news[i] + '</li>';
        }
        console.log(html);
        $('.news').innerHTML = html;
    }
    function $(id){
        return document.querySelector(id);
    }
    </script>
    

    后台代码

      将后台返回的数据,作为参数传给函数appendHtml,然后调用函数appendHtml执行。从而获得了后台返回的数据,实现了跨域。
    
    app.get('/getNews', function(req, res){
    
    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }
    var cb = req.query.callback;
    //判断是否有callback如果有,返回appendHtml(JSON.stringify(data))这样html就能以执行js方式调用函数 appendHtml
    if(cb){
        res.send(cb + '('+ JSON.stringify(data) + ')');
    }else{
        res.send(data);
    }
    })
    

    第二种CORS

    CORS全称Cross-Origin Resource Sharing,定义了在必须访问跨域资源时,浏览器与服务器要如何沟通。原理是使用自定义的的HTTP头部让浏览器与服务器沟通,从而决定请求或相应是否成功。比如在发送一个简单的get请求时,需要给它附加一个额外的origin头部,其中包含请求页面的源信息,以便让服务器根据这个头部信息决定是否给予响应。

        只需要后台做配置,设置可以允许的 origin
    

    // res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
    这样a.jrg.com:8080的网站前来访问就可以接受,并给返回数据。
    允许网页地址是http://a.jrg.com:8080来访问接口要数据
    res.header("Access-Control-Allow-Origin", "*");
    // 允许任何网站前来要数据。
    代码例子 :

          <!DOCTYPE html>
         <html>
          <head>
              <meta charset="utf-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
              <title>news</title>
              <style>
                    .container{
                    width: 900px;
                  margin: 0 auto;
             }
          </style>
    </head>
    <body>
          <div class="container">
            <ul class="news">
            <li>第11日前瞻:中国冲击4金 博尔特再战</li>
            <li>男双力争会师决赛 </li>
            <li>女排将死磕巴西!</li>
      </ul>
    <button class="change">换一组</button>
     </div>
      <script>
    
    $('.change').addEventListener('click', function(){
        var xhr = new XMLHttpRequest();
        xhr.open('get', 'http://b.jrg.com:8080/getNews', true);
        xhr.send();
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200 ||xhr.status ===304){
                appendHtml( JSON.parse(xhr.responseText) )
            }
        }
        window.xhr = xhr
    })
    function appendHtml(news){
        var html = '';
        for( var i=0; i<news.length; i++){
            html += '<li>' + news[i] + '</li>';
        }
        console.log(html);
        $('.news').innerHTML = html;
    }
    function $(id){
        return document.querySelector(id);
    }
    </script>
    </html>
    
    
      app.get('/getNews', function(req, res){
    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }
     //  res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
     res.header("Access-Control-Allow-Origin", "*");
     console.log("111111");
     res.send(data);
    })
    

    第三种降域

     a.html
                  <!doctype html>
                             <html lang="en">
                <head>
                         <meta charset="UTF-8">
                        <title>Document</title>
        <style>
            .ct{
                width: 910px;
                margin: auto;
            }
            .main{
                float: left;
                width: 450px;
                height: 300px;
                border: 1px solid #ccc;
            }
            .main input{
                margin: 20px;
                width: 200px;
            }
            .iframe{
                float: right;
            }
            iframe{
                width: 450px;
                height: 300px;
                border: 1px dashed #ccc;
            }
           </style>
        </head>
        <body>
    
        <div class="ct">
            <h1>使用降域实现跨域</h1>
            <div class="main">
                <input type="text" placeholder="http://a.jrg.com:8080/a.html">
            </div>
    
            <iframe src="http://b.jrg.com:8080/b.html" frameborder="0" ></iframe>
    
        </div>
    
    
        <script>
            //URL: http://a.jrg.com:8080/a.html
            document.querySelector('.main input').addEventListener('input', function(){
                console.log(this.value);
                window.frames[0].document.querySelector('input').value = this.value;
            })
            document.domain = "jrg.com"
        </script>
         </body>
        </html>
    
    
      b.html
    
        <!doctype html>
         <html lang="en">
          <head>
           <meta charset="UTF-8">
           <title>Document</title>
         <style>
            html,body{
                margin: 0;
            }
            input{
                margin: 20px;
                width: 200px;
            }
        </style>
        </head>
         <body>
             <input id="input" type="text"  placeholder="http://b.jrg.com:8080/b.html">
         <script>
          // URL: http://b.jrg.com:8080/b.html
    
        document.querySelector('#input').addEventListener('input', function(){
            window.parent.document.querySelector('input').value = this.value;
        })
         document.domain = 'jrg.com';
         </script>
         </body>
         </html>
    
    

    document.domain = "jrg.com" 通过这行代码,将两个网站的都降级为jrg.com 所以属于同源了,可以相互访问数据。

    第四种postMessage() 是用主动发送 和主动接收的方式

    
      <html>
    <style>
        .ct{
            width: 910px;
            margin: auto;
        }
        .main{
            float: left;
            width: 450px;
            height: 300px;
            border: 1px solid #ccc;
        }
        .main input{
            margin: 20px;
            width: 200px;
        }
        .iframe{
            float: right;
        }
        iframe{
            width: 450px;
            height: 300px;
            border: 1px dashed #ccc;
        }
    </style>
    
    <div class="ct">
        <h1>使用postMessage实现跨域</h1>
        <div class="main">
            <input type="text" placeholder="http://a.jrg.com:8080/a.html">
        </div>
    
        <iframe src="http://localhost:8080/b.html" frameborder="0" ></iframe>
    
    </div>
    
    
    <script>
    //URL: http://a.jrg.com:8080/a.html
    // 给其他网站主动发送数据。有监听的网站,可以接受到数据。
    $('.main input').addEventListener('input', function(){
        console.log(this.value);
        window.frames[0].postMessage(this.value,'*');
    })
    
    //监听 并接受返回的数据。可以用e.data接收。
    window.addEventListener('message',function(e) {
            $('.main input').value = e.data
        console.log(e.data);
    });
    function $(id){
        return document.querySelector(id);
    }
    </script>
    </html>
    
    

    相关文章

      网友评论

          本文标题:三种以上跨域的解决方式

          本文链接:https://www.haomeiwen.com/subject/byfbqxtx.html