前端面试题总结分享

192 阅读3分钟

问题一: 从页面 A 打开一个新页面 B,B 页面关闭(包括意外崩溃),如何通知 A?

首先,这个题目是前端通信题目,可以从3个方面来解答这个问题

  • A 页面打开 B 页面,A、B 页面通信方式?
  • B 页面正常关闭,如何通知 A 页面?
  • B 页面意外崩溃,又该如何通知 A 页面?

首先,我们来看 A 页面打开 B 页面,A、B 页面通信方式:

A、B 页面通信方式有:

  • url 传参
  • postmessage
  • localStorage
  • WebSocket
  • SharedWorker
  • Service Worker

url 传参

A:

<!-- A.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>A</title>
</head>
<body>
    <h1>A 页面</h1>
    <button type="button" onclick="openB()">B</button>
    <script>
        window.name = 'A' //表示页面的名称
        function openB() {
          window.open("B.html", "B") // 第一个参数表示页面的名称
        }

        window.addEventListener('hashchange', function () {// 监听 hash
            alert(window.location.hash)
        }, false);
    </script>
</body>
</html>

B:

<!-- B.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>B</title>
    <button type="button" onclick="sendA()">发送A页面消息</button>
</head>
<body>
    <h1>B 页面</h1>
    <span></span>
    <script>
        window.name = 'B'
        window.onbeforeunload = function (e) {
            window.open('A.html#close', "A")
            return '确定离开此页吗?';
        }
    </script>
</body>
</html>

总结: 上述知识点,首先A页面有一个Button点击事件,里面的方法window.open去往B页面,同时在B页面当中有一个onbeforeunload在浏览器关闭的时候触发,里面有一个window.open去往A页面,这就是A页面和B页面的一个通信方式,桥接它们的是A页面当中的hashchange事件,通过这个事件就可以接收到B页面传递过来的值.

postMessage

postMessageh5 引入的 API,postMessage() 方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档、多窗口、跨域消息传递,可在多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案,简直不要太好用

A:

<!-- A.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>A</title>
</head>
<body>
    <h1>A 页面</h1>
    <button type="button" onclick="openB()">B</button>
    <script>
        window.name = 'A'
        function openB() {
            window.open("B.html?code=123", "B")
        }
        window.addEventListener("message", receiveMessage, false);
        function receiveMessage(event) {
            console.log('收到消息:', event.data)
        }
    </script>
</body>
</html>

B:

<!-- B.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>B</title>
    <button type="button" onclick="sendA()">发送A页面消息</button>
</head>
<body>
    <h1>B 页面</h1>
    <span></span>
    <script>
        window.name = 'B'
        function sendA() {
            let targetWindow = window.opener  // window.opener表示打开窗口A
            targetWindow.postMessage('Hello A', "http://localhost:3000");
        }
    </script>
</body>
</html>

总结: postMessage通信的步骤是点击A页面的按钮跳转到B页面,在A页面通过监听message事件,接收B页面传递过来的数据event.data,在B页面点击按钮发送到A页面,将数据'hello A',传递到A页面,注意浏览的同源策略!

LocalStorage

// A
localStorage.setItem('testB', 'sisterAn');

// B
let testB = localStorage.getItem('testB');
console.log(testB)

总结: Localstorage本地存储用的场景很多也比较简单,但是要注意localStorage 仅允许你访问一个Document 源(origin)的对象 Storage;存储的数据将保存在浏览器会话中。如果 A 打开的 B 页面和 A 是不同源,则无法访问同一  Storage

接着,我们来看第二个问题,B 页面正常关闭,如何通知 A 页面?

首先在B页面监听window.onbeforeunload,然后再去执行window.onunload,我们可以通过这两个方法向A页面通信.

最后一个问题,B 页面意外崩溃,又该如何通知 A 页面?

我们可以利用 window 对象的 loadbeforeunload 事件,通过心跳监控来获取 B 页面的崩溃,具体代码如下:

 window.addEventListener('load', function () {
      sessionStorage.setItem('good_exit', 'pending');
      setInterval(function () {
         sessionStorage.setItem('time_before_crash', new Date().toString());
      }, 1000);
   });

   window.addEventListener('beforeunload', function () {
      sessionStorage.setItem('good_exit', 'true');
   });

   if(sessionStorage.getItem('good_exit') &&
      sessionStorage.getItem('good_exit') !== 'true') {
      /*
         insert crash logging code here
     */
      alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'));
   }

总结: 首先,在页面加载的时候,监听load事件设置一个sessionStorage,设置它的键和状态"pedding"并且每隔一秒钟再设置一次,并且在页面关闭的时候触发beforeunload事件,并把它的值改为"true",接下来就判断pedding是否为"true".