
前端面试题系列文章:
【12】「2023」性能优化相关知识点
【13】「2023」H5相关知识点
X-Mind原图地址:
一. HTTP协议
GET和POST请求的区别
Get 和 Post 请求是都 HTTP 协议请求方法,有以下区别
- 应用场景:
GET请求是一个幂等的请求,一般GET请求不会对服务器的数据造成影响,而POST不是一个幂等的请求,一般对于服务器会产生影响。 - 是否缓存:浏览器一般会对
GET请求做缓存,很少对POST请求做缓存 - 发送的报文格式:
GET请求报文的实体中为空,POST请求的报文实体部分一般为向服务端发送的数据 - 安全性:
GET会将请求参数放在 url 中,相对于POST是不太安全的(如果带了用户名密码等信息,可以通过浏览器记录查看到) - 请求长度:由于浏览器对 url 长度的限制,所以会影响
GET请求发送数据的长度(之前还出过线上问题) - 参数类型:
POST的参数支持更多的数据类型。
常见的HTTP请求头和响应头
HTTP 常见的请求头
- User-Agent: 浏览器的用户代理字符串
- Referer:发出请求的页面url
- Cookie: 当前页面设置的任何cookie
- Host: 页面请求的域名地址
- Connection: 浏览器与服务器之间的连接类型
- Accept: 浏览器能够处理的内容类型
- Accept-Charset: 浏览器能够处理的字符集
- Accept-Encoding: 浏览器能够处理的压缩编码
常见的响应头
- Date: 表示消息发送的时间
- server: 服务器名称
- Connection: 浏览器与服务器之间的连接类型
- content-type: 表示后面的文档属于什么MIME类型
OPTIONS请求方法及使用场景
OPTIONS是除了GET和POST之外的其中一种 HTTP请求方法。
OPTIONS请求方法的主要用途有两个:
- 获取服务器支持的所有HTTP请求方法
- 用来检查访问权限。例如:在进行
CORS跨域资源共享时,对于复杂请求,就是使用OPTIONS方法发送嗅探请求,以判断是否有对指定资源的访问权限。
HTTP1.0 和 HTTP1.1 之间的区别
- 连接方面: http1.0 默认使用非持久化连接,而 http1.1 默认使用持久化连接。http1.1 通过持久化连接使多个 http 请求复用同一个TCP连接,减少建立连接的开销。
- 缓存方面:http1.0 使用 If-Modified-Since、Expires 来作为缓存的判断标准,而 http1.1 中则使用 Etag、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略。
- 资源请求方面: 在 http1.0 中,存在浪费带宽的情况,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送回来了, http1.1 则在请求头中引入了 range ,它语序请求资源的某个部分,即返回码是 206 。
- http1.1 请求头中新增了
host字段,用来指定服务器的域名。随着虚拟主机技术的发展,一台物理服务器上可以存在多个虚拟主机,并且共享一个IP地址。 - http1.1 中相对于 http1.0 还新增了很多请求方法,如 PUT、HEAD、OPTIONS等。
HTTP1.1 和 HTTP2.0 的区别
-
二进制协议: http2.0是一个二进制协议。在 http1.1版中,报文的头信息必须是文本(ASCII编码),而数据体可以是文本,也可以是二进制。http2.0 则头信息和数据体都是二进制,并且统称为“帧”,可以分为头信息帧和数据帧。帧的概念是它实现多路复用的基础。
-
多路复用:http2.0 实现了多路复用。http2.0 仍然复用 TCP 连接,但是在一个连接里,客户端和服务端都可以同时发送多个请求或回应,而且不用按照顺序一一发送,这就避免了“队头阻塞”的问题。
-
数据流:http2.0 使用了数据流的概念。因为 http2.0 中的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能来自不同的请求。因此,必须要对数据包做出标记,指出他属于哪个请求。http2.0 将每个请求或回应的所有数据包,称为一个
数据流。每个数据流都有独一无二的编号,数据包发送时,都必须标记数据流ID,用来区分它属于哪个数据流。 -
头部信息压缩:http2.0实现了头信息压缩,由于http1.1协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 cookie 和 User Agent,一模一样的内容,每次请求都携带会浪费很多带宽。http2.0 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用gzip或 compress 压缩后再发送;另一方面, 客户端和服务端同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样的字段了,只发送索引号,来达到提高传输效率的目的。
-
服务器推送: http2.0 允许服务器在未经客户端的允许,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源,这样就可以相对减少一些延迟时间。这里需要注意的是 http2 下服务器主动推送的是静态资源,和 Websokcet 以及使用 SSE 等方式向客户端发送及时数据的推送是不同的。
队头阻塞是由 HTTP 基本的“请求-应答”模型所导致的。HTTP报文规定必须是“一发一收”,这就行程了一个先进先出的“串行”队列。队列中的请求是没有优先级的,只有入队的先后顺序,排在最前面的请求最先被发送,如果队首的请求因为处理了太慢耽误了时间,那么队列里后面的请求也不得不跟着一起等待。结果就是其他的请求承担了不应有的时间成本,造成了队头堵塞的现象。
对 keep-alive 的理解
HTTP1.0 中默认是在每次请求/应答的时候,都建立一次连接,完成请求后会立即断开,这就是短连接。当使用keep-alive模式时,keep-alive功能使客户端到服务端的连接持续有效,当出现后继请求时,就可以复用之前建立的连接,这就是长连接。
HTTP1.1开始默认使用keep-alive模式,什么时候会断开链接?进行tcp四次挥手呢?
服务器上有一个 keepalive_timeout 65 字段,可以控制,超过这个时间没有发送http请求,就会断开连接。
页面在加载有大量图片时,HTTP的加载表现
- 在
HTTP 1下,浏览器对同一个域名下最大TCP连接数为6,所以会请求多次。可以用多域名部署解决。这样可以提高同时请求的数据,加快页面的加载速度。 - 在
HTTP 2下,由于HTTP2支持多路复用,可以在一个TC连接中发送多个请求,大大加快了页面的加载速度。
HTTP2 是如何做到头部信息压缩的
一方面,使用HPACK算法,压缩头部内容。另一方面在客户端和服务端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,以后就不发送同样的字段了,只发送索引号。
二. TCP协议
几种TCP标志符
- SYN(synchronous建立联机)
- ACK(acknowledgement确认)
- PSH(push推送)
- FIN(finish结束)
- RST(reset重置)
- URG(urgent紧急)
TCP 3次握手
三次握手(Three-way Handshare)其实就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包。进行三次握手的主要作用是为了确认双发的收发能力是否正常、指定自己的初始化序列号,为后面的可靠传输做准备。
刚开始客户端处于 CLosed 的状态,服务端处于 Listen 状态。

