JS 跨域

1、概念

  跨域是指 從一個域名的網頁去訪問另外一個域名的資源,只要協議、域名、端口有任何一個不一樣,就被看成是跨域。javascript

  這是有瀏覽器的 同源策略 形成的。所謂同源是指, 域名、協議、端口均相同html

  同源策略限制一下幾種行爲:html5

    一、Cookie、LocalStorage 和 IndexDB(瀏覽器本地數據庫) 沒法讀取;java

    二、DOM 和 JS對象沒法獲取;node

    三、AJAX 請求不能發送nginx

 

2、瀏覽器爲何限制跨域訪問呢?

  緣由在於同源策略 是用來隔離潛在惡意文件的關鍵機制。若是缺乏了同源策略,瀏覽器很容易受到XSS(跨域腳本攻擊)和 CSRF(跨站請求僞造)的攻擊。數據庫

 

3、跨域解決方案

  一、 經過jsonp跨域
  二、 document.domain + iframe跨域
  三、 location.hash + iframe
  四、 window.name + iframe跨域
  五、 postMessage跨域
  六、 跨域資源共享(CORS)
  七、 nginx代理跨域
  八、 nodejs中間件代理跨域
  九、 WebSocket協議跨域json

    

  一、經過 JSONP 跨域

    原理:經過script標籤引入一個js文件,這個js文件載入成功後會執行咱們在url參數中指定的函數,而且會把咱們須要的json數據做爲參數傳入(即用 Javascript 動態script,再請求一個帶參網址實現跨域通訊)。segmentfault

  

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 傳參並指定回調執行函數爲onBack
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
    document.head.appendChild(script);

    // 回調執行函數
    function onBack(res) {
        alert(JSON.stringify(res));
    }
 </script>

  服務端返回數據:跨域

  

onBack({"status": true, "user": "admin"})

  

  JSONP的優缺點: 

    優勢:

      一、它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;

      二、它的兼容性更好,在更加古老的瀏覽器中均可以運行,不須要XMLHttpRequest或ActiveX的支持;

      三、而且在請求完畢後能夠經過調用callback的方式回傳結果。 

 

     缺點:

      一、只能實現 GET 一種請求;

      二、只支持跨域HTTP請求這種狀況。

 

  注:在 html 中,擁有src屬性的元素能夠跨域訪問資源,src 屬性擁有跨域請求的特色。

    經過src屬性,img能夠引用其它站點或圖牀的圖片,大大下降本站的圖片持久。

    經過src屬性,script能夠引用CDN的JS文件,加速了瀏覽器的腳本文件的下載,跨域的數據獲取更加高效和方便。

    經過src屬性,iframe能夠嵌入其它站點的頁面,可讓頁面的框架和可變內容分離,內容引用較爲靈活,方便引用其它站點。

  不一樣的是:

    使用 img標籤 不能訪問服務器返回的響應內容,只能單向的發送get請求。

    使用 script標籤 實現的jsonp跨域能夠將服務器響應文本以函數參數的形式返回。

  JSONP就是利用了script標籤的跨域能力

 

  二、經過 CORS(跨域資源共享)實現跨域

    CORS 的基本思想就是使用自定義的 HTTP 頭部 讓瀏覽器與服務器進行溝通,決定請求或響應式是成功仍是失敗。

    服務器對於CORS的支持,主要是經過設置 Access-Control-Allow-Origin 來進行的,若是瀏覽器檢測到響應的設置,就容許 AJAX 進行跨域訪問。

    只須要在後臺中加上響應頭來容許域請求,在被請求的Response header中加入如下設置,就能夠實現跨域訪問。

  

//指定容許其餘域名訪問
'Access-Control-Allow-Origin:*'//或指定域
//響應類型
'Access-Control-Allow-Methods:GET,POST'
//響應頭設置
'Access-Control-Allow-Headers:x-requested-with,content-type'
    參考博文:http://www.ruanyifeng.com/blog/2016/04/cors.html

   

  3.經過 postMessage 實現跨域

    postMessage是HTML5 XMLHttpRequest Level 2中的API,且是爲數很少能夠跨域操做的window屬性之一,它可用於解決如下方面的問題:
      一、 頁面和其打開的新窗口的數據傳遞
      二、 多窗口之間消息傳遞
      三、 頁面與嵌套的iframe消息傳遞
      四、上面三個場景的跨域數據傳遞

    用法:postMessage(data,origin)方法接受兩個參數
      data: html5規範支持任意基本類型或可複製的對象,但部分瀏覽器只支持字符串,因此傳參時最好用JSON.stringify()序列化。
      origin: 協議+主機+端口號,也能夠設置爲"*",表示能夠傳遞給任意窗口,若是要指定和當前窗口同源的話設置爲"/"。

 

    (1)a.html(http://www.domain1.com/a.html)

<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'aym'
        };
        // 向domain2傳送跨域數據
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };

    // 接受domain2返回數據
    window.addEventListener('message', function(e) {
        alert('data from domain2 ---> ' + e.data);
    }, false);
</script>

    

    (2)、b.html(http://www.domain2.com/b.html)

<script>
    // 接收domain1的數據
    window.addEventListener('message', function(e) {
        alert('data from domain1 ---> ' + e.data);

        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;

            // 處理後再發回domain1
            window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
        }
    }, false);
</script>

 

  

 

  

  參考博文:
    http://www.javashuo.com/article/p-gjnaksry-em.html
      http://www.javashuo.com/article/p-blmelnye-bd.html
  感謝博主分享!
相關文章
相關標籤/搜索