用户从输入 URL 到显示页面这个过程发生了什么
- 浏览器校验 URL 格式
- 浏览器的网络进程会先查找缓存中是否存在该资源,有的话直接返回,如果没有的话会发起 URL 请求
- DNS解析,查询这个域名的 IP 地址,如果协议是 HTTPS,还需要建立 TLS 连接
- TCP连接,利用目标服务器的 IP 地址 通过 TCP 三次握手建立连接
- 构建HTTP请求报文,发送 HTTP 请求
- 服务器处理请求并返回响应报文
- 断开TCP连接,数据传输完成,正常情况下 TCP 将四次挥手断开连接。但是如果浏览器或者服务器在HTTP头部加上 Connection: keep-alive,TCP 就会一直保持连接。
- 浏览器的网络进程接收到响应报文后进行解析,如果状态码是 301 或者 302,则需要取得响应头中的 Location 对应的地址进行重定向,再重新发起请求
- 渲染页面,浏览器首先解析 HTML 生成 DOM 树,解析 CSS 生成 CSSOM 树,然后 DOM 树和 CSSOM 树进行合成生成渲染树,通过渲染树进行布局并且计算每个节点信息,绘制页面
UDP
面向报文
- UDP 是一个面向报文(报文可以理解为一段段的数据)的协议。意思就是 UDP 只是报文的搬运工,不会对报文进行任何拆分和拼接操作。
不可靠性
- UDP 是无连接的,也就是说通信不需要建立和断开连接。
- UDP 也是不可靠的。协议收到什么数据就传递什么数据,并且也不会备份数据,对方能不能收到是不关心的
- UDP 没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP。
高效
因为 UDP 没有 TCP 那么复杂,需要保证数据不丢失且有序到达。所以 UDP 的头部开销小,只有八字节,相比 TCP 的至少二十字节要少得多,在传输数据报文时是很高效的。
传输方式
UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
TCP
TCP三次握手
- 第一次握手:客户端向服务端发送带有SYN(连接请求)标志的数据包
- 第二次握手:服务端向客户端发送带有SYN/ACK(应答)标志的数据包
- 第三次握手:客户端向服务端发送带有带有ACK标志的数据包
TCP四次挥手
- 客户端发送一个FIN(断开连接请求),用来关闭客户端到服务器的数据传送
- 服务器收到这个FIN,它发回一个ACK(应答)
- 服务器关闭与客户端的连接,发送一个FIN给客户端
- 客户端发回ACK报文确认,进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有收到 服务器 的重发请求的话,就进入 CLOSED 状态。当 服务器 收到确认应答后,也便进入 CLOSED 状态。
为什么客户端要进入 TIME-WAIT 状态,等待 2MSL 时间后才进入 CLOSED 状态?
为了保证 服务器 能收到 客户端 的确认应答。若 客户端 发完确认应答后直接进入 CLOSED 状态,如果确认应答因为网络问题一直没有到达,那么会造成 服务器 不能正常关闭。
TCP/IP四层网络模型
TCP/IP模型是一系列网络协议的总称,这些协议的目的是使得计算机之间可以进行信息交换
从上到下分别是
- 应用层:负责传送各种最终形态的数据,是直接与用户信息打交道的层,主要协议是 http协议
- 传输层:负责传送文本数据,主要协议是 TCP协议
- 网络层:负责分配地址和传送二进制数据,主要协议是 IP协议
- 链路层:负责建立电路连接,是整个网络的物理基础,典型的 以太网协议
TCP/IP模型是一系列网络协议的总称,这些协议的目的是使得计算机之间可以进行信息交换
从上到下分别是
- 应用层:负责传送各种最终形态的数据,是直接与用户信息打交道的层,主要协议是 http协议
- 传输层:负责传送文本数据,主要协议是 TCP协议
- 网络层:负责分配地址和传送二进制数据,主要协议是 IP协议
- 链路层:负责建立电路连接,是整个网络的物理基础,典型的 以太网协议
OSI七层模型
从上到下分别是
- 应用层:文件传输,常用协议 HTTP
- 表示层:数据格式化,代码转换,数据加密
- 会话层:建立,解除会话
- 传输层:提供端对端的接口,TCP、UDP
- 网络层:为数据包选择路由,IP
- 数据链路层:传输有地址的帧
- 物理层:二进制的数据形式在物理媒体上传输数据
流量控制
在 TCP 链接中,对于发送端和接收端而言,TCP 需要把发送的数据放到发送缓存区, 将接收的数据放到接收缓存区。而经常会存在发送端发送过多,而接收端无法消化的情况,所以就需要流量控制,就是在通过接收缓存区的大小,控制发送端的发送。如果对方的接收缓存区满了,就不能再继续发送了。而这种流量控制的过程就需要在发送端维护一个发送窗口,在接收端维持一个接收窗口。
拥塞处理
原因是有可能整个网络环境特别差,容易丢包,那么发送端就应该注意了。 主要用三种方法:
- 慢启动阈值 + 拥塞避免
- 快速重传
- 快速回复
慢启动阈值 + 拥塞避免
对于拥塞控制来说,TCP 主要维护两个核心状态: 拥塞窗口(cwnd) 慢启动阈值(ssthresh) 在发送端使用拥塞窗口来控制发送窗口的大小。 然后采用一种比较保守的慢启动算法来慢慢适应这个网络,在开始传输的一段时间,发送端和接收端会首先通过三次握手建立连接,确定各自接收窗口大小,然后初始化双方的拥塞窗口,接着每经过一轮 RTT(收发时延),拥塞窗口大小翻倍,直到达到慢启动阈值。 然后开始进行拥塞避免,拥塞避免具体的做法就是之前每一轮 RTT,拥塞窗口翻倍,现在每一轮就加一个。
快速重传
在 TCP 传输过程中,如果发生了丢包,接收端就会发送之前重复 ACK,比如 第 5 个包丢了,6、7 达到,然后接收端会为 5,6,7 都发送第四个包的 ACK,这个时候发送端受到了 3 个重复的 ACK,意识到丢包了,就会马上进行重传,而不用等到 RTO (超时重传的时间) 选择性重传:报文首部可选性中加入 SACK 属性,通过 left edge 和 right edge 标志那些包到了,然后重传没到的包
快速恢复
如果发送端收到了 3 个重复的 ACK,发现了丢包,觉得现在的网络状况已经进入拥塞状态了,那么就会进入快速恢复阶段: 会将拥塞阈值降低为 拥塞窗口的一半 然后拥塞窗口大小变为拥塞阈值 接着 拥塞窗口再进行线性增加,以适应网络状况
TCP 和 UDP 的区别
TCP是一个面向连接的、可靠的、基于字节流的传输层协议。 而UDP是一个面向无连接的传输层协议。(就这么简单,其它TCP的特性也就没有了)。 具体来分析,和 UDP 相比,TCP 有三大核心特性:
面向连接。所谓的连接,指的是客户端和服务器的连接,在双方互相通信之前,TCP 需要三次握手建立连接,而 UDP 没有相应建立连接的过程。可靠性。TCP 花了非常多的功夫保证连接的可靠,这个可靠性体现在哪些方面呢?一个是有状态,另一个是可控制。TCP 会精准记录哪些数据发送了,哪些数据被对方接收了,哪些没有被接收到,而且保证数据包按序到达,不允许半点差错。这是有状态。当意识到丢包了或者网络环境不佳,TCP 会根据具体情况调整自己的行为,控制自己的发送速度或者重发。这是可控制。相应的,UDP 就是无状态, 不可控的。面向字节流。UDP 的数据传输是基于数据报的,这是因为仅仅只是继承了 IP 层的特性,而 TCP 为了维护状态,将一个个 IP 包变成了字节流。
HTTP
什么是HTTP协议
HTTP 协议(超文本传输协议)是个无状态协议,不会保存状态,基于tcp的协议
http传输流
- 首先发送端在应用层(HTTP协议)发起HTTP请求
- 接着传输层(TCP协议)把从应用层收到的数据(HTTP请求报文)进行分割,并在各个报文上打上
标记序号及端口号后转发个网络层 - 在网络层(IP协议)增加作为通信目的地的MAC地址后转发给链路层
- 接收端的服务器在链路层收到数据,按序往上层发送,一直到应用层
http缓存机制
HTTP缓存即是浏览器第一次向一个服务器发起HTTP请求后,服务器会返回请求的资源,并且在响应头中添加一些有关缓存的字段如:cache-control,expires,last-modifed,ETag,Date等,之后浏览器再向该服务器请求资源就可以视情况使用强缓存和协商缓存
强缓存
浏览器直接从本地缓存中获取数据,不与服务器进行交互
通过 Cache-Control 验证强缓存是否可用
- no-store:不允许缓存 (用于秒杀页面等变化频率非常高的场景)
- no-cache:可以缓存,使用前必须要去服务端验证是否过期,是否是最新版本
- must-revalidate:如果缓存不过期就可以继续使用,过期了就必须去服务端验证
协商缓存
浏览器发送请求到服务器,服务器判断是否可使用本地缓存
服务器通过请求头中是否带上 If-Modified-Since 和 If-None-Match 这些条件请求字段检查资源是否更新
- 若资源更新,那么返回资源和 200 状态码
- 如果资源未更新,那么告诉浏览器直接使用缓存获取资源
HTTP的无状态性
所谓HTTP协议的无状态性是指服务器的协议层无需为不同的请求之间建立任何相关关系,它特指的是协议层的无状态性。但是这并不代表建立在HTTP协议之上的应用程序就无法维持状态。应用层可以通过会话Session来跟踪用户请求之间的相关性,服务器会为每个会话对象绑定一个唯一的会话ID,浏览器可以将会话ID记录在本地缓存LocalStorage或者Cookie,在后续的请求都带上这个会话ID,服务器就可以为每个请求找到相应的会话状
常见的状态码
2xx 成功
200 OK,表示从客户端发来的请求在服务器端被正确处理
3XX 重定向
301 永久性重定向,表示资源已被分配了新的 URL 302 临时性重定向,表示资源临时被分配了新的 URL
4XX 客户端错误
403 表示对请求资源的访问被服务器拒绝 404 表示在服务器上没有找到请求的资源
5XX 服务器错误
500 表示服务器端在执行请求时发生了错误
HTTPS
HTTPS 就是在 HTTP 和 TCP 协议中间加入了 SSL/TLS 安全套接层。
结合非对称加密和对称加密的各自优点,配合证书。既保证了安全性,也保证了传输效率。
目前应用最广泛的是TLS1.2,实现原理如下:
- Client 发送 random1+对称加密套件列表+非对称加密套件列表
- Server 收到信息, 选择 对称加密套件+非对称加密套件 并和 random2+证书(公钥在证书中) 一起返回
- Client 验证证书有效性,并用 random1+random2 生成 pre-master 通过服务器公钥加密+浏览器确认 发送给 Server
- Server 收到 pre-master,根据约定的加密算法对 random1+random2+pre-master(解密)生成 master-secret,然后发送服务器确认
- Client 收到生成同样的 master-secert,对称加密秘钥传输完毕 TLS1.3 则简化了握手过程,完全握手只需要一个消息往返,提升了性能。不仅如此,还对部分不安全的加密算法进行了删减。
websocket
WebSocket 是长轮询
具体比如在一个电商场景,商品的库存可能会变化,所以需要及时反映给用户,所以客户端会不停的发请求,然后服务器端会不停的去查变化,不管变不变,都返回,这个是短轮询。 而长轮询则表现为如果没有变,就不返回,而是等待变或者超时(一般是十几秒)才返回,如果没有返回,客户端也不需要一直发请求,所以减少了双方的压力。
跨域
-
JSONP,全称为json with padding,解决老版本浏览器跨域数据访问问题,原理是web页面调用JS文件不受浏览器同源策略限制,所以通过script标签可以进行跨域请求
-
cors,全称是跨域资源共享,允许浏览器向跨源服务器发出XMLHTTP Request请求,从而克服了ajax只能同源使用的策略,实现cors的关键是服务器,只要服务器实现了cros接口,就可以跨域通信
-
服务器代理
web安全
Cookie、Session、Token、JWT
傻傻分不清之 Cookie、Session、Token、JWT
参考文章