-
第一次握手: 客户端给服务端发送
SYN=1,并且指明初始化序列号seq=x(也称ISN,Initial Sequence Number),服务器收到SYN=1知道,客户端要求建立连接。此时客户端处于SYN_SEND状态。 -
SYN=1,seq = x
第一次握手,由浏览器发起,告诉服务器我要发送请求了。
-
第二次握手: 服务端收到客户端的请求连接,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN。同时会把客户端的 ISN + 1 作为 ack的值,表示自己已经收到了客户端的 SYN。此时服务端除以
SYN_REVD状态。 -
SYN=1,ACK=1,ack=x+1, seq=y
第二次握手,由服务器发起,告诉浏览器已经确认,并且准备好接受请求了,你赶紧发吧。
-
第三次握手: 客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务端的 ISN + 1作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于
ESTABLISHED状态。服务器收到 ACK 报文之后,也处于ESTABLISHED状态。此时,双方已经建立起了连接。 -
ACK=1,ack=y+1, seq=x+1
第三次握手,由客户端发起,告诉浏览器,我马上发送了,请求准备接收
为什么要三次握手,两次不行吗?
-
保证客户端、服务端的收发能力都正常。
-
防止初始化的连接请求在网络节点中延迟到服务端已经关闭了之后才到达,服务端会错误的解释为一次新的连接,导致不不要的资源浪费。
详细过程:当客户端发送连接请求,但因为连接请求报文丢失,于是客户端重新发送连接请求。当第二次的请求确认,建立连接,数据传输完毕之后,正常释放连接。此时客户端一共发送了两个连接请求,第一个连接请求在某些网络节点滞留,延误到第二次连接释放以后才到达服务端,此时的服务端误认为是一次新的请求,于是向客户端发送确认报文段,同意建立连接。而客户端忽略服务端发来的确认,此时服务端一直在等待客户端发送数据,浪费资源。
-
防止半开连接,如果没有三次握手的确认机制的话,那么当某次请求发生丢失的话,任何一方只要把连接请求发出去了,都会误认为已经建立连接了。
TCP 4次挥手

