前端面试 页面通信

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 => {
    ...
})

 

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