OSI 模型(七层)
OSI 将计算机网络体系结构划分为七层,每一层实现各自的功能和协议,并完成与相邻层的接口通信。即每一层扮演固定的角色,互不打扰
- 应用层
定义了应用进程之间的交互规则,通过不同的应用层协议为不同的网络应用提供服务。例如域名系统 DNS,支持万维网应用的 HTTP 协议,电子邮件系统采用的 SMTP 协议等
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
TCP/IP 网络模型(四层)
- 应用层
- 传输层(TCP/UDP)
- 网际层(IP)
- 网络接口层
五层网络模型
1. 应用层:直接为应用进程提供服务(HTTP, FTP, SMTP, DNS)
- 相当于合并了 OSI 中的应用层、表示层、会话层
应用层协议定义的是应用进程间通讯和交互的规则,不同的应用有着不同的应用层协议,如 HTTP 协议(万维网服务)、FTP 协议(文件传输)、SMTP 协议(电子邮件)、DNS(域名查询)等。
2. 传输层:为两台主机中的进程提供通信服务(TCP, UDP)
UDP / 用户数据报协议
(User Datagram Protocol,UDP):
- 无连接的;
- 提供尽最大努力的交付服务,但不保证交付的可靠性;
- 是面向报文的;
- 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低;
- 支持一对一、一对多、多对一和多对多的交互通信;
- 首部开销较小,只有 8 个字节,远小于 TCP 的 20 个字节。首部共由四个字段组成,每个字段两个字节:
- 源端口号:在需要对方回信时选用,不需要时可用全 0 表示;
- 目标端口号;
- 长度:UDP 用户数报的总长度;
- 校验和:检测 UDP 用户数据报在传输中是否有错,如果有错则丢弃。
TCP / 传输控制协议
(Transmission Control Protocol,TCP):
- 面向连接的;
- 提供可靠的交付服务;
- 提供全双工的通信,两端都设有缓存,用来临时存放通信数据;
- 面向字节流,这里的流指的是流入或流出进程的字节序列;
- 每一条 TCP 连接唯一地被通信两端的两个端点所确定,即:
TCP 连接 ::= {socket1,socket2} = {(IP1,port1),(IP2,port2)}
TCP 报文首部
TCP 虽然是面向字节流的,但其传输的基本数据单元则是报文段。
一个 TCP 报文段分为首部和数据两部分,TCP 首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项(n 为整数),具体格式如下:
源端口和目的端口:各占 2 个字节。序号:在一个 TCP 连接中,传送的字节流中的每一个字节都要按顺序进行编号。确认号:表示期望收到对方下一个报文段的第一个数据字节的序号。例如 B 收到 A 的报文,序号值为 501 ,数据长度为 200 字节(序号 501 ~ 700),此时表明 B 正确收到了序号 700 及其之前的所有数据,因此 B 在发送给 A 的确认报文段中确认号的值为 701。数据偏移:表示该数据报中数据的起始位置,由于数据报是由 首部+数据 组成,所以实际上就是指报文段的首部长度。保留:占 6 位,保留为今后使用,目前应置为 0 。- 六个
控制位:其作用分别如下:
同步 SYN (SYNchronization):在连接建立时用来同步序号。当 SYN = 1 而 ACK = 0 时,表明这是一个连接请求报文段;对方若同意建立连接,则应在响应的报文段中使 SYN = 1 和 ACK = 1 。确认 ACK (ACKnowledgment):用于标志的 TCP 包是否对上一个包进行了确认操作,如果确认了,则把 ACK 标志位设置成 1。终止 FIN (FINis):当值为 1 时,表明此报文段发送方的数据已发送完毕,并要求释放连接。推送 PSH (Push):当值为 1 时,表示接受方应该将数据立即交付给应用进程,而不是等待缓存填满后再向上交付。复位 RST (Reset):当值为 1 时,表明 TCP 连接出现严重差错,必须立即释放,然后再重新建立连接;也可以用来拒绝一个非法的报文段或拒绝打开一个连接。紧急 URG (URGent):当值为 1 时,表明紧急指针字段有效,代表此报文中有紧急数据,应尽快传送,而无需按原来的排队顺序传送。
窗口大小:保持动态变化,用于指明接收方允许发送方发送的数据量。校验和:占 2 字节,校验的字段范围包括首部和数据。紧急指针:占 2 字节,仅在 URG = 1 时才有意义,用于指明紧急数据的结束位置,位于结束位置之后的就是普通数据。
0. 选项`:长度可变,最长可达 40 字节。可用的选项有:最大报文段长度 ,窗口扩大选项、时间戳选项等。
可靠性的保证?
无差错、不丢失、不重复、并且按序到达。
序列号 & 确认应答号
序列号是给发送数据的每一个字节都标上号码的编号;- 接收端查询接收数据的 TCP 首部中的
序列号&数据长度,将自己下一步需要接收的序列号作为确认应答 ACK返回给发送端; - 发送端发送数据后,会等待接收方发出确认应答,如果在一定时间内发送端都没有收到确认应答,发送端会认为数据丢失,进行
数据重发;
没有收到确认应答的原因,分为两种情况:
- 发送端发送的数据丢失;
- 接收端发送的确认应答丢失(发送端重发后,接收端接收到重复的数据会丢弃,但是会重发确认应答);
总结: 通过序列号 & 确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,确保数据不会重复发送、重复接收。
超时重发
为了能够在不同网络环境下都保持高性能通信,且无论网络拥堵情况发生何种变化,都要保持这一特性,TCP 每次发包都会计算往返时间(RTT/Round Trip Time) & 其偏差(RTT 波动时间/抖动),重发的超时时间就是比两者的和再大一点的值;
此外数据也不会被无限次的重发,达到一定重发次数后,如果还没有任何确认应答返回,会判断网络或对方主机发生了异常,强制关闭连接。
总结:保证接收端接收数据的完整性
连接管理
保证了端对端通信的可靠性
三次握手
三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送 3 个报文。
目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。
- A 请求建立连接,发送
SYN = 1,同时选择一个初始序号seq = x,之后进入SYN-SENT(同步已发送)状态; - B 收到连接请求报文段后,如果同意建立连接,则发送确认报文段,此时
SYN 和 ACK 都置为 1,确认号ack = x + 1,并为自己选择一个初始序号seq =y,之后进入SYN-RCVD(同步收到)状态; - A 收到 B 的确认后,发出最后的确认,确认报文段的
ACK 为 1,确认号ack = y + 1,序号seq = x + 1。B 收到后检查ack 是否= y + 1,如果正确证明建立连接成功,之后 A & B 进入ESTABLISHED(已连接)状态;
三次握手的主要信息是
- 在建立连接的过程中,也会确定发送数据包的单位(
最大消息长度/MSS/Max Segment Size),即一个段,理想的最大消息长度正好是 IP 中不会被分片处理的最大数据长度。 - TCP 在传输大量数据时,是以 MSS 的大小将数据进行分割发送,重发也是以 MSS 为单位。
四次挥手
- 假设 A 先主动关闭连接,此时需要发送连接释放报文段:首部终止控制位
FIN = 1,序号seq = u + 1,其中 u 等于前面传送过的数据的最后一个字节的序号。之后 A 进入FIN-WAIT-1(终止等待 1)状态; - B 收到连接释放请求报文段后立即发出确认,确认号
ack = u + 2,序号seq = v + 1,其中 v 等于前面传送过的数据的最后一个字节的序号。之后 B 进入CLOSE-WAIT(关闭等待)状态。A 收到确认后进入FIN-WAIT-2状态。此时 TCP 连接处于半关闭状态,即 A 已经没有数据需要发送,但如果 B 数据没有发送没,扔可以继续发送,A 也可以继续接收; - B 发送连接释放报文段:首部终止控制位
FIN = 1,然后进入LAST_ACK状态 - A 收到来自 B 的断开连接请求后就进入
TIME_WAIT状态, B 收到 A 的确认后,就关闭连接;
为什么连接的时候是三次握手,关闭的时候却是四次握手?
建立连接时因为当 Server 端收到 Client 端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。所以建立连接只需要三次握手。
又因为 TCP 是全双工模式。 这就意味着,关闭连接时,当 Client 端发出 FIN 报文段时,只是表示 Client 端告诉 Server 端数据已经发送完毕了。当 Server 端收到 FIN 报文并返回 ACK 报文段,表示它已经知道 Client 端没有数据发送了,但是 Server 端还是可以发送数据到 Client 端的,所以 Server 很可能并不会立即关闭 SOCKET,直到 Server 端把数据也发送完毕。
当 Server 端也发送了 FIN 报文段时,这个时候就表示 Server 端也没有数据要发送了,就会告诉 Client 端,我也没有数据要发送了,这样才嫩断开两个方向的连接。
滑动窗口
因为 TCP 以 段为单位发送数据,如果每次都是等到上一个段的确认应答后,才发送下一个段,会有一个问题:RTT 越长,通信性能就越差。
因此,引入了窗口的概念,即确认应答不是以每个分段来确认,而是以更大的单位确认
- 窗口中的数据即使没有收到确认应答也可以被发送出去;
- 窗口中的数据要缓存,如果出现丢包情况,可以进行重传,直到收到确认应答;
- 没有收到确认应答的数据包不一定都会被重发,因为以最新的确认应答来判断对方已经收到的数据(即前面的 ACK 丢失,也可以通过后面的 ACK 来确认,提高了效率);
- 收到确认应答的数据可以从缓存区清除;
- 如果发送端的某个报文丢失,接收端会一直返回对当前收到的数据包的确认应答,发送端如果连续 3 次收到同一个确认应答包,就会对其进行重发(
高速重发机制,比超时重发更加高效)
总结:提高了数据传输效率
流量控制
流量控制(flow control)是指控制发送方的发送速率,以便接收方来得及接收。假设 A 向 B 发送数据,在连接建立时,B 会将自己接收窗口(rwnd,receiver window)的大小告诉 A ,而 A 需要保证发送窗口的大小不能超过 B 接收窗口的大小,通过该机制就可以实现对发送方的流量控制。
拥塞控制
网络拥塞(congestion)是指传输的数据量超过节点承受能力而导致传输能力下降的情况。而拥塞控制就是防止过多的数据注入到网络中而造成路由器和链路过载。TCP 采用四种算法来进行拥塞控制,分别是:慢启动(slow start)、拥塞避免(congestion avoidance)、快重传(fast retransmit)和快恢复(fast recovery):
-
慢启动 慢开始和拥塞避免都是基于窗口的拥塞控制:发送方会维持一个名为拥塞窗口 cwnd(congestion window)的状态变量,其值取决于网络的拥塞程度,并会动态变化,同时发送方会让自己的发送窗口等于拥塞窗口。 慢启动的思路如下:由于不知道网络的负载能力,所以最好的选择就是逐步探测,即由小到大成倍地增大发送窗口,也就是说,由小到大成倍地增大拥塞窗口的值。
-
拥塞避免 拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢地增大:每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是像慢启动阶段那样加倍地增长。慢启动和拥塞避免通常是配合使用,以保证启动速度,一开始使用慢启动进行成倍增长,当达到某一个阈值 ssthresh 后采用拥塞避免进行稳步尝试:
-
快重传和快恢复 快重传算法要求接收方不要等待自己发送数据时才进捎带确认,而是要立即发送确认,即使收到了失序报文段也要立即发出对已收到的报文段的重复确认。示例如下:
比如,当 M3 丢失时,之后发送 M4 , M5 , M6 时收到的都是对于 M2 的重复确认,此时发送方就可以知道 M3 已经丢失,需要立即进行重传。由于此时只是个别报文出现了丢失,而不是网络拥塞,所以执行快恢复:发送方调整 ssthresh = cwnd / 2,并设置 cwnd = ssthresh = 8 (图中点 5),并开始执行拥塞避免算法。
TCP 与 UDP 区别及应用场景?
TCP
TCP 是面向连接的、面向面向字节流的可靠的流协议。流就是指不间断的数据结构,当应用程序采用 TCP 发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。
TCP 为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此外还具备“流控制(流量控制)”、“拥塞控制”、提高网络利用率等众多功能。
TCP 有以下特点:
- TCP 充分地实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在 UDP 中都没有。
- 此外,TCP 作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。
- 根据 TCP 的这些机制,在 IP 这种无连接的网络上也能够实现高可靠性的通信( 主要通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现)。
UDP
UDP 是面向报文的,所谓面向报文,是指面向报文的传输方式是应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则 IP 层需要分片,降低效率。若太短,会是 IP 太小。
UDP 是不具有可靠性的数据报协议,细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。
UDP 有以下特点:
-
UDP 不提供复杂的控制机制,利用 IP 提供面向无连接的通信服务。
-
传输途中出现丢包,UDP 也不负责重发。
-
当包的到达顺序出现乱序时,UDP 没有纠正的功能。
-
并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况,UDP 也无法进行流量控制等避免网络拥塞行为。
-
如果需要以上的细节控制,不得不交由采用 UDP 的应用程序去处理。
-
UDP 常用于以下几个方面:
- 包总量较少的通信(DNS、SNMP 等);
- 视频、音频等多媒体通信(即时通信);
- 限定于 LAN 等特定网络中的应用通信;
- 广播通信(广播、多播)。
应用
TCP 适用于对准确性要求高或者要求有连接的场景,比如,电子邮件、网页传输、文件传输都是基于 TCP
UDP 主要用于那些对高速传输和实时性有较高要求但对准确性要求较低的场景,比如,域名转换、网络管理、视频流等都是基于 UDP
3. 网络层:为两台主机提供通信服务,并通过选择合适的路由将数据传递到目标主机。
4. 数据链路层:负责将网络层交下来的 IP 数据报封装成帧,并在链路的两个相邻节点之间传送帧,每一帧都包含数据 & 必要的控制信息(同步信息、地址信息、差错控制等)
5. 物理层:为数据传输提供物理媒介。
传输媒介
物理层并不指具体的传输媒介,相反物理层希望能够尽量屏蔽不同媒介间的差异。这些传输媒介可以分为以下两类:
导引型传输媒介:信号被导引沿着固体媒介进行传播,如双绞线、同轴电缆、光缆。 非导引型传输媒介:信号在自由空间内进行传播,如短波通信、微波通信。
信道分类
信道是指信息传输的基本通道,它可以分为以下三类:
- 单工信道:只能有一个方向的通信而没有反方向的通信;
- 半双工信道:通信的双方都能发送信息,但双方不能同时发送或接收信息。
- 全双工信道:通信的双方可以同时发送和接收信息。
信道复用
信道复用是信息传输当中最常使用的技术,用于提高信息传输的效率,根据采用技术的不同,可以分为以下几类:
- **频分复用(FDM,Frequency Division Multiplexing)**是将用于传输信道的总带宽划分成若干个子频带(或称子信道),每个子信道传输一路信号;
- 时分复用(TDM,Time Division Multiplexing) 是指采用同一物理连接的不同时段来传输不同的信号;
- 在**统计时分复用(Statistic TDM)**模式下,各用户将数据发送到集中器的输入缓存中,然后由集中器进行顺序扫描并放入到 STDM 帧中
- **波分复用(WDM,Wavelength Division Multiplexing)**是将两种或多种不同波长的光载波信号在发送端经复用器汇合在一起,并耦合到光线路的同一根光纤中进行传输;在接收端,经分用器将各种波长的光载波分离,然后由光解调器作进一步处理以恢复原信号
- **码分复用(CDM,Code Division Multiplexing)**是靠不同的编码来区分各路原始信号的一种复用方式。
网络性能优化
- 减少 http 请求
- 服务端渲染
- 静态资源使用 CDN(内容分发网络)
- css 写头部,js 写底部
- 简单图标用矢量图
- 使用 http 缓存
- 图片懒加载
- 压缩代码,去掉空白、注释等
- 降低 css 选择器的复杂性;
- 减少重排重绘
什么是 HTTP? HTTP 和 HTTPS 的区别?
HTTP
HTTP (HyperText Transfer Protocol),即超文本运输协议,是实现网络通信的一种规范
HTTP 常被用于在 Web 浏览器和网站服务器之间传递信息,以明文方式发送内容,不提供任何方式的数据加密
HTTP特点如下:
- 支持客户/服务器模式
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快
- 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间
- 无状态:HTTP 协议无法根据之前的状态进行本次的请求处理
HTTPS
HTTP在通信过程中,存在以下问题:
- 通信使用明文(不加密),内容可能被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
HTTPS 出现正是为了解决 HTTP 不安全的特性
https:是以安全为目标的 HTTP 通道,即 HTTP 下 加入 SSL 层进行加密。其作用是:建立一个信息安全通道,来确保数据的传输,确保网站的真实性。
为了保证这些隐私数据能加密传输,让 HTTP 运行安全的 SSL/TLS 协议上,即 HTTPS = HTTP + SSL/TLS,通过 SSL 证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密
SSL 协议位于 TCP/IP 协议与各种应用层协议之间,浏览器和服务器在使用 SSL 建立连接时需要选择一组恰当的加密算法来实现安全通信,为数据通讯提供安全支持
- 首先客户端通过 URL 访问服务器建立 SSL 连接
- 服务端收到客户端请求后,会将网站支持的证书信息(证书中包含公钥)传送一份给客户端
- 客户端的服务器开始协商 SSL 连接的安全等级,也就是信息加密的等级
- 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站
- 服务器利用自己的私钥解密出会话密钥
- 服务器利用会话密钥加密与客户端之间的通信
SSL 的实现
SSL 的实现这些功能主要依赖于三种手段:
- 对称加密:采用协商的密钥对数据加密
- 非对称加密:实现身份认证和密钥协商
- 摘要算法:验证信息的完整性
- 数字签名:身份验证
对称加密
加密和解密使用的秘钥都是同一个,是对称的。只要保证了密钥的安全,那整个通信过程就可以说具有了机密性
非对称加密
非对称加密,存在两个秘钥,一个叫公钥,一个叫私钥。两个秘钥是不同的,公钥可以公开给任何人使用,私钥则需要保密
公钥和私钥都可以用来加密解密,但公钥加密后只能用私钥解 密,反过来,私钥加密后也只能用公钥解密
混合加密(机密性)
在 HTTPS 通信过程中,采用的是对称加密+非对称加密,也就是混合加密
在对称加密中讲到,如果能够保证了密钥的安全,那整个通信过程就可以说具有了机密性
而 HTTPS 采用非对称加密解决秘钥交换的问题
具体做法是发送密文的一方使用对方的公钥进行加密处理“对称的密钥”,然后对方用自己的私钥解密拿到“对称的密钥”
这样可以确保交换的密钥是安全的前提下,使用对称加密方式进行通信
举个例子:
网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文
上述的方法解决了数据加密,在网络传输过程中,数据有可能被篡改,并且黑客可以伪造身份发布公钥,如果你获取到假的公钥,那么混合加密也并无多大用处,你的数据扔被黑客解决
因此,在上述加密的基础上仍需加上完整性、身份验证的特性,来实现真正的安全,实现这一功能则是摘要算法
摘要算法(完整性)
实现完整性的手段主要是摘要算法,也就是常说的散列函数、哈希函数
可以理解成一种特殊的压缩算法,它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”
摘要算法保证了“数字摘要”和原文是完全等价的。所以,我们只要在原文后附上它的摘要,就能够保证数据的完整性
比如,你发了条消息:“转账 1000 元”,然后再加上一个 SHA-2 的摘要。网站收到后也计算一下消息的摘要,把这两份“指纹”做个对比,如果一致,就说明消息是完整可信的,没有被修改
数字签名(身份认证)
数字签名能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名
原理其实很简单,就是用私钥加密,公钥解密
签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的
因为谁都可以发布公钥,为了防止黑客伪造公钥,就需要一个第三方,就是证书验证机构
CA 验证机构
数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场
CA 对公钥的签名认证要求包括序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”
流程如下图:
- 服务器的运营人员向数字证书认证机构申请公开密钥;
- 数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名
- 然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起
- 服务器会将这份由数字证书认证机构颁发的数字证书发送给客户端,以进行非对称加密方式通信
接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,则证明:
- 认证服务器的公开密钥的是真实有效的数字证书认证机构
- 服务器的公开密钥是值得信赖的
(CA 采用的是非对称性加密,私钥由 CA 持有,公钥由浏览器持有,但是会事先内嵌在浏览器当中)
区别?
- HTTP 协议的数据传输是明文的,不安全;HTTPS 使用了 SSL/TLS 协议进行了加密处理, 是 HTTP 协议的安全版本;
- HTTP 和 HTTPS 使用连接方式不同,默认端口也不一样,HTTP 默认端口是 80;HTTPS 默认端口是 443
- HTTPS 由于需要设计加密以及多次握手,性能方面不如 HTTP
- HTTPS 的 SSL,SSL 证书需要花费一定成本,功能越强大的证书费用越高
HTTP 常见的请求头有哪些? 作用?
HTTP 头字段(HTTP header fields),是指在超文本传输协议(HTTP)的请求和响应消息中的消息头部分
它们定义了一个超文本传输协议事务中的操作参数
HTTP 头部字段可以自己根据需要定义,因此可能在 Web 服务器和浏览器上发现非标准的头字段
下面是一个 HTTP 请求的请求头:
GET /home.html HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0
常用状态码 & 适用场景
HTTP 状态码(英语:HTTP Status Code),用以表示网页服务器超文本传输协议响应状态的 3 位数字代码
简单来讲,http 状态码的作用是服务器告诉客户端当前请求响应的状态,通过状态码就能判断和分析服务器的运行状态
分类
状态码第一位数字决定了不同的响应状态,有如下:
1xx 表示消息 2xx 表示成功 3xx 表示重定向 4xx 表示请求错误 5xx 表示服务器错误
1xx
代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束
常见的有:
100(客户端继续发送请求,这是临时响应):这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应101:服务器根据客户端的请求切换协议,主要用于 websocket 或 http2 升级
2xx
代表请求已成功被服务器接收、理解、并接受
常见的有:
200(成功):请求已成功,请求所希望的响应头或数据体将随此响应返回201(已创建):请求成功并且服务器创建了新的资源202(已创建):服务器已经接收请求,但尚未处理203(非授权信息):服务器已成功处理请求,但返回的信息可能来自另一来源204(无内容):服务器成功处理请求,但没有返回任何内容205(重置内容):服务器成功处理请求,但没有返回任何内容206(部分内容):服务器成功处理了部分请求
3xx
表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向
常见的有:
300(多种选择):针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择301(永久移动):请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置302(临时移动): 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求303(查看其他位置):请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码304(not modified):资源未修改,可以使用协商缓存305 (使用代理): 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理307 (临时重定向): 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
4xx 客户端错误
代表了客户端看起来可能发生了错误,妨碍了服务器的处理
常见的有:
400(错误请求): 服务器不理解请求的语法401(未授权): 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。403(禁止): 服务器拒绝请求404(未找到): 服务器找不到请求的网页405(方法禁用): 禁用请求中指定的方法406(不接受): 无法使用请求的内容特性响应请求的网页407(需要代理授权): 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理408(请求超时): 服务器等候请求时发生超时
5xx 服务端错误
表示服务器无法完成明显有效的请求。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生
常见的有:
500(服务器内部错误):服务器遇到错误,无法完成请求501(尚未实施):服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码502(错误网关): 服务器作为网关或代理,从上游服务器收到无效响应503(服务不可用): 服务器目前无法使用(由于超载或停机维护)504(网关超时): 服务器作为网关或代理,但是没有及时从上游服务器收到请求505(HTTP 版本不受支持): 服务器不支持请求中所用的 HTTP 协议版本
适用场景
下面给出一些状态码的适用场景:
100:客户端在发送 POST 数据给服务器前,征询服务器情况,看服务器是否处理 POST 的数据,如果不处理,客户端则不上传 POST 数据,如果处理,则 POST 上传数据。常用于 POST 大数据传输206:一般用来做断点续传,或者是视频文件等大文件的加载301:永久重定向会缓存。新域名替换旧域名,旧的域名不再使用时,用户访问旧域名时用 301 就重定向到新的域名302:临时重定向不会缓存,常用 于未登陆的用户访问用户中心重定向到登录页面304:协商缓存,告诉客户端有缓存,直接使用缓存中的数据,返回页面的只有头部信息,是没有内容部分400:参数有误,请求无法被服务器识别403:告诉客户端进制访问该站点或者资源,如在外网环境下,然后访问只有内网 IP 才能访问的时候则返回404:服务器找不到资源时,或者服务器拒绝请求又不想说明理由时503:服务器停机维护时,主动用 503 响应请求或 nginx 设置限速,超过限速,会返回 503504:网关超时
http 请求方法
- GET - 对服务器资源的简单请求
- POST - 用于新建数据,发送包含用户提交数据的请求
- PUT - 用于更新数据
- DELETE - 用于删除数据
- HEAD - 类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头
- PUT - 向指定资源位置上传其最新内容
- DELETE - 发送一个用来删除指定文档的请求
- OPTIONS - 返回所有可用的方法,可检查服务器支持哪些方法
- TRACE - 发送请求的一个副本,以跟踪其处理进程
- CONNECT - 用于 ssl 隧道的基于代理的请求
get & post 区别
GET 和 POST,两者是 HTTP 协议中发送请求的方法
GET 方法请求一个指定资源的表示形式,使用 GET 的请求应该只被用于获取数据;
POST 方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用
本质上都是 TCP 链接,并无差别
但是由于 HTTP 的规定和浏览器/服务器的限制,导致他们在应用过程中会体现出一些区别:
GET和HEAD一样是幂等的,不会修改服务器上的信息,但POST可能会修改服务器上的资源。GET在浏览器回退时是无害的,而POST会再次提交请求。GET产生的 URL 地址可以被 Bookmark,易于分享,而POST不可以。GET参数附加在URL后面,用?分隔URL和数据,多个参数之间用&连接;POST数据放在Request body中;所以GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文,只有使用 HTTPS 才能加密安全- 对参数的数据类型,
GET只接受 ASCII 字符,而POST没有限制。 - HTTP 对
URL长度没有限制,但实际开发中,浏览器 & 服务器会对URL的长度进行限制,所以GET传输数据大小会受限;POST参数放在Request body中,理论上长度没有限制,但实际上服务器会规定对POST提交数据大小的限制。 GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。GET请求会被浏览器主动 cache,而POST不会,除非手动设置。
从输入 URL 到页面加载的全过程
简单的分析,从输入 URL 到回车后发生的行为如下:
URL 解析 DNS 查询 TCP 连接
1. URL 解析
首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行对应操作;
2. DNS 查询
3. 三次握手建立 TCP 连接
4. 发送 HTTP 请求
当建立 tcp 连接之后,就可以在这基础上进行通信,浏览器发送 http 请求到目标服务器
请求的内容包括:
请求行 请求头 请求主体
5. 响应请求
当服务器接收到浏览器的请求之后,就会进行逻辑操作,处理完成之后返回一个 HTTP 响应消息,包括:
状态行 响应头 响应正文
在服务器响应之后,由于现在 http 默认开始长连接 keep-alive,当页面关闭之后,tcp 链接则会经过四次挥手完成断开
6. 页面渲染
当浏览器接收到服务器响应的资源后,首先会对资源进行解析:
查看响应头的信息,根据不同的指示做对应处理,比如重定向,存储 cookie,解压 gzip,缓存资源等等 查看响应头的 Content-Type 的值,根据不同的资源类型采用不同的解析方式
关于页面的渲染过程如下:
- 解析 HTML,构建 DOM 树
- 解析 CSS ,生成 CSS 规则树
- 合并 DOM 树和 CSS 规则,生成 render 树
- 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
- 绘制 render 树( paint ),绘制页面像素信息
- 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成( composite ),显示在屏幕上
浏览器缓存机制
缓存机制/缓存工作流程(三级原理)
- 浏览器第一次发送请求,先去内存中找;
- 内存中找不到就去硬盘获取;
- 硬盘中找不到,则向服务器发送请求,拿到服务器返回的响应,并根据响应的缓存标识,决定是否缓存响应结果,如果缓存,则将请求结果和缓存表示存入浏览器缓存中。
缓存机制的关键
- 浏览器每次发起请求,先去浏览器缓存中寻找;
- 浏览器每次收到响应,都会将结果和缓存表示存储到浏览器缓存中;
- 强制缓存优先于协商缓存。
浏览器缓存位置
memory & disk,找缓存时先去 memory 找,再去 disk 找;
memory 缓存
- 快速性:在进行的内存中,读取快速;
- 时效性:当该进程关闭,进程中的内存也会被清空。
disk 缓存
- 缓存至硬盘,读取速度较慢
强制缓存
分为三种情况:
- 浏览器缓存中不存在缓存结果 & 缓存标识,强制缓存失效,则向服务器发送请求;
- 存在缓存结果 & 缓存标识,但结果已经失效,则使用协商缓存;
- 存在缓存结果 & 缓存标识,并且结果还未失效,使用强制缓存(直接返回结果)。
缓存规则
HTTP 中控制强制缓存的字段:Expires & Cache-Control,后者优先级更高
Expires
HTTP/1.0,值为服务器返回请求结果的到期时间(是一个绝对时间); 请求时使用客户端的时间与此时间做对比,未失效则使用
- 问题:客户端和服务端如果有一方的时间不准确,强制缓存则无意义
Cache-Control
HTTP/1.1,主要取值如下:
public:表示客户端和代理服务器都可以对该结果进行缓存;private:表示只有客户端可以缓存结果(default);no-cache:客户端缓存结果,但是否使用取决于协商缓存;no-store:不缓存(不使用强制缓存,也不使用协商缓存);max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效(是一个相对时间)。
Pragme
在三者中优先级最高,并且只有 no-cache 一个属性,效果同 Cache-Control:no-cache
协商缓存/对比缓存
在强制缓存失效后,浏览器携带缓存标识向服务器发送请求,由服务器决定是否使用缓存。
分为两种情况:
- 协商缓存生效,
return 304; - 协商缓存失效,
return 200 & 请求结果。
缓存规则
HTTP 中控制强制缓存的字段:Last-Modified / If-Modified-Since & Etag / If-None-Match,后者优先级更高
Last-Modified / If-Modified-Since
- 服务器返回的响应中的字段
Last-Modified:表示该资源在服务器上最后被修改的时间; - 客户端发送请求中的字段
If-Modified-Since: 携带的是上次响应中的Last-Modified值; - 服务器收到请求后,会将其中的
If-Modified-Since与资源在服务器中的最后修改时间做对比,如果最后修改时间大于If-Modified-Since,证明缓存的资源已经失效,则return 200 & 请求结果;否则return 304 & 不返回 Last-Modified,表明资源无更新,可以使用缓存文件。
Etag / If-None-Match
优先级更高; 在 HTTP/1.1 出现主要是为了解决:
- 一些文件会周期性地修改,但是内容并没有修改(仅仅改变修改的事件),这时不希望客户端认为此文件被修改了而去重新发送请求;
- 某些文件修改特别频繁(如在秒以下的时间内修改,在 1s 内修改了 N 次),
If-Modified-Since能检查道德粒度是秒级的,这种修改无法判断(或者说 UNIX 记录的 mtime 只能精确到秒); - 一些服务器不能够精确得到文件最后的修改时间。
- 服务器响应中的字段
Etag:是该资源对应的唯一标识符(由服务器生成); - 客户端发送请求中的字段
If-None-Match: 携带上次响应中的Etag值; - 服务器收到请求后,会将其中的
If-None-Match字段与该资源在服务器中的Etag值做对比,如果不一致,证明缓存失效,则return 200 & 请求结果;否则return 304 & 新的 ETag(ETag是重新生成的,虽然跟之前的没变化,但也要返回),表明资源无更新,可以使用缓存文件。
用户行为对缓存的影响
- 地址栏回车、页面链接跳转、新开窗口、前进后退对强制缓存、协商缓存都有效;
- F5 刷新使得强制缓存失效,但不会使协商缓存失效;
- ctrl+F5 会使得强制缓存和协商缓存都失效。