前端面試-跨域那些事兒

瞭解跨域以前,咱們先來了解以下兩個知識點javascript

  1. URL組成css

    URL:協議 + 域名 + 端口號(默認爲8080可省略) + 參數html

  2. 瀏覽器同源策略前端

    所謂同源是指,域名,協議,端口相同。java

    同源策略是瀏覽器的行爲,是爲了保護本地數據不被JavaScript代碼獲取回來的數據污染,所以攔截的是客戶端發出的請求回來的數據接收,即請求發送了,服務器響應了,可是沒法被瀏覽器接收。segmentfault

    不知足同源策略的條件的網頁,是不可以互相通訊的,這時候就須要咱們使用跨域來解決這個問題後端

1.跨域方法概覽

  • JSONP
  • PostMessage
  • domain
  • Hash
  • 跨域資源共享(CORS)
  • WebSocket協議跨域

2. JSONP 跨域

  • 經過在界面動態寫入 script 標籤,設置src屬性,將請求以URL參數的形式附加在URL中,而且指定回調函數
  • 服務器返回回調函數,而且將數據看成回調函數的參數返回
  • 在界面定義回調函數,服務器返回以後會直接調用

代碼示例:跨域

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

    // 傳參一個回調函數名給後端,方便後端返回時執行這個在前端定義的回調函數
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);

    // 回調執行函數
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>
複製代碼

服務器返回以下,返回即執行瀏覽器

handleCallback(someData)
複製代碼

3. postMessage詳解

postMessage方法接收兩個參數服務器

  • data
  • origin:發送目標的URL地址

代碼示例:

  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>
複製代碼
  1. 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>
複製代碼

4. domain

此方法僅限主域相同,子域不一樣的跨域應用場景

實現方式:兩個頁面都經過js強制設置 document.domain爲基礎主域,就實現了同域

代碼示例:

  1. 父窗口:http://www.domain1.com/a.html
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>
複製代碼
  1. 子窗口:http://child.domain2.com/b.html
<script>
    document.domain = 'domain.com';
    // 獲取父窗口中變量
    alert('get js data from parent ---> ' + window.parent.user);
</script>
複製代碼

5. CORS

普通跨域請求:只服務端設置Access-Control-Allow-Origin便可,前端無須設置

6. WebSocket協議跨域

前端代碼示例

<div>user input:<input type="text"></div>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>

<script>
var socket = io('http://www.domain2.com:8080');

// 鏈接成功處理
socket.on('connect', function() {
    // 監聽服務端消息
    socket.on('message', function(msg) {
        console.log('data from server: ---> ' + msg); 
    });

    // 監聽服務端關閉
    socket.on('disconnect', function() { 
        console.log('Server socket has closed.'); 
    });
});

document.getElementsByTagName('input')[0].onblur = function() {
    socket.send(this.value);
};
</script>
複製代碼

參考文章:

前端常見跨域解決方案

相關文章
相關標籤/搜索