刚开始双方都处于ESTABLISHED状态,假如是客户端先发起的关闭请求。四次挥手如下。
-
第一次挥手:客户端会发送一个
FIN=1报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。 -
FIN=1,seq=u
第一次挥手,告诉服务器我要断开连接,同时停止发送数据,等待服务端的确认
-
第二次挥手: 服务端收到
FIN=1报文后,会发送一个ACK=1,且把客户端的ISN+1作为ack,表明已经收到了客户端的报文了,此时服务端处于CLOSE_WAIT状态 -
ACK=1,ack=u+1,seq = v
第二次挥手,服务端进入
CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2状态,等待服务端发出的连接释放报文段。 -
第三次挥手:如果服务端也想断连接了(服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求),和客户端第一次挥手一样,发个
FIN=1的报文,且指定一个序列号。此时服务端处于LSAT_ACK(最后确认)状态,等待客户端的确认。 -
FIN=1,ACK=1,seq=w,ack=u+1
第三次挥手,服务端进入
LAST_ACK状态,等待客户端确认。 -
第四次挥手:客户端收到
FIN之后,会发送ACK报文,且把服务端的服务端的序列号值+1作为自己的ack,此时客户端处于TIME_WAIT状态。需要过一阵子(2MSL)以确保服务端收到自己的ACK报文后才会进入ClOSE状态,服务端收到ACK报文后,就处于CLOSE状态,关闭连接。 -
ACK=1,seq=u+1,ack=w+1
第四次挥手,客户端收到服务端的连接释放报文后,对此发出确认报文,客户端进入
TIME_WAIT状态。此时TCP并不会立马释放,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
为什么要4次挥手?
之前我们已经介绍了为什么建立连接需要3次握手。而断开连接需要4次挥手。
在3次握手的基础上,由于我们服务端收到FIN报文时,很可能存在没有发送完的数据。所以只能先发送一个ACK报文告诉客户端我已经收到了关闭请求,只有等到服务端所有的报文都发送完了,才能发送FIN报文。
三. HTTPS协议
HTTP 和 HTTPS 协议的区别
-
HTTP 是超文本传输协议,是明文传输的,HTTPS则是具有安全性的SSL加密传输协议。
-
HTTPS 协议需要CA证书,费用比较高,而HTTP协议不需要
-
使用的连接方式不同,端口号也不同HTTP默认使用80,HTTPS为443
HTTPS是在HTTP和TCP之间建立了一个安全层,HTTP与TCP通信的时候,必须先进过一个安全层,对数据包进行加密,然后将加密后的数据包传给TCP,相应的接收端的TCP必须将数据包解密,才能传给上面的HTTP。
为什么要使用HTTPS
由于HTTP协议采用明文信息传输,存在一些问题:
- HTTP采用明文进行数据传输
- HTTP无法验证报文的完整性
- HTTP无法做身份认证,可能遭遇中间人攻击
HTTPS如何解决问题:
- 通信加密:由于HTTP协议基于TCP/IP协议族,没有加密机制。但是可以通过 SSL(Secure Socket Layer,安全套接层) 建立安全的通信线路。
- 报文防篡改:使用加密能保证数据内容不被监听,但是数据任然有被篡改的可能,所以还需要用加密算法对数据进行完整性校验。
- 身份认证:虽然能保证数据和内容不被监听和篡改,但服务器是会对所有的请求都做出响应的。如果面对海量的请求,会造成服务器无法响应正常的请求。所以HTTPS还提供了”证书“的手段,用以证明服务端和客户端的身份。而证书一般是由第三方机构办法的,基本上不可能伪造。
HTTPS = HTTP + 加密 + 认证 + 完整性保护
TSL/SSL的工作原理,CA证书
TSL/SSL 全称 安全层传输协议(Transpost Layer Security),是介HTTP和TCP之间的一层安全协议,不影响原有的TCP协议和HTTP协议。
TSL/SSL的功能实现主要依赖三类基本算法:散列函数hash、对称加密、非对称加密,这三类算法的作用如下:
- 基于散列函数验证信息的完整性
- 对称加密采用协商的秘钥对数据加密
- 非对称加密实现身份认证和秘钥协商
(1)散列函数hash
常见的散列函数有MD5、SHA1、SHA256。该函数的特点是单项不可逆,对输入数据非常敏感,输出的长度固定,任何数据的修改都会改变散列函数的结果,所以可以用于信息篡改并验证数据的完整性。
(2)对称加密
对称加密的方法是,双方使用同一个秘钥对数据进行加密和解密。但是对称加密存在一个问题,如何保证秘钥传输的安全性,因为秘钥也是通过网络传输,一旦秘钥被其他人获取到,那么加密过程就毫无作用。那么就需要使用非对称加密了。
常见的对称加密算法有AES-CBC、DES、3DES、AES-GCM等。相同的秘钥可以用于信息的加密和解密。
(3)非对称加密
非对称加密的做法是,我们拥有两个秘钥,一个是公钥(一般放在客户端),一个是私钥(一般放在服务端)。公钥是公开的,私钥是保密的。用私钥加密的数据需要公钥才能解密,用公钥加密的数据,需要私钥才能解密。所以我们大可以把公钥'公之于众',让任何想和我们通信的客户都可以使用公钥进行数据加密,且不会被监听。但非对称加密的过程很慢,如果每次通信都使用非对称加密的话,反而会造成等待时间过长的问题。
所以在建立连接的时候采用的是非对称加密,通信的过程中采用的是对称加密。
常见的非对称加密算法有RSA、ECC、DH等。
(4)数字证书(CA证书)
现在的方法也不一定是安全的,因为没有办法确定拿到的公钥就一定是安全的公钥。可能存在一个中间人,截取了对方发送给我的公钥,而给我的是中间人自己伪造的公钥。当我们用伪造的公钥发送信息,中间人一定能解析出我们发送的信息,然后用正确的公钥伪装成我们向服务端发送信息,这样的话我们的信息就被中间人"偷看了"。为了解决这样的为题,可以使用数字证书。
- 首先使用一种Hash算法来对服务器上
公钥和其他信息进行加密,生成信息摘要- 然后让有公信力的CA权威机构用它的私钥对
信息摘要进行加密得到签名(私钥签名,公钥验签,所以我们只需要让客户端用认证机构给的公钥验签就能得到信息摘要)- 当客服端收到服务端返回的
数字证书(证书同时包括了公钥和其他信息+签名)时,先根据之前的Hash算法对公钥和其他信息进行加密,再次生成信息摘要,然后使用CA权威机构的公钥对数字证书中的签名进行解密,最后将解密的信息摘要和生成的摘要进行对比,就能发现得到的信息是否被修改了。
注意: CA权威机构本来也没多少个,浏览器内部都内置了各大CA机构的公钥信息。

