点击蓝字 「前端小苑」关注我
网络知识是前端工程师需要掌握的,也是面试过程中的必考点,主要会考察的知识点有以下几类:
TCP协议相关
http发展的过程及各版本的特点
https相关
本文会按照这三类来梳理知识重点,以及常见的面试题。
TCP协议相关的知识考查,一般会围绕着三次握手和四次挥手展开。
UDP协议是面向无连接的,不需要在正式传递数据之前先连接起双方,具有不可靠性:不保证有序且不丢失的将数据传递到对端,并且没有任何控制流量的算法。优点是:相比TCP更轻便高效。
TCP建立连接和断开连接都需要进行握手,并在数据传输过程中,通过算法来保证数据的可靠性。
关于TCP的握手机制,一定不要死记硬背,要理解为什么这么设计,也就很容易记住了。
三次握手:
在客户端和服务器之间建立正常的TCP网络连接时,客户端首先会发出一个SYN消息,服务器使用SYN+ACK应答表示已经接收到这个消息,最后客户端再以ACK消息响应。这样在客户端和服务器之间才能建立起可靠的TCP连接,数据才可以在客户端和服务器之间传递。
建立连接时,客户端发送SYN包到服务器,等待服务器响应。(SYN 同步序列编号,是建立连接时使用的握手信号)。
服务器收到SYN包,使用ACK包进行确认应答,同时自己也会发送一个SYN包,即发送SYN+ACK包。
客户端收到服务器的SYN包,向服务器发送确认包ACK。此包发送完毕,代表TCP连接完成,完成了三次握手。
四次挥手:
四次挥手是释放TCP连接的握手过程。
客户端向服务端发送释放连接报文FIN,等待服务端确认,并停止发送数据。
服务器收到连接释放请求后,发送ACK包表示确认。(此状态下,表示客户端到服务器的连接已经释放,不再接受客户端发的数据了,但是服务器要是还发送数据,客户端依然接收)
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文FIN,等待客户端确认。
客户端收到服务器连接释放报文后,发出ACK包表示确认。此时客户端会进入TIME_WAIT状态,该状态将持续2MSL(最大报文段生存时间,指报文段在网络中生存的时间,超时将被抛弃)时间,若该时间段内没有服务器重发请求的话,就进入关闭状态,当服务端接收到ACK应答后,立即进入关闭状态。
借用《图解http》的一张图片:
在建立TCP连接时,Server端在接收到客户端的SYN连接请求后,可以直接发送SYN+ACK包,其中ACK作为应答,SYN用来发起连接请求。但是关闭连接时,服务端收到FIN包时,可能还没有发送完数据,不能立即关闭,所以只能先回复ACK包进行确认,告知客户端已经收到FIN报文。然后等到服务端数据都发送完毕,才能向客户端发送FIN包,所以需要四次握手。
三次是最小的安全次数,可以保证通信的双方都具有发送消息和接收响应的能力,发送方和接收方始终同步序号,可以实现可靠传输。
了解http的发展过程,可以帮助我们清楚http协议一直以来所存在的问题,以及所做的更新有什么实际意义。同时http/1、http/2的Keep-Alice、pipline、多路复用、ServerPush等特点也是我们需要掌握的知识,面试中也会经常提及。
http/0.9
没有HEADER等描述数据的信息,只规定了客户端和服务端的通信形式,只支持GET请求。
增加status code和header。
http/1.0 正式作为标准,传输内容格式不限制,增加了PUT、PATCH、HEAD、OPTIONS、DELETE 命令。
http/1.1 增加了持久连接(Keep-Alive)和管道机制。
http/2 增加了多路复用,服务端推送,头部️压缩,二进制帧数据传输等。
从上面http发展历程中,已经知道Keep-Alive是http/1.1增加的。 在没有Keep-Alive之前,http请求都是短连接,就是说每一次请求都要建立连接,请求完成后马上关闭连接,也就是我们上面说的三次握手和四次挥手过程,每次请求都要建立连接带来了资源的浪费,为了提高请求效率,于是有了Keep-Alice。
Keep—Alive允许在一定时间内,同一个域名多次请求数据,只建立一次http连接,其他请求可以复用这个连接通道,以达到提高请求效率的目的。
如果浏览器要向一个域名发送多个请求,需要在本地维护一个FIFO队列,完成了一个再发送下一个,这样就存在一个问题,服务端从完成一个请求开始回传,到收到下一个请求的这段时间内是处于空闲状态的。
于是提出了管道机制,试图将浏览器的请求一股脑的打包发给服务器,服务器就可以在出开完一个请求后,马上处理下一个,不会在之前说的空闲时间。
服务端收到多个管道请求后,需要按照接收顺序逐个响应。如果第一个请求处理特别慢,后续的响应的都会被阻塞着,这种情况称为「队首阻塞」。
服务端为了保证按顺序回传,通常需要缓存多个响应,从而占用更多的服务端资源,也更容易被攻击。
浏览器连续发送多个请求后,等待响应的这段时间,如果遇到网络异常导致连接断开,无法得知服务器处理情况,如果全部重试,可能会在服务端重复处理。
服务端和浏览器中间的代理设备不一定支持http管道,这给管道技术的普及带来了更多复杂性。
多路复用是http/2的特性,http/2最大的特点是使用二进制帧数据进行传输。
首先介绍http/2中几个重要的概念:
帧: http/2数据通信的最小单位。每个帧都包含帧首部,其中会标识当前帧所属的流。
消息: 指http/2中逻辑上的http消息。例如请求和响应等,消息由一个或多个帧组成。 、
流: 存在于连接中的虚拟通道。流可以承接双向消息,每个流都有一个唯一的整数id。
连接: 与http/1相同,都是指对应的TCP连接。
http/1的请求和响应报文,都是由起始行、首部和实体正文(可选)组成,各部分之间以文本换行符分隔。而http/2将请求和响应数据分隔成为更小的帧,并对他们采用二进制编码。
http/2 中,同域名下的所有请求都在一个连接上完成,这个连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,消息由一个或多个帧组成。多个帧之间可以乱序发送,然后根据帧首部的流标识可以重新组装。
http请求都是由状态行、请求/响应头部、消息主体三部分组成,一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩后的二进制文件(例如图片、音频),但是状态行和头部却没有经过任何压缩,直接以文本传输。对于一个请求而言,其headers所占的字节数也不少,尤其cookie,有些时候headers甚至超过了主体的大小。
头部压缩使用了 HPACK算法。会在支持http/2的浏览器和服务端之间:
维护一份相同的静态字典,包含常见的头部名称以及特别常见的头部名称和值的组合。
这样对完全匹配的头部键值对,例如:method:GET,就可以使用一个字符表示。对于头部名称可以匹配的,例如cookie: xxx,可以将名称使用一个字符表示。
维护一份相同的动态字典,可以动态的添加内容。
支持基于静态哈夫曼码表的哈夫曼编码(Huffman Coding)
支持服务端推送,意味着服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置再发起请求。
另外,服务端可以主动推送,客户端也有权选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。
关于http/2的带来的一些优化,推荐这三篇文章,内容不多,且是几年前的文章,但是文章很棒,可以让我们真正理解http/2带来的优化。
HTTP/2 与 WEB 性能优化(一)
HTTP/2 与 WEB 性能优化(二)
HTTP/2 与 WEB 性能优化(三)
想要真正的了解https,需要了解很多相关知识,比如SSL,对称加密,非对称加密,CA证书等知识。
https协议本身并不是一种新的协议,在HTTP跟TCP中间加多了一层加密层TLS/SSL。通常HTTP直接和TCP通信,而HTTPS要先将数据给到TLS/SSL,数据经加密后,再给到 TCP 进行传输。
在回答这个问题之前,我们先看下http请求存在哪些不足:
通信使用明文(不加密),内容可能会被窃听
不会验证通信方的身份,因此可能会遭遇伪装
无法保证报文的完整性,请求或响应的内容被篡改也无法知道
https就是对上面三点不足的解决,可以认为:
https == http + 加密 + 身份验证 + 数据完整性保护
那么,他们的 区别 就明显了:
http使用明文传输,https则是具有安全性的ssl加密传输协议
http不会验证通信放的身份,https会通过数字证书来验证身份
https可以保证数据的完整性,防止传输内容被中间人冒充或篡改
除以上外,http和https使用的端口也不同,前者使用80端口,后者使用443端口
客户端发送 Client Hello 报文开始SSL通信。请求中包含:客户端支持的SSL版本、加密组件列表(所使用的加密算法和秘钥长度等)。
服务端接收到请求后,以 Server Hello应答。应答报文中包含:从客户端提供的支持的SSL版本和加密组件中筛选出的SSL版本和加密组件。
之后服务端发送Certificate报文,报文中包含公开秘钥证书。
最后服务发送Server Hello Done报文,通知客户端最初阶段的SSL握手协商部分结束。
客户端会校验证书通过,创建随机数,并使用证书中提供的公钥对随机数(Pre-master secret)进行加密,并将加密后的随机数通过报文Client Key Exchange报文发送给服务端。
接着客户端继续发送Change Cipher Spec报文,告知服务器之后的通信会采用Pre-master secret秘钥进行加密。
客户端发送通过秘钥加密的Finish报文。表示握手阶段的客户端部分已经完成。
服务端通过客户端传入的随机数构造对称加密算法,同样发送Change Cipher Spec报文,告知客户端之后的通信会使用随机数秘钥进行加密。
服务端同样发送Finish报文。
客户端和服务器的Finish报文交换完毕后,SSL连接到此建立完成,之后就发起http协议了。
为了方便理解,简述一下上面过程:
客户端发起请求,服务端响应给用户端证书,证书中包含公钥;
客户端接收到证书后,生成随机数,通过公钥加密,将随机数发送给服务端,并凭随机数构造对称加密和服务端通信,并告知服务端此次通信后的通信都将使用随机数秘钥(Pre-master secret)进行加密;
服务端使用私钥解析随机数,并通过随机数构造对称加密算法,同样告知客户端之后的请求将使用随机数进行加密。
对称加密: 对称加密指的就是加密和解密使用同一个秘钥,所以叫做对称加密。对称加密只有一个秘钥。
非对称加密: 加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。
通过上面的握手过程可知,https在证书验证阶段,使用非对称加密来传输共享秘钥,之后的传输中都使用对称加密方式。原因是,非对称加密的加解密效率是非常低的,而http场景中通常端与端之间的交互量很大,对非对称加密的效率是无法忍受的。另外, HTTPS场景中只有服务端保存了私钥,一对公私钥只能实现单向加解密过程。因此 HTTPS 中的内容传输采用对称加密。
这个问题也可以问成 为什么需要CA认证机构颁发证书?
我们假设如果不存在认证机构,则人人都可以制造证书,这就带来了"中间人攻击"问题。
中间人攻击的过程如下:
客户端请求被劫持,将所有的请求发送到中间人的服务器
中间人服务器返回自己的证书
客户端创建随机数,使用中间人证书中的公钥进行加密发送给中间人服务器,中间人使用私钥对随机数解密并构造对称加密,对之后传输的内容进行加密传输
中间人通过客户端的随机数对客户端的数据进行解密
中间人与服务端建立合法的https连接(https握手过程),与服务端之间使用对称加密进行数据传输,拿到服务端的响应数据,并通过与服务端建立的对称加密的秘钥进行解密。
中间人再通过与客户端建立的对称加密对响应数据进行加密后传输给客户端
客户端通过与中间人建立的对称加密的秘钥对数据进行解密
简单来说,中间人攻击中,中间人首先伪装成服务端和客户端通信,然后又伪装成客户端和服务端进行通信(如图)。 整个过程中,由于缺少了证书的验证过程,虽然使用了https,但是传输的数据已经被监听,客户端却无法得知。
CA证书中会包含颁发机构信息、公钥、公司信息、域名、有效期等信息,浏览器验证证书:
首先就是要验证域名、有效期等信息是否正确
然后判断证书来源的合法性。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证
判断证书是否被篡改。需要与 CA 服务器进行校验
判断证书是否已吊销
以上任意一步都满足的情况下浏览器才认为证书是合法的。
有关gzip压缩、cdn、dns解析等,将在系列文章的「性能优化篇」介绍,欢迎持续关注。
你连 HTTPS 原理都不懂,还讲“中间人攻击”?:https://urlify.cn/zQj6f2
yu_shihu_
,计划创建一个前端交流群,供大家一起学习交流。系列文章传送门
更多文章请点击“阅读原文”
喜欢本文点个“在看”哟!