前端面試 頁面通信

1.什麼是同源策略及限制

同源策略限制從一個源加載的文檔或者腳本如何與來自另一個源的資源進行交互。

(請求協議、域名、端口不同,都算跨域)

  • Cookie、LocalStorage和IndexDB無法讀取
  • DOM無法獲得
  • AJAX請求不能發送

2.前後端通信

  • Ajax
  • WebSocket 不受同源策略限制
  • CORS 允許跨域通信

3.創建Ajax

// 第一步,創建一個XHR對象 IE不支持XMLHttpRequest,所以要做兼容性校驗

var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');

// 第二步,設置請求類型、URL、參數

xhr.open('GET', url, true);

// open方法有三個參數:請求類型(get、post等),請求的URL和表示異步發送請求的布爾值。

// 第三步,發送請求

xhr.send();

// 第四步,註冊事件 onreadystatechange 狀態改變就會調用

xhr.onreadystatechange = function() {

    if(xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304){

        // 第五步,如果能夠進到這個判斷,說明數據完美的回來了,並且請求的頁面是存在的。

        fn.call(this, xhr.responseText);

    }

};

4.跨域通信的幾種方式

  • JSONP
  • Hash ,hash改變頁面不刷新!!
  • postMessage
  • WebSocket,不受同源策略限制
  • CORS 允許跨域通信

4.1 jsonp

前端寫一個<script>標籤,callback是和後端商量好的回調函數jsonpFun,並且前端需要定義一個全局函數jsonpFun

<script src="xxxx?data=11&callback=jsonpFun"></script>

後端返回一個js代碼塊,執行全局函數jsonpFun

<script>
    jsonpFun({
        data: {}
    })
</script>

4.2 hash

// 利用hash,場景是當前頁面 A 通過iframe 或者 frame 嵌入跨域的頁面 B
// 在 A 頁面中
var B = document.getElementByTagName('iframe');
B.src = B.src + '#' + data; // data爲字符串類型數據

// 在 B 頁面中,
window.onhashchange = function() {
    var data = window.location.hash;
} 

4.3 postMessage

// 窗口 A(http://A.com) 向跨域的窗口 B(http://B.com)
B窗口 window.postMessage('data', 'http://B.com');
// 在 B 窗口監聽
window.addEventListener('message', function(event) {
    console.log(event.origin); // 源 http://A.com
    console.log(event.source); // 引用A窗口對象
    console.log(event.data); // 對象 
})

4.4 WebSocket

var ws = new WebSocket('wss://echo.websocket.org');

ws.onopen = function(e) {
    console.log('connection open');
    ws.send('hello world'); // 發送請求
}

// 接收消息
ws.onmessage = function(e) {
    console.log('receive message' + e.data);
    ws.close();  // 關閉連接
}

// 監聽連接關閉
ws.onclose = function(e) {
    console.log('connection closed');
}

4.5 CORS

fetch.('url', {
    method: 'get'
}).then(res => {
    ...
}).catch(err => {
    ...
})

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章