一、TCP连接的三次握手建立连接
TCP标志位:
- SYN:同步标志位,用于建立会话连接,同步序列号
- ACK:确认标志位,对已接收的数据包进行确认
- FIN:完成标志位,表示我已经没有数据要发送了,即将关闭连接
所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个报文:
- 第一次握手:客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入
SYN_SENT
状态,等待服务器端确认 - 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将TCP报文标志位SYN和ACK都置为1,ack=J+1,随机产生一个序号值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入
SYN_RCVD
状态。 - 第三次握手:
客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED
状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了
注意:我们上面写的ack和ACK,不是同一个概念:
- 小写的ack代表的是头部的确认号Acknowledge number, 缩写ack,是对上一个包的序号进行确认的号,ack=seq+1。
- 大写的ACK,则是我们上面说的TCP首部的标志位,用于标志的TCP包是否对上一个包进行了确认操作,如果确认了,则把ACK标志位设置成1
为什么需要三次握手
- 假设client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。
- 假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了
- 所以,采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接
详细请看:一文彻底搞懂 TCP三次握手、四次挥手过程及原理 - 知乎 (zhihu.com)
二、TCP的四次挥手关闭连接
四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开:
- 第一次挥手: Client端发起挥手请求,向Server端发送标志位是FIN报文段,设置序列号seq,此时,Client端进入
FIN_WAIT_1
状态,这表示Client端没有数据要发送给Server端了。 - 第二次分手:Server端收到了Client端发送的FIN报文段,向Client端返回一个标志位是ACK的报文段,ack设为seq加1,Client端进入
FIN_WAIT_2
状态,Server端告诉Client端,我确认并同意你的关闭请求。 - 第三次分手: Server端向Client端发送标志位是FIN的报文段,请求关闭连接,同时Client端进入
LAST_ACK
状态。 - 第四次分手 : Client端收到Server端发送的FIN报文段,向Server端发送标志位是ACK的报文段,然后Client端进入
TIME_WAIT
状态。Server端收到Client端的ACK报文段以后,就关闭连接。此时,Client端等待2MSL的时间后依然没有收到回复,则证明Server端已正常关闭,那好,Client端也可以关闭连接了
为什么连接的时候是三次握手,关闭的时候却是四次握手?
建立连接时,因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。所以建立连接只需要三次握手
关闭连接时,当Client端发出FIN报文段时,只是表示Client端告诉Server端数据已经发送完毕了。当Server端收到FIN报文并返回ACK报文段,表示它已经知道Client端没有数据发送了,但是Server端还是可以发送数据到Client端的,所以Server很可能并不会立即关闭SOCKET,直到Server端把数据也发送完毕。当Server端也发送了FIN报文段时,这个时候就表示Server端也没有数据要发送了,就会告诉Client端,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接
为什么要等待2MSL?
MSL:报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。有以下两个原因:
- 第一点:保证TCP协议的全双工连接能够可靠关闭:
由于IP协议的不可靠性或者是其它网络原因,导致了Server端没有收到Client端的ACK报文,那么Server端就会在超时之后重新发送FIN,如果此时Client端的连接已经关闭处于CLOESD
状态,那么重发的FIN就找不到对应的连接了,从而导致连接错乱,所以,Client端发送完最后的ACK不能直接进入CLOSED
状态,而要保持TIME_WAIT
,当再次收到FIN的收,能够保证对方收到ACK,最后正确关闭连接。 - 第二点:保证这次连接的重复数据段从网络中消失
如果Client端发送最后的ACK直接进入CLOSED
状态,然后又再向Server端发起一个新连接,这时不能保证新连接的与刚关闭的连接的端口号是不同的,也就是新连接和老连接的端口号可能一样了,那么就可能出现问题:如果前一次的连接某些数据滞留在网络中,这些延迟数据在建立新连接后到达Client端,由于新老连接的端口号和IP都一样,TCP协议就认为延迟数据是属于新连接的,新连接就会接收到脏数据,这样就会导致数据包混乱。所以TCP连接需要在TIME_WAIT状态等待2倍MSL,才能保证本次连接的所有数据在网络中消失。
三、http1.0
- 特点:每次请求和响应后会销毁TCP连接,前一个响应完成后才能发送下一个请求
- 无法复用连接,每次请求都需要创建新的TCP连接
- 队头堵塞。前一个请求被堵塞了,后续请求无法发送
四、http1.1
- 长连接。允许在增加请求头connection:keep-alive。后面的客户端请求在一段时间内可以复用之前的TCP连接
- 管道化。可以不等第一个请求响应继续发送后面的请求,但响应的顺序还是按照请求的顺序返回
- 缓存处理。新增响应头 cache-control,用于实现客户端缓存
- 断点传输。在上传/下载资源时,如果资源过大,将其分割为多个部分,分别上传/下载
为什么 HTTP1.1 不能实现多路复用
HTTP1.1是通过文本传入,没有流的概念。在进行并行传输(多路复用)传递数据时,接收方不能区分多个响应分别对应的请求,所以无法将多个响应的结果进行组装
五、http2
- 二进制分帧。将传输的消息分为更小的二进制帧,每帧都有自己的序号,被打乱也能在另一端重组。
- 多路复用(并行传输)。在同一域名下所有访问都是从同一个 tcp 连接中走,并且不再有队头阻塞问题,也无须遵守响应顺序。
- 头部压缩。http2.0 通过字典的形式,将头部中的常见信息替换为更少的字符,极大的减少了头部的数据量,从而实现更小的传输量。
- 允许服务端直接推送消息给客户端,无需客户端明确的请求。
多路复用
在http2.0中,有两个十分重要的概念,帧和流。帧是数据传输中最小的单位,每个帧会标志出自己属于哪个流,多个数据帧就构成了数据流。多路复用就是在一个TCP连接中允许多个流同时存在,也就是多个请求,接收端可以通过帧的标识知道属于哪个请求。通过这个功能可以解决http旧版中对头堵塞的问题,提高了传输的性能。
六、HTTPS握手过程
- 客户端请求服务器,并告诉自己采用的加密方式和密钥长度等信息
- 服务器响应,将公钥和证书发送给客户端
- 客户端检查证书后,生成会话密钥,并用服务器传回来的公钥加密这个会话密钥,之后传给服务器。
- 服务器用私钥解密会话密钥,并用会话密钥加密信息发送给客户端,表示已经准备就绪。
- 客户端用会话密钥解密服务端发送的信息后,知道服务器已准备就绪
- 后续客户端和服务器用会话密钥加密信息进行传递
- 密钥:密钥是一种参数,它是在明文转换成密文或密文转换成明文的算法中输入的参数。分为对称密钥和非对称密钥,分别用于对称加密和非对称加密。
- 对称加密:又称私钥加密,即信息的发送方和接受方使用同一个密钥对信息进行加密。
- 非对称加密:又称公钥加密。即信息的发送方和接收方使用一堆密钥,即公钥和私钥。私钥自己保存,不对外泄露。公钥指公共的密钥,即任何人都可以获得。用公钥对信息进行加密,用私钥解密。
- 摘要:摘要算法又称哈希/散列算法。它通过一个函数,将任意长度的数据转换为一个固定长度的数据串(通常用十六进制表示)。算法不可逆。
七、HTTPS 握手过程中,客户端如何验证证书的合法性
- 校验颁发证书的机构是否受客户端信任
- 校验证书是否被吊销
- 对比系统时间,判断证书是否过期
- 通过校验对方是否存在私钥,判断证书的网站域名是否与证书颁发的域名一致
为什么需要CA机构对证书签名
主要是为了增加证书的可信性。如果没有权威机构对证书进行签名,客户端就不知道证书是否是伪造的,HTTPS将变得毫无意义。
HTTPS中间人攻击
针对HTTPS的攻击主要有SSL劫持攻击和SSL剥离攻击。
- SSL劫持攻击:攻击者劫持了客户端和服务器之间的连接,将服务器的合法证书替换为伪造的证书,从而获取客户端和服务器之间传递的信息。这种方式一般容易被用户发现,浏览器会明确的提示证书错误,但某些用户安全意识不强,可能会点击继续浏览,从而达到攻击目的。
- SSL剥离攻击:攻击者劫持了客户端和服务器之间的连接,攻击者保持自己和服务器之间的 HTTPS 连接,但发送给客户端普通的 HTTP 连接,由于 HTTP 连接是明文传输的,即可获取客户端传输的所有明文数据。
如何劫持https请求
https有防篡改的特点,只要浏览器证书验证的过程是正确的,很难在用户不察觉的情况下进行攻击。如果能更改浏览器的证书验证过程,便有可能实现https中间人攻击
要劫持https,必须要伪造一个证书,并且要让用户信任这个证书(如何病毒,恶意软件,诱导)。一旦证书被信任后,就可以使用普通中间人攻击的方式,利用伪造的证书进行攻击
八、HTTP状态码301和302的应用场景
301表示永久重定向,302表示临时重定向。
当浏览器收到的是301,会缓存重定向的地址,之后不会再重新请求服务器,而是使用缓存的地址。浏览器收到302,不会缓存重定向地址。
因此301适合永久转移的场景:域名变更;302适合临时转移的场景:首页临时跳转到活动页。
HTTP状态码 304 和 403
- 304:资源未修改,服务器告诉客户端请求的资源未修改,客户端会使用之前的缓存。在304状态码的响应中,服务器不会携带任何的响应体。
- 403:不允许访问,服务器告诉客户端这个资源目前不允许访问,这个状态码一般出现在权限不足的情况下。
九、cookie和token都放在header里面,为什么不会劫持token
浏览器会自动发送cookie给服务器,攻击者会利用这点进行csrf攻击
token一般不放在cookie里面,放在localstorage,在请求时也是自动添加到请求头里面,因此不容易引发crsf。
十、JWT(JSON Web Tokens)
JWT的原理
服务器认证后,生成一个JSON对象,发给用户,之后用户跟服务器通信,服务器完全靠这个JSON对象认定用户身份。为了防止用户篡改数据,服务器在生成对象时,会加上签名。
JWT的数据结构
JWT是一个很长的字符串,中间用 .
分为三部分
Header(头部).Payload(负载).Signature(签名)
- Header : 部分是一个 JSON 对象,描述 JWT 的元数据
- Payload: 部分也是一个 JSON 对象,用来存放实际需要传递的数据
- Signature: 使用特定的算法对前面两部分进行加密,得到的加密结果,防止数据篡改
JWT的特点
- JWT默认是不加密的,生成原始token后,也可以再加密一次
- JWT在不加密的情况下,不要将秘密数据写入JWT
- 由于服务器不再保存session状态,因此无法在使用中更改或废止token。也就是说,一旦JWT签发了,在到期之前始终会生效,除非服务器部署额外的逻辑。
- JWT本身包含了认证信息,一旦泄露,任何人都可以获取令牌的权限。为了减少盗用,JWT的到期时间应该设置的比较短。对一些比较重要的权限,使用时应该对用户进行再次验证。
- 为了减少盗用,JWT不应该使用HTTP明文传输,应该是HTTPS协议传输。
详细请看:前端面试查漏补缺--(十) 前端鉴权 - 掘金 (juejin.cn)
十一、单点登录
单点登录(Single Sign On),简称SSO,在多个应用系统中,用户只需要登录一次就可以访问所有受信任的应用系统
SSO一般都需要一个统一的认证中心(passport),子系统的登录均通过passport,子系统本身不参与登录,当有一个系统成功登录后,passport会颁发一个令牌给各个子系统,子系统可以根据令牌获取各自受保护的资源。为了减少登录,各个子系统在被passport授权后会,会创建一个局部会话,在一定时间内不需要再向passport认证
单点登录流程
- 用户访问系统 1 的受保护资源,系统 1 发现用户未登录,跳转至 sso 认证中心,并将自己的地址作为参数
- sso 认证中心发现用户未登录,将用户引导至登录页面
- 用户输入用户名密码提交登录申请
- sso 认证中心校验用户信息,创建用户与 sso 认证中心之间的会话,称为全局会话,同时创建授权令牌
- sso 认证中心带着令牌跳转会最初的请求地址(系统 1)
- 系统 1 拿到令牌,去 sso 认证中心校验令牌是否有效
- sso 认证中心校验令牌,返回有效,注册系统 1
- 系统 1 使用该令牌创建与用户的会话,称为局部会话,返回受保护资源
- 用户访问系统 2 的受保护资源
- 系统 2 发现用户未登录,跳转至 sso 认证中心,并将自己的地址作为参数
- sso 认证中心发现用户已登录,跳转回系统 2 的地址,并附上令牌
- 系统 2 拿到令牌,去 sso 认证中心校验令牌是否有效
- sso 认证中心校验令牌,返回有效,注册系统 2
- 系统 2 使用该令牌创建与用户的局部会话,返回受保护资源
详细请看:前端面试查漏补缺--(十) 前端鉴权 - 掘金 (juejin.cn)
十二、文件上传如何做断点续传
客户端将上传文件的二进制进行切片,每片数据都按顺序进行序号标识,上传文件的时候把序号上传,服务器收到文件后将文件保存为临时文件,并记录每个文件上的序号。
若上传中止,等到下次上传时,可以向服务器索要已上传文件的序号,客户端仅需要上传剩余的文件分片即可。
当全部分片上传完成后,服务器根据序号重组出完整的文件,并删除所有分片文件
十三、SSL和TSL
它们都是用于保证信息安全传输的协议,位于应用层和传输层之间,TSL是SSL的升级版。
- 客户端向服务器索要公钥
- 客户端用公钥加密会话密钥,服务器用私钥解密会话密钥
- 传输的数据使用会话密钥加密,然后传输,接收方使用会话密钥解密得到传输的数据。
十四、网络的五层模型
从上到下分别是:应用层、传输层、网络层、数据链路层、物理层。在发送消息时,每次从上到下进行加包,接收消息时,从下到上进行解包,得到原始信息。
- 应用层:网页、邮件、文件中心等等,它的代表协议有 http、smtp、pop3、ftp、DNS 等等
- 传输层主要面向传输过程,比如 TCP 协议是为了保证可靠的传输,而 UDP 协议则是一种无连接的广播,它们提供了不同的传输方式
- 网络层主要解决如何定位目标的问题,比如 IP、ICMP、ARP 等等
- 数据链路层的作用是将数据可靠的传输到目标,比如常见的以太网协议、P2P 协议
- 物理层是要规范网络两端使用的物理设备,比如蓝牙、wifi、光纤、网线接头等等
十五、GET和POST的区别
从HTTP的角度来说,GET和POST没什么本质的区别。之所以在开发中会产生区别,是由于浏览器的默认行为造成中。
GET和POST的区别:
-
浏览器在发送 GET 请求时,不会附带请求体
-
GET 请求的传递信息量有限,适合传递少量数据;POST 请求的传递信息量是没有限制的,适合传输大量数据。
-
GET 请求只能传递 ASCII 数据,遇到非 ASCII 数据需要进行编码;POST 请求没有限制
-
大部分 GET 请求传递的数据都附带在 path 参数中,能够通过分享地址完整的重现页面,但同时也暴露了数据,若有敏感数据传递,不应该使用 GET 请求,至少不应该放到 path 中
-
刷新页面时,若当前的页面是通过 POST 请求得到的,则浏览器会提示用户是否重新提交。若是 GET 请求得到的页面则没有提示。
-
GET 请求的地址可以被保存为浏览器书签,POST 不可以
十六、HTTP劫持、DNS劫持
http劫持是指攻击者在对客户端和服务器同时建立了连接通道,通过某种方式让客户端的请求发送到攻击者的服务器,然后攻击者就有了控制响应内容的能力,从而在客户端展示错误的信息。比如在页面上添加一些广告
DNS劫持是指攻击者劫持了DNS服务器,获得了修改DNS解析记录的权限,从而导致客户端请求的域名被解析到错误的服务器,攻击者通过这种方式窃取用户资料或破坏原有正常服务
十七、XSS攻击和CSRF攻击
XSS是指跨站脚本攻击,攻击者利用站点的漏洞,在表单提交时,向表单里面添加一些恶意脚本。当其他正常用户访问网站时,页面出现攻击者的恶意脚本,脚本被执行,使页面被破坏或用户信息被窃取。
要防范XSS攻击需要在服务器过滤脚本,将一些危险的元素或属性去掉或对元素进行HTML实体编码。
CSRF是跨站请求伪造攻击,是一种挟制用户在已经登录的web应用上执行非其本意的操作的攻击方法。如:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的
防范CSRF攻击:
-
验证码;强制用户必须与应用进行交互,才能完成最终请求。此种方式能很好的遏制 csrf,但是用户体验比较差。
-
Referer check:请求来源限制,此种方法成本最低,但是并不能保证 100% 有效,因为服务器并不是什么时候都能取到 Referer,而且低版本的浏览器存在伪造 Referer 的风险。
-
token:token 验证的 CSRF 防御机制是公认最合适的方案
十八、WebSocket协议
WebSocket协议是HTML5带来的新协议,相对于HTTP,它是一个持久连接的协议。它利用http协议完成握手后,通过TCP连接通道发送消息,使用WebSocket协议可以实现服务器主动推送消息
- 发送http请求,请求行中path需要使用ws:开头的地址
- 请求头中分别加入upgrade、connection、Sec-WebSocket-Key、Sec-WebSocket-Version标记
- 服务器收到请求,发现是一个WebSocket协议的连接,响应行中包含Switching Protocols,同时响应头中包含upgrade、connection、Sec-WebSocket-Accept标记
- 当客户端收到响应后即可完成握手,随后使用建立的 TCP 连接直接发送和接收消息
和传统的http相比有什么优势
当页面需要观察实时数据的变化时(如K线图或聊天),过去经常使用两种方法实现:
- 短轮询:客户端每隔一段时间向服务器发送请求,询问有没有新数据
- 长轮询:发送一次请求,服务器将其挂起,等到有消息时再响应。响应后,客户端又发送一次请求,重复流程。
这是因为http协议,响应必须在请求之后发生,服务器是被动的,无法主动推送信息。让客户端不断的发送请求,浪费了资源。
WebSocket就是为了解决这个问题,它利用http完成握手之后,就可以与服务器建立持久的连接,服务器在有需要的时候可以主动推送消息给客户端,这样占用的资源最少,同时实时性最高
十九、在浏览器地址栏输入地址,并按下回车,之后发生了什么?
- 浏览器自动补全协议、端口。
- 浏览器自动完成url编码
- 浏览器根据地址查找本地缓存,根据缓存规则看是否命中缓存。如果命中,则直接使用缓存,不再发起请求
- 没有命中,根据DNS解析出服务器的IP地址
- 浏览器向服务器发出建立TCP连接的申请,完成三次握手后,建立连接。
- 若使用了HTTPS协议,还会进行SSL握手,建立加密通道
- 浏览器设置好请求头,协议,cookie,发起请求
- 服务器处理请求,响应一个http报文给浏览器
- 浏览器根据使用协议的版本,connection字段的约定,决定是否保留 TCP 连接
- 浏览器根据响应状态码决定如何处理这一次响应
- 浏览器根据响应头的Content-Type字段识别响应类型,如果是text/html,则对响应体的内容进行HTML解析,否则做其他的处理
- 浏览器根据响应头的其他内容完成缓存、cookie的设置
- 浏览器从上到下开始解析HTML,如果遇到外部链接,进一步请求资源
- 解析过程生成DOM树、CSSOM叔,一边生成,一边把两者合并成渲染树(Render Tree),随后对渲染树中的每个节点计算位置和大小(reflow),最后把每个节点利用GPU渲染到屏幕(repaint)
- 在解析过程中还会触发一系列的事件,当DOM树完成后会触发DOMContentLoaded事件,当所有资源加载完毕后会触发load事件
DNS域名解析
DNS域名解析是指把域名解析成服务器IP地址的过程
在具体的实现上,域名解析是由多次层级的服务器共同完成的。在查找域名时,客户端会先查找自身的DNS映射表,如果找不到解析记录,就使用用户配置的DNS服务器,若目标DNS服务器找不到,则继续往上一个层级查找,直到到达根域名服务器。根域名服务器会根据域名的类型,将解析任务分发到对应的子域名服务器查找,直到找到解析记录为止。
二十、网页验证码
验证码主要是让服务器区分请求是人发送的还是机器发送的,可以避免某些程序恶意提交大量信息到服务器,导致服务器产生大量垃圾数据。有时,验证码也可以防止机器暴力破解用户密码,它通过短时间不断提交登录信息,尝试各种组合来破解密码。
21、cookie、localStorage、sessionStorage的区别
- 存储的时间有效期不同。cookie的有效期是可以设置的,默认是关闭浏览器后失效。sessionStorage的有效期仅是当前页,关闭会话页或浏览器后失效。localStorage的有效期在不手动删除的情况下一直有效
- 储存的大小不同。cookie的储存大小是4k左右,localStorage和sessionStorage是5M
- 与服务端的通信。cookie会被携带在http的请求头中,参与服务端的通信。localStorage和sessionStorage是单纯的前端存储,不参与通信。
- 对于浏览器的支持。cookie出现的比较早,对于所有的浏览器都支持,localStorage和sessionStorage出现的比较晚,对于版本低的浏览器不支持(如IE8以下的浏览器)
22、HTTP常见的请求方法
- GET,向服务器请求资源
- POST,向服务器提交信息,通常用于产生新的数据
- PUT,修改服务器的数据
- DELETE,删除服务器的数据
- OPTIONS,发生在跨域的预检请求中,表示客户端向服务器申请跨域提交
- TRACE,回显服务器收到的请求,主要用于测试和诊断
- CONNECT,用于建立连接管道,通常在代理场景中使用,网页中很少用到
23、优化网络性能
- 优化打包体积。利用一些工具压缩打包体积
- 多目标打包,利用一些插件,针对不同的浏览器打包出不同的兼容性版本
- 压缩。服务器的各种文件可以压缩后再响应给客户端,只要压缩时间小于优化的传输时间,压缩就是可行的
- CDN,利用CDN可以大幅减少静态资源的访问时间。对于公共库的访问,可以使用知名的CDN资源
- 缓存。对于除HTML之外的静态文件,均开启协商缓存,利用构建工具打包产生的文件hash值来置换缓存
- http2。开启http2后利用头部压缩、多路复用,利用带宽传递大量文件
- 利用defer、async让页面尽早加载js文件
- perfetch、perload。利用perfetch让页面在空闲时预先下载其他页面使用的资源,利用perload让页面预先下载本页面可能使用的资源