美文网首页
跨域的解决方式

跨域的解决方式

作者: madpluto | 来源:发表于2017-06-20 09:56 被阅读0次

    jsonp

    html中可以通过script标签引入其他域的js,利用这一特性,结合后端支持,可以实现跨域访问接口
    实现原理:

    1. 定义数据处理函数_fun
    2. 创建script标签,src的地址执行后端接口,最后加个参数callback=fun
    3. 服务端在收到请求后,解析参数,计算返还数据,输出 fun(data) 字符串。
    4. fun(data)会放到script标签做为js执行。此时会调用fun函数,将data做为参数。

    前端代码:

    <!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/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>' + new[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 = parse(Math,random()*news.length);
        data.push(news[index]);
        news.splice(index,1);
      }
    
      var cb = req.query.callback;
      if(cb){
        res.send(cb + '(' + JSON.stringfy(data) + ')');
      }else{
        res.send(data);
      }
    
    })
    

    CORS

    CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。
    实现方式:

    1. 使用XMLHttpRequest发送请求时,服务器发现不同源会在请求中加一个请求头Origin
    2. 后台确定接受该请求,则在响应头中加一个Access-Control-Allow-Origin
    3. 浏览器判断该响应头中包含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){
            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", "*"); 
        res.send(data);
    })
    

    降域

    降域的使用条件是两个名的一级域名相同(例如: a.test.com 与 b.test.com)都同属于test.com这个域名

    测试时需使用a.test.com:8080/a.html访问,不能使用localhost,否则会报错:报错信息为不能把domain设置为test.com

    a.html

       <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>使用降域实现跨域</h1>
            <div class="main">
                <input type="text" placeholder="http://a.test.com:8080/a_jiangyu.html">
            </div>
    
            <iframe src="http://b.test.com:8080/b_jiangyu.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;
            })
    
            //取一级域名作为domain
            document.domain = "test.com"
        </script>
    
        </html>
    

    b.html

      <html>
        <style>
            html,
            body {
                margin: 0;
            }
    
            input {
                margin: 20px;
                width: 200px;
            }
        </style>
    
        <input id="input" type="text" placeholder="http://b.jiangyu.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;
            })
    
            //取一级域名作为domain
            document.domain = 'test.com';
        </script>
    
        </html>
    

    PostMessage

    使用window.postMessage() 实现
    postMessage的原理是会向另一个地方发送信息,另一个地方通常是iframe,或者是由当前页面弹出的窗口。参数是:信息以及表示接受消息方的来自哪个域的字符串,如果给定*便是不限定接受者的域。

    a.html

       <html>
        <style>
            .ct {
                width: 910px;
                margin: auto;
            }
    
            .ct h1 {
                text-align: center;
            }
    
            .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.test.com:8080/a.html">
            </div>
    
            <iframe src="http://localhost:8080/b.html" frameborder="0"></iframe>
    
        </div>
    
    
        <script>
            //URL: http://a.test.com:8080/a.html
            $('.main input').addEventListener('input', function() {
                window.frames[0].postMessage(this.value, '*');
            })
            window.addEventListener('message', function(e) {
                $('.main input').value = e.data
            });
    
            function $(id) {
                return document.querySelector(id);
            }
        </script>
    
        </html>
    

    b.html

        <html>
        <style>
            html,
            body {
                margin: 0;
            }
    
            input {
                margin: 20px;
                width: 200px;
            }
        </style>
    
        <input id="input" type="text" placeholder="http://b.test.com:8080/b.html">
        <script>
            // URL: http://b.test.com:8080/b.html
    
            $('#input').addEventListener('input', function() {
                window.parent.postMessage(this.value, '*');
            })
            window.addEventListener('message', function(e) {
                $('#input').value = e.data
            });
    
            function $(id) {
                return document.querySelector(id);
            }
        </script>
    
        </html>
    

    相关文章

      网友评论

          本文标题:跨域的解决方式

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