跨域

什么是同源策略

同源策略(same origin policy),1995年同源政策由 Netscape 公司引入瀏覽器。目前,所有瀏覽器都實(shí)行這個(gè)政策瀏覽器出于安全方面的考慮,只允許與本域下的接口進(jìn)行交互。不同源的客戶腳本在沒有明確授權(quán)的情況下,不能讀取對(duì)方的資源。
同源政策的目的,是為了保證用戶信息的安全,防止惡意的網(wǎng)站竊取數(shù)據(jù)

本域指的是

  • 同協(xié)議:比如都是 http 或者 https
  • 同端口:比如都是 80 端口
  • 同域名:比如都是 google.com

什么是跨域?跨域有幾種實(shí)現(xiàn)形式

跨域是指通過一定方式繞過瀏覽器同源政策的限制,可以與不同域進(jìn)行交互
目前學(xué)習(xí)到四種實(shí)現(xiàn)形式:

  • JSONP
  • CORS
  • 降域
  • postMessage

JSONP 的原理是什么

jsonp 是一種跨域通信的手段,它的原理其實(shí)很簡(jiǎn)單:

  1. 首先是利用 script 標(biāo)簽的 src 屬性來實(shí)現(xiàn)跨域。
  2. 通過將前端方法作為參數(shù)傳遞到服務(wù)器端,然后由服務(wù)器端注入?yún)?shù)之后再返回,實(shí)現(xiàn)服務(wù)器端向客戶端通信。
  3. 由于使用 script 標(biāo)簽的 src 屬性,因此只支持 get 方法

CORS是什么

  • CORS 是一個(gè) W3C 標(biāo)準(zhǔn),全稱是“跨域資源共享”(Cross-origin resource sharing,它允許瀏覽器向跨源服務(wù)器,發(fā)出 XMLHttpRequest 請(qǐng)求,從而克服了 AJAX 只能同源使用的限制

  • CORS 需要瀏覽器和服務(wù)器同時(shí)支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于 IE10。

  • 整個(gè) CORS 通信過程,都是瀏覽器自動(dòng)完成,不需要用戶參與。對(duì)于開發(fā)者來說,CORS 通信與同源的 AJAX 通信沒有差別,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn) AJAX 請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附加的頭信息,有時(shí)還會(huì)多出一次附加的請(qǐng)求,但用戶不會(huì)有感覺。

因此,實(shí)現(xiàn) CORS 通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了 CORS 接口,就可以跨源通信。

參考阮一峰

根據(jù)視頻里的講解演示三種以上跨域的解決方式 ,寫成博客

  • JSONP
var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')

http.createServer(function(req, res){
  var pathObj = url.parse(req.url, true)

  switch (pathObj.pathname) {
    case '/getNews':
      var news = [
        "第11日前瞻:中國(guó)沖擊4金 博爾特再戰(zhàn)200米羽球",
        "正直播柴飚/洪煒出戰(zhàn) 男雙力爭(zhēng)會(huì)師決賽",
        "女排將死磕巴西!郎平安排男陪練模仿對(duì)方核心"
        ]
      res.setHeader('Content-Type','text/json; charset=utf-8')
      if(pathObj.query.callback){
        res.end(pathObj.query.callback + '(' + JSON.stringify(news) + ')')  // 將數(shù)據(jù)處理后返回
      }else{
        res.end(JSON.stringify(news))
      }

      break;

    default:
      fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
        if(e){
          res.writeHead(404, 'not found')
          res.end('<h1>404 Not Found</h1>')
        }else{
          res.end(data)
        }
      }) 
  }
}).listen(8080)
<!DOCTYPE html>
<html>
<body>
  <div class="container">
    <ul class="news">
    </ul>
    <button class="show">show news</button>
  </div>

<script>
   // 通過script標(biāo)簽發(fā)送請(qǐng)求
  $('.show').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);
  })

   // 將獲取到的數(shù)據(jù)添加到頁面中
  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>
  • CORS