HTTPS握手过程
如果使用HTTPS协议,在通信之前存在TSL的一个四次握手的过程。
- 第一次握手: 客户端向服务端发送使用的协议的版本号、一个随机数和可以使用的加密方法。
- 第二次握手:服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。
- 第三次握手:客户端收到后,首先检查数字证书是否有效,如果有效,则会生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务端,并且还会提供一个前面所有内容的hash值供服务端校验。
- 第四次握手:服务器接收后,使用自己的秘钥对数据解密,同时向客户端发送一个前面所有内容的hash值供客户端校验。
这时候,客户端和服务端都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后进行传输。
精炼版:
1.首先客户端向服务器发起HTTPS请求 2.服务端下发CA证书,和非对称加密后的公钥 3.客户端验证CA证书,并且会生成一个共享秘钥,对数据进行加密,同时用服务端的公钥对共享密钥进行加密 4.服务端收到信息后,先用私钥去解密加密的共享密钥,拿到共享秘钥,然后使用共享密钥解析出数据 5.之后客户端和服务器端就使用共享秘钥加密的内容内容进行交互了
四. 浏览器在按下回车键后都发生了些什么事?

解析URL
首先判断该URL是否是一个URL结构的字符串,如果是非URL结构的字符串,则会用浏览器默认的搜索引擎搜索该字符串。下面是一个URL的组成。

