前端面试题
跨标签页通信的方式
-
localStorage或者sessionStorage:一个标签页可以将数据存储在localStorage或者sessionStorage中,其他标签页可以监听存储事件来获取更新的数据。
-
Broadcast Channel API: Broadcast Channel API 允许不同标签页之间通过共享的通道进行消息广播和接收。一个标签页可以通过通道发送消息,其他订阅了相同通道的标签页可以接收到这些消息。
在发送消息的标签中:在接收消息的标签中:

首先在发送消息的标签页中创建一个 Broadcast Channel,并指定一个唯一的通道名称(这里是myChannel)。通过 channel.postMessage()方法发送消息到该通道。
在接收消息的标签页,利用同样通道名称的Broadcast Channel来监听消息。
- SharedWorker:SharedWorker是一种在多个标签页之间共享的后台线程。标签页可以通过 SharedWorker进行通信,发送消息和接收消息。
共享脚本文件worker.js
tab1的js文件
script1.js
tab2的js文件
script2.js
在worker.js中通过监听connect事件,获取通信端口port,然后通过端口来传递消息,并在不同的tab标签页中监听worker.js发送的消息。
4. Service Worker是一种独立于网页的脚本,可以在后台运行,提供离线缓存和消息传递等功能。标签页可以通过Service Worker进行通信,发送和接收消息。详情看[网易云课堂 Service Worker 运用与实践 (qq.com)](https://mp.weixin.qq.com/s/3Ep5pJULvP7WHJvVJNDV-g)
5. postMessage:[window.postMessage - Web API 接口参考 | MDN (mozilla.org)](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage)
7. cookie
8. indexedDB
9. ajax,websocket
10. queryString params
浏览器从输入url到页面展示的过程
- URL输入,浏览器解析URL,提取协议、域名、路径等信息
- DNS解析寻找IP地址
- 浏览器与服务器建立TCP连接
- 发送HTTP/HTTPS请求
- 服务器响应请求,发送响应信息
- 浏览器拿到解析html文件解析渲染页面
- HTTP/HTTPS请求结束,断开TCP连接
OSI七层网络分层模型
- 应用层:包括HTTP、HTTPS、SSH等协议
- 表示层:为不同终端的上层用户提供数据和信息正确的语法表示变换方法。如文本文件的ASCII格式和UTF-8格式。
- 会话层:主要为两个会话层实体进行会话,而进行的对话连接的管理服务。会话层会在OSI的模型负责会话检查点和恢复,它允许不同来源的信息流作适当的合并或同步化。会话层协议比如:SOCKS、SDP、PPTP等。
- 传输层:该层的协议为应用进程提供端到端的通信服务。它提供面向连接的数据流支持、可靠性、流量控制、多路复用等服务。传输层协议有TCP、UDP、SPX;
- 网络层:又称IP层,提供路由和寻址的功能,使两个终端系统能够互连且决定最佳路径,并具有一定的拥塞控制和流量控制的能力。
- 数据链路层:在两个网络实体之间提供数据链路连接的建立、维持和释放管理。构成数据链路数据单元(frame:数据帧或帧),并对帧定界、同步、收发顺序的控制。并且包括传输过程中的网络流量控制、差错检测和差错控制等方面。数据链路层会对物理层的原始数据进行数据封装-封装的数据信息中,包含了地址段和数据段等。地址段含有点对点发送节点和接收节点的地址(如MAC地址),控制段用来表示数格连接帧的类型,数据段包含实际要传输的数据。数据链路层的协议有:异步传输模式、VLAN(IEEE 802.1Q)、帧中继、高级资料链接控制、点对点协议、以太网(IEEE 802.3)、Wi-Fi(IEEE 802.11)等。数据链路层的设备有:网卡、交换机、桥接器(网桥)等。
- 物理层:双绞线、光纤、中继器等物理设备,用来传输电信号。
TCP/IP协议分层
- 应用层
- 传输层
- 网络层
- 数据链路层
- 物理层
HTTP1.0、1.1、2.0、3.0的区别
- 1.0: 1)浏览器与服务器只保持
短连接,浏览器的每次请求都需要与服务器建立一个TCP连接,都要经过三次握手,四次挥手。而且是串行请求。2)由于浏览器必须等待响应完成才能发起下一个请求,造成队头阻塞。如果某请求一直不到达,那么下一个请求就一直不发送。(高延迟-带来页面加载速度的降低) - 1.1: 1)支持
长连接,通过Connection: keep-alive保持HTTP连接不断开,避免重复建立TCP连接。keep-alive不会永远保持连接,它有一个持续时间,一般在服务器中配置(如apache),另外长连接需要客户端和服务器都支持时才有效;2)支持管道化传输,通过长连接实现一个TCP连接中同时处理多个HTTP请求;只要第一个请求发送出去了,不必等其回来,就可以发送第二个请求。服务器会按照请求的顺序去返回响应的内容,无法存在并行响应。(HTTP请求返回顺序按照服务器响应速度来排序);3)新增了一些请求方法,新增了一些请求头和响应头;4)支持断点续传,新增Range和Content-Range 头表示请求和响应的部分内容;5)加入缓存处理(响应头新字段Expires、Cache-Control);6)增加了重要的头Host字段,为了支持多虚拟主机的场景,使用同一个IP地址上可以托管多个域名,访问的都是同一个服务器,从而满足HTTP协议发展需要的更高级的特性。7)并且添加了其他请求方法:PUT、DELETE、OPTIONS等。缺点:1)队头阻塞;2)无状态通信模型(巨大的HTTP头部),也就是服务器端不保存客户端请求的任何状态信息,这样会造成一些需求频繁交互的应用程序难以实现,需要通过其他机制来保证状态的一致性等;3)明文传输-不安全;4)不支持服务端推送 - 2.0: 1)采用
二进制格式而非文本格式;2)多路复用,在同一个TCP连接上同时传输多条消息;每个请求和响应都被分配了唯一的标识符,称为“流(Stream)”; 3)使用HPACK算法报头压缩,降低开销;4)服务器推送,支持服务器主动将相关资源预测性的推送给客户端,以减少后续的请求和延迟。(例如HTML、CSS、JavaScript、图像和视频等文件)。 - 3.0:该协议基于UDP,又取了TCP中的精华,实现了既快又可靠的协议。1)传输层由TCP改成使用UDP传输;2)队头阻塞的问题解决更为彻底;3)切换网络时的保持连接:基于TCP的协议,由于切换网络之后,IP会改变,因而之前的连接不可能继续保持。而保持UDP的QUIC协议,则可以内建与TCP中不同的连接标识方法,从而在网络切换完成之后,恢复之前与服务器的连接;4)升级新的压缩算法。
- 多路复用与管道化传输的区别:多路复用为每个请求分配了唯一的标识符,通过标识符来识别分配响应。而管道化传输虽然同时处理多个请求,但是必须等待上一个请求响应返回之后才会返回下一个请求响应。
三次握手,四次挥手
- 三次挥手:
- 第一次握手(SYN=1,seq=X):客户端发送一个TCP的SYN(synchronous)标识位置的包,表示客户端打算连接服务器的端口,以及初始序号X,保存在包头的序列号seq(sequence number)字段里,发送完毕后,客户端进入
SYN_SEND状态 - 第二次握手(SYN=1,ACK=1,seq=y,ACKnum=x+1):服务器发回确认包(ACK)应答。即SYN标识位和ACK标识位均为1.服务器端选择自己ISN序列号,放到seq域里,同时将确认序号(Acknowledgement Number)设置为客户的ISN加1,即X+1。发送完毕后,服务器端进入
SYN_RCVD状态 - 第三次握手(ACK=1, ACKnum=y+1):客户端再次发送确认包(ACK),SYN标识位为0,ACK标识位为1,并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方,并且在数据段写入ISN+1。发送完毕后,客户端进入
ESTABLISHED状态,当服务器收到这个包时,也进入ESTABLISHED状态,TCP握手结束。
-
*为何是三次握手:**因为三次握手正好可以保证客户端知道服务端可以收到自己的请求,服务端也知道客户端可以收到自己的消息。再多就会造成资源浪费,再少就无法保证双方确认对方可以收到自己发出的消息。*阻止重复历史连接的初始化;同步双方的ISN(初始序列号);避免资源浪费。 详情看4.1 TCP 三次握手与四次挥手面试题 | 小林coding (xiaolincoding.com)
-
四次挥手:
- 第一次挥手(FIN=1,seq=x):客户端发出一个FIN标识位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。发送完毕后,客户端进入
FIN_WAIT_1状态 - 第二次挥手(ACK=1,ACKnum=x+1):服务器端确认客户端的FIN包,发送一个确认包,表明自己接收了客户端关闭连接的请求,但还没有准备好关闭连接。发送完毕后,服务器端进入
CLOSE_WAIT,客户端接收到确认包后,进入FIN_WAIT_2状态,等待服务器端关闭连接。 - 第三次挥手(FIN=1,seq=y):服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。发送完毕后,服务器端进入
LAST_ACK状态,等待来自客户端的最后一个ACK - 第四次挥手(ACK=1,ACKnum=y+1):客户端接收来自服务器端的关闭请求,发送一个确认包,并进入
TIME_WAIT状态,等待可能出现的要求重传的ACK包。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。客户端等待了2MSL(Maximum Segment Lifetime)之后,没有收到服务器端的ACK,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态
为什么挥手需要四次:1.关闭连接时,客户端向服务器端发送FIN时,仅仅表示客户端不再发送数据了,但还可以接收数据;2.服务端收到客户端的FIN时,先回一个ACK应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN报文给客户端来表示现在同意关闭连接
为什么TIME_WAIT是2MSL:MSL是报文最大生存时间,超过这个时间报文将被丢弃。客户端发送确认报文到服务端,再从服务端返回ACK到客户端,一来一回,正好2MSL。如果在TIME_WAIT时间内,因为客户端的ACK没有传输到服务端,客户端又接收到了服务端重发的FIN报文,那么2MSL时间将会重新计时。
HTTP和HTTPS
HTTPS经由HTTP进行通信,利用SSL/TLS来加密数据包。
- HTTPS的数据传输是加密的,而HTTP的数据传输是明文的,是不安全的;
- HTTPS需要SSL,SSL证书需要购买,功能越强大的证书费用越高;
- HTTPS由于需要涉及加密以及多次握手,性能方面不如HTTP;
- HTTP和HTTPS使用的连接方式不同,默认端口也不一样。HTTP是80,HTTPS是443。
- HTTPS的证书验证是非对称加密,实际的内容传输是对称加密
常见状态码
- 200:请求成功。一般用于GET、POST请求
- 301:Moved Permanently永久移动。请求的资源已经被永久移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替。
- 304:Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
- 401:Unauthorized 请求要求用户的身份认证
- 403:Forbidden 服务器理解客户端的请求,但是拒绝执行此请求
- 404: Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置“您所请求的资源无法找到”的个性页面
- 408: request time-out 服务器等待客户端发送的请求时间过长,超时
- 412: Precondition Failed 客户端请求信息的先决条件错误
- 500: Internal Server Error 服务器内部错误,无法完成请求
- 501: Not Implemented 服务器不支持请求的功能,无法完成请求
- 502: Bad Gateway 作为网关或者代理工具的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
- 503:Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
- 504: Gateway time-out充当网关或代理的服务器,未及时从远端服务器获取请求
- 505: HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
webpack plugins和loader的区别
- loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中。1)处理一个文件可以使用多个loader,loader的执行顺序和配置中的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行;2)第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数,最后执行的loader会返回此模块的js源码
- 在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果
- loader是文件转换器,将A文件编译成B文件。plugin是一个扩展器,针对的是loader结束后,webpack打包的整个过程,不直接操作文件,基于事件机制工作,它会监听webpack打包过程中的某些节点,执行广泛的任务
懒加载的方式
- IntersectionObserver
- getBoundingClientRect().top <= clientHeight
- offsetTop <= scrollTop + clientHeight
判断数据类型
- typeof:只能识别基础类型和引用类型
- constructor: 指向创建该实例对象的构造函数。
null和undefined没有constructor,constructor可以被改写 - instanceof: 只可以用来判断引用类型
- Object.prototype.toString.call: 返回为
[object XXX]
跨域
- proxy:使用代理去避开跨域请求,一般使用nginx。最常用的方式
- CORS:需要后端修改相关配置,一般修改
Access-Control-Allow-XXX等配置 - JSONP,即利用script,img等标签跨域
- postMessage