跨域的幾種實現方式

JSONP
// 前端代碼
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .ct {
      width: 300px;
      margin: 0 auto;
      margin-top: 20px;
      border: 1px solid #ccc;
    }
    .ct img {
      width: 300px;
      height: 200px;
    }
    .ct h3 {
      font-size: 14px;
      padding: 5px;
    }
    .ct p {
      font-size: 12px;
      padding: 5px;
    }
    .btn {
      display: block;
      width: 80px;
      height: 40px;
      font-size: 12px;
      margin: 0 auto;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="ct">
     ![](http://a.jpg)
      <h3 class="title">寵物的斑斑劣跡:偷吃毫無悔意</h3>
      <p class="content">我們都以為自己出門時、寵物們都會乖乖待在家里,但一些照片顯示,你想得太美了。</p>
    </div>
    <button class="btn">換個新聞看看</button>
  </div>

  <script>

    var btn = document.getElementsByClassName('btn')[0];
    var ct = document.getElementsByClassName('ct')[0];
    btn.addEventListener('click', function(){
      var script = document.createElement("script");
      script.src = "http://localhost:8080/getNews?callBack=switchNews";
      document.head.appendChild(script);
      document.head.removeChild(script);
    })

    function switchNews(data){
      var html = '';
      html += '![](' + data.img + ')';
      html += '<h3 class="title">' + data.title + '</h3>';
      html += '<p class="content">' + data.content + '</p>';
      ct.innerHTML = html;
    }

  </script>
  
</body>
</html>

// 后端代碼
app.get('/getNews',function(req, res){
  var news = [
    {
      img:"http://n.sinaimg.cn/tech/transform/20170701/QJiR-fyhskrp9685559.jpg",
      title: "極地生物散發神秘魅力",
      content: "這些極具視覺沖擊效果畫面向我們揭示了生活在格陵蘭島冰蓋下的神秘生物。"
    },
    {
      img:"http://n.sinaimg.cn/tech/transform/20170701/cycK-fyhskrp9682498.jpg",
      title: "南非蜥蜴覓食遭蝴蝶調戲",
      content: "一頭熒光黃色的蜥蜴正在尋找自己的下一餐,遇到了一群蝴蝶。"
    },
    {
      img:"http://n.sinaimg.cn/tech/transform/20170630/4f0z-fyhskrp8448536.jpg",
      title: "澳袋鼠代班當牧羊犬",
      content: "當Lochie Ireson看到一頭“牧羊犬袋鼠”跳上一頭羊的背,把羊群趕進圍欄的畫面時,他簡直驚呆了。lalalalalalalaallalal"
    }
  ];

  var cb = req.query.callBack;
  var index = parseInt(Math.random()*news.length);
  if (cb) {
    res.send(cb + '(' + JSON.stringify(news[index]) + ')');
  }
})
CORS
// 前端代碼
  <script>

    var btn = document.getElementsByClassName('btn')[0];
    var ct = document.getElementsByClassName('ct')[0];
    btn.addEventListener('click', function(){
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function(){
        if(xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 304)){
          var data = JSON.parse(xhr.responseText);
          switchNews(data);
        } 
      }
      xhr.open('get', 'http://b.supoxiao.com:8080/getNews', true);
      xhr.send();
    })

    function switchNews(data){
      var html = '';
      html += '![](' + data.img + ')';
      html += '<h3 class="title">' + data.title + '</h3>';
      html += '<p class="content">' + data.content + '</p>';
      ct.innerHTML = html;
    }

  </script>

// 后端代碼
app.get('/getNews', function(req, res){
  var news = [
    {
      img:"http://n.sinaimg.cn/tech/transform/20170701/QJiR-fyhskrp9685559.jpg",
      title: "極地生物散發神秘魅力",
      content: "這些極具視覺沖擊效果畫面向我們揭示了生活在格陵蘭島冰蓋下的神秘生物。"
    },
    {
      img:"http://n.sinaimg.cn/tech/transform/20170701/cycK-fyhskrp9682498.jpg",
      title: "南非蜥蜴覓食遭蝴蝶調戲",
      content: "一頭熒光黃色的蜥蜴正在尋找自己的下一餐,遇到了一群蝴蝶。"
    },
    {
      img:"http://n.sinaimg.cn/tech/transform/20170630/4f0z-fyhskrp8448536.jpg",
      title: "澳袋鼠代班當牧羊犬",
      content: "當Lochie Ireson看到一頭“牧羊犬袋鼠”跳上一頭羊的背,把羊群趕進圍欄的畫面時,他簡直驚呆了。lalalalalalalaallalal"
    }
  ];

  var index = parseInt(Math.random()*news.length);

  res.header("Access-Control-Allow-Origin", "http://a.supoxiao.com:8080");
  res.send(news[index]);


});
降域

對于頁面中使用iframe嵌套另外的網站時,如果符合同源策略,就可以通過window.frames[index].document操作對應iframe里的網站,如果不符合,則不能相互訪問,但是如果這些網站有著相同的主網站,則可以通過降域實現跨域。例如:a.test.com:8080和b.test.com:8080的主域名為test.com:8080

原理

在script標簽里寫上document.domain = "主域名",就可以實現降域,
然后就可以使用window.frames[index].document操作對應iframe里的網站,實現跨域。

// 創建a.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    iframe {
      width: 500px;
      height: 200px;
    }
    .wrapper {
      margin-left: 100px;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="ct">
      <h1>降域</h1>
      <input type="text" placeholder="hello">
    </div>
    
    <iframe src="http://b.supoxiao.com:8080/b.html"></iframe>
  </div>
  
  <script>
    document.querySelector("input").addEventListener("input",function(){
      window.frames[0].document.querySelector("input").value = this.value;
    })
    document.domain = "supoxiao.com";

  </script>
  
</body>
</html>

// 創建b.html

<html>
<head>
  <meta charset="utf-8">
  <style>
  </style>
</head>
<body>

    <p>我是b</p>

    <input type="text" placeholder="hello2">

  
  <script>

    document.domain = "supoxiao.com";
  </script>
  
</body>
</html>
postMessage

postMessage()方法允許來自不同源的腳本采用異步方式進行有限的通信,可以實現跨文本檔、多窗口、跨域消息傳遞。postMessage(data,origin)方法接受兩個參數,data是要傳遞的數據,origin可以設置目標窗口的url,只包括協議、域名、端口。也可以設置為"*",表示傳遞給任意窗口

原理

postMessage可向任意窗口發送數據,由目標窗口選擇接受數據。
通過postMessage()發送數據,然后再寫一個監聽函數就可以實現跨域操作。

// 創建a.html
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    iframe {
      width: 500px;
      height: 200px;
    }
    .wrapper {
      margin-left: 100px;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="ct">
      <h1>postMessage</h1>
      <input type="text" placeholder="hello">
    </div>
    
    <iframe src="http://b.supoxiao.com:8080/b.html"></iframe>
  </div>
  <script>
    document.querySelector("input").addEventListener("input",function(){
      window.frames[0].postMessage(this.value,"*");
    })
    
    window.addEventListener("message",function(e){
      document.querySelector("input").value = e.data;
    })
  </script>
  
</body>
</html>

// 創建b.html
<html>
<head>
  <meta charset="utf-8">
  <style>
  </style>
</head>
<body>

    <p>我是b</p>

    <input type="text" placeholder="hello2">

  
  <script>
  var input = document.querySelector("input");
  window.addEventListener("message",function(e){
    input.value = e.data;
  })
  input.addEventListener("input",function(){
    window.parent.postMessage(this.value,"*")
  })
  </script>
  
</body>
</html>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 概念1:同源策略 同源策略,Same-origin policy,瀏覽器處于安全考慮,只允許與本域下的接口交互。不...
    虛玩玩TT閱讀 643評論 0 0
  • JSONP JSONP 是JSON with padding(填充式JSON 或參數式JSON)的簡寫;JSONP...
    Schrodinger的貓閱讀 339評論 0 0
  • 什么是同源策略? 同源策略是指,瀏覽器出于安全方面的考慮,只允許與本域下的接口交互。不同源的客戶端腳本在沒有明確授...
    upup_dayday閱讀 266評論 0 0
  • 本文著作權歸饑人谷_Lyndon和饑人谷所有,轉載請注明出處。 這是一篇對于跨域的總結,將涵蓋跨域的四種方法: j...
    HungerLyndon閱讀 14,731評論 7 25
  • 用大愛點燃山村希望 貴州省黔西縣定新鄉莊子村屬國家一類貧困村,位于定新鄉東南面,距鄉政府駐地4.5公里,面積6平方...
    中外藝術家閱讀 625評論 0 0