var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')

http.createServer(function(req, res){
  var pathObj = url.parse(req.url, true)

  switch (pathObj.pathname) {
    case '/getNews':
      var news = [
        "第11日前瞻:中國(guó)沖擊4金 博爾特再戰(zhàn)200米羽球",
        "正直播柴飚/洪煒出戰(zhàn) 男雙力爭(zhēng)會(huì)師決賽",
        "女排將死磕巴西!郎平安排男陪練模仿對(duì)方核心"
        ]
      res.setHeader('Access-Control-Allow-Origin','*') // 設(shè)置響應(yīng)頭中的屬性,允許所有的站點(diǎn)訪問
      res.end(JSON.stringify(news))

      break;

    default:
      fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
        if(e){
          res.writeHead(404, 'not found')
          res.end('<h1>404 Not Found</h1>')
        }else{
          res.end(data)
        }
      }) 
  }
}).listen(8080)
<!DOCTYPE html>
<html>
<body>
  <div class="container">
    <ul class="news">
    </ul>
    <button class="show">show news</button>
  </div>

<script>

  $('.show').addEventListener('click', function(){
    xhr = new XMLHttpRequest();  // 創(chuàng)建 AJAX 請(qǐng)求
    xhr.open('GET','http://127.0.0.1:8080/getNews',true);
    xhr.send();
    xhr.onload = function(){
      appendHtml(JSON.parse(xhr.responseText));
    }
  })

  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>
  • postMessage
    postMessage 是 HTML5 新增加的一項(xiàng)功能,跨文檔消息傳輸(Cross Document Messaging),目前:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 都支持這項(xiàng)功能,使用起來也特別簡(jiǎn)單
    • 首先創(chuàng)建 a.html

      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>postMessage</title>
      </head>
      <body>
        <iframe src="http://localhost:8080/b.html" ></iframe>
        <script>
          window.onload = function(){
            var targetOrigin = "http://localhost:8080";
            window.frames[0].postMessage('看到我發(fā)給你的信息沒', targetOrigin);
          }
          window.addEventListener('message',function(e){
            console.log('a.html接收到信息:',e.data);
          });
        </script>
      </body>
      </html>
      
    • 創(chuàng)建 b.html

      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>postMessageB</title>
      </head>
      <body>
        
        <script>
          window.addEventListener('message',function(e){
            if(e.source != window.parent){
              return
            }
            var data = e.data;
            console.log("b.html接收到的消息", data);
            parent.postMessage("我看到你發(fā)的消息了", e.origin)
          })
        </script>
      </body>
      </html>
      

在瀏覽器中打開 http://localhos/a.html

postMessage.png

跨域成功
參考:MDN

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 題目1.什么是同源策略? 同源策略(Same origin Policy): 瀏覽器出于安全方面的考慮,只允許與本...
    FLYSASA閱讀 1,889評(píng)論 0 6
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實(shí)際上跨域的范圍絕對(duì)不止那么狹隘。具體概念如下:只要協(xié)議...
    w_zhuan閱讀 622評(píng)論 0 0
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實(shí)際上跨域的范圍絕對(duì)不止那么狹隘。具體概念如下:只要協(xié)議...
    他在發(fā)呆閱讀 864評(píng)論 0 0
  • 給大家推薦這首歌。 大部分的原因是, 送給所有在清明節(jié)不能回家的朋友。 歌詞 夜色茫茫 罩四周 天邊新月如鉤 回憶...
    大胡子豬閱讀 445評(píng)論 0 2
  • 不知不覺間,那個(gè)老師被調(diào)離了! 文 / 錢黎潔 咱孩子班級(jí)下學(xué)期鐵定換語文老師了!那天一起在校門外等孩子,一洋同班...
    錢錢show生活閱讀 408評(píng)論 0 0

友情鏈接更多精彩內(nèi)容