面試--同源以及規避同源限制的方法

同源概述

什麼是同源

協議相同 域名相同 端口相同javascript

同源政策的目的

同源政策的目的,是爲了保證用戶信息的安全,防止惡意的網站竊取數據。
設想這樣一種狀況:A網站是一家銀行,用戶登陸之後,又去瀏覽其餘網站。若是其餘網站能夠讀取A網站的 Cookie,會發生什麼?html

不一樣源的狀況會有哪些限制

隨着互聯網的發展,"同源政策"愈來愈嚴格。目前,若是非同源,共有三種行爲受到限制。
(1) Cookie、LocalStorage 和 IndexDB 沒法讀取。
(2) DOM 沒法得到。
(3) AJAX 請求不能發送。前端

如何規避上面的三種限制?

cookie

Cookie 是服務器寫入瀏覽器的一小段信息,只有同源的網頁才能共享。
可是,兩個網頁一級域名相同,只是二級域名不一樣,瀏覽器容許經過設置document.domain共享 Cookie。
舉例來講,A網頁是http://w1.example.com/a.html,B網頁是http://w2.example.com/b.html,那麼只要設置相同的document.domain,兩個網頁就能夠共享Cookie。java

document.domain = 'example.com';

如今,A網頁經過腳本設置一個 Cookie。react

document.cookie = "test1=hello";

B網頁就能夠讀到這個 Cookie。web

var allCookie = document.cookie;

打開的新窗口和當前窗口不一樣源

若是兩個網頁不一樣源,就沒法拿到對方的DOM。典型的例子是iframe窗口和window.open方法打開的窗口,它們與父窗口沒法通訊。
徹底不一樣源的網站,目前有三種方法,能夠解決跨域窗口的通訊問題。
一、片斷標識符
片斷標識符(fragment identifier)指的是,URL的#號後面的部分,好比http://example.com/x.html#fra...的#fragment。若是隻是改變片斷標識符,頁面不會從新刷新。
父窗口的json

var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;

子窗口的segmentfault

window.onhashchange = checkMessage;

function checkMessage() {
  var message = window.location.hash;
  // ...
}

二、window.postMessage
能夠隱藏一個iframe iframe裏邊的爲子頁面
子頁面發送信息跨域

var ifr=window.parent;
    var targeOrigin='http://localhost:63342/reactWork';
    ifr.postMessage("asa1111",targeOrigin);

父頁面
在父頁面中經過 隱藏一個iframe來實現跨域的數據傳輸
html瀏覽器

<iframe src="http://localhost:3000/talk" id="test"></iframe>

js

<script type="text/javascript">
     window.addEventListener('message',function (event) {
         console.log(event)
         if(event.origin=='http://localhost:1234'){
             console.log(event.data)  //會輸出event的數據
         }
     },false)
</script>

Ajax

同源政策規定,AJAX請求只能發給同源的網址,不然就報錯。
一、jsonp
JSONP是服務器與客戶端跨源通訊的經常使用方法。最大特色就是簡單適用,老式瀏覽器所有支持,服務器改造很是小。
基本的思想
網頁經過添加一個<script>元素,前端的瀏覽器向服務器請求JSON數據,這種作法是不會受到同源政策的限制;服務器在收到請求後,將數據放在一個指定名字的回調函數foo裏傳回來。
前端的js

//動態的插入js腳本
    function addScriptTag(src) {       
        var script = document.createElement('script');
        script.setAttribute("type","text/javascript");
        console.log(src)
        script.src = src;
        document.body.appendChild(script);
    }
    window.onload = function () {
        addScriptTag('http://localhost:3000/talk?callback=foo');
    }
    //傳到服務器端的那個回調函數
    function foo(data) {
        console.log('Your public IP address is: ' + data.ip);
    };

服務器端
直接在index.ejs中寫 給這個回調函數傳遞的就是要發送的數據

foo({
"ip": "8.8.8.8"
});

二、websocket 關於websocket能夠查看個人另外一篇文章
三、cors 關於cors能夠查看個人另外一篇文章 https://segmentfault.com/a/11...

相關文章
相關標籤/搜索