缓存判断
浏览器中的缓存分为两种:强缓存、协商缓存。
- 强缓存:直接浏览器缓存中拿到之前缓存下来的数据,不需要再次向服务端发送请求,通过
Expires(Http1.0)或Cache-Control(http1.1)字段来判断 - 协商缓存:协商缓存是当强缓存不生效的时,浏览器携带缓存标识想服务端发送请求,由服务端根据
Etag、Last-modified标识决定是否使用缓存(分别对应请求头中的If-Nonoe-Match和If-Modified-Since)。

DNS域名解析
我们目前只知道需要访问的域名,但要想在因特网中进行传输数据需要知道对方的IP地址。DNS域名解析系统可以将域名解析为IP地址。在解析IP地址的过程中存在两种查询方式:递归查询和迭代查询
- 递归查询:我们的浏览器、操作系统、路由器都会缓存一些URL对应的IP地址,统称为DNS高速缓存。这是为了加快DNS解析速度,使得不必每次都到根域名服务器中去查询。
- 迭代查询:迭代查询的方式就是,非本地的DNS服务器并不会自己向其他服务器进行查询,而是把能够解析该域名的服务器IP地址返回给客户端,客户端会不断的向这些服务器进行查询,直到查询到了位置。

我们本地缓存一些URL对应的IP地址,我们客户端到本地域名服务器是递归查询。向根域名服务器、顶级域名服务器、权限域名服务器查询的时候是迭代查询。
TCP三次握手
具体过程参考上述内容
HTTPS握手
具体过程参考上述内容
服务器处理请求并返回结果
服务器上通常会运行着响应请求的web server,常见web server的有Nginx,Apache,IIS。HTTP请求的资源一般可分为两种: 静态资源、动态资源。
静态资源:一般根据url的地址去服务器中寻找。
动态资源:就需要web server把不同请求委托给服务器上处理请求的应用程序进行处理,应用程序根据业务逻辑返回响应的数据或其他资源。
浏览器渲染页面

- DOM树构建:HTML解析器将HTML解析成DOM Tree。
- CSS解析器:CSS解析器将CSS解析成CSS Tree。
- 渲染树构建: 将CSS树和HTML树合并成Render Tree。
- 页面布局:对Layout Tree进行分层生成Layer Tree。
- 构件绘制列表:对每个Layer Tree生成绘制列表,并提交到合成线程。
- 合成线程将图层分成图块:合成线程将图层分成图块
- 光栅化:光栅化线程池中将「图块转化为位图」,光栅化之后会将会将绘制命令给浏览器进程。
- 页面绘制:浏览器进程根据绘图命令生成页面,并显示到显示器上。
TCP4次挥手
具体过程参考上述内容