网络模型和协议
网络模型
TCP/IP 4层模型 应用层 传输层 网络层 网络接口层
TCP/IP 5层模型 应用层 传输层 网络层 数据链路层 物理层
OSI 7层模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
协议
是指两个或者多个通信实体之间交换的报文的格式和顺序,以及报文发送和接收一条报文或其他事件所采取的动作。常见的协议有tcp协议和udp协议
TCP和UDP的区别
UDP特点
- **无连接:**知道对端的IP和端口号就直接进行传输, 不需要建立连接。
- **不可靠:**没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息。
- **面向数据报:**不能够灵活的控制读写数据的次数和数量,应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并。
- 数据收不够灵活,但是能够明确区分两个数据包,避免粘包问题
TCP特点
- 面向连接;
- 每一条TCP连接只能是点对点的(一对一);
- 提供可靠交付的服务;
- 提供全双工通信;
- 面向字节流。
UDP如何保证可靠
TCP、UDP、IP报文格式
TCP
UDP
IP
IP报文格式分别有IPv4和IPv6
IPv4
IPv6
三次握手四次挥手
三次握手
- TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
- TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
- TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1(即序列号前x的数据报已经收到),同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
- TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1(即序列号前y的数据报已经收到),自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号,因此seq=x+1。
- 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么TCP客户端最后还要发送一次确认呢(三次握手的原因)
两个原因
-
第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
原理:如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
-
要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认
原理:如上图所示,如果只有两次握手,则只有客户端知道了服务端已经知道它的初始化序号为x,而服务端并不知道客户端是否知道它的初始化序号y,因此需要第三次握手,客户端发送ack=y+1告知服务端,客户端已经知道服务端的初始序号y,以此达到双方对初始序列号的协商。
四次挥手
- 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
- 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
- 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
- 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
- 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
- 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
为什么客户端最后还要等待2MSL
- 保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
- 防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
为什么建立连接是三次握手,关闭连接确是四次挥手呢
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
如果已经建立了连接,但是客户端突然出现故障了怎么办
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
TCP粘包
Tcp粘包
指发送方发送的若干数据包在接收方接收时粘成一团,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾
产生的原因
- 发送方的原因:TCP默认使用Nagle算法,而Nagle算法主要做两件事情:只有上一个分组得到确认,才发送下一个分组,收集多个小分组,在一个确认到来时一起发送,Nagle算法造成了发送方可能存在粘包现象
- 接收方的原因:TCP接收到分组时,应用层并不会立即处理,TCP将接收到的分组放到接收缓存中,然后应用程序主动从接收缓存中读取分组,当TCP接收分组的速度大于应用程序读取分组的速度时,多个包就会被存至缓存,应用程序读取时,就会读到多个首尾相连在一起的包
TCP粘包问题如何解决
- 消息数据固定长度,发送定长包。如果每个消息的大小都是一样的,那么在接收对等方只要累计接收数据,直到数据等于一个定长的数值就将它作为一个消息,但是浪费存储和网络资源。
- 使用分割符来区分包的界限,包尾加上\r\n标记。FTP协议正是这么做的。但问题在于如果数据正文中也含有\r\n,则会误判为消息的边界。
- 数据包的头部中增加数据包长度字段。包头是定长的4个字节,说明了包体的长度。接收对等方先接收包体长度,依据包体长度来接收包体。
TCP拆包
概念
发送方将一个数据包拆分成了多个数据包进行传送
产生的原因
- 发送数据的数据大于TCP剩余的缓冲区的大小
- 发送数据的数据大于MSS最大报文长度
TCP 协议如何保证可靠传输
TCP 协议可靠传输概念
Tcp的可靠传输是确保一个进程从其接收缓存中读出的数据流是无损坏、无间隙、非冗余和按序的数据流;即改字节流与连接的另一方端系统发送出的字节流完全相同。
保证可靠传输的方法
(校 序 重 流 拥)
- 检验和
发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
- 确认应答+序列号
接收方收到报文就会确认(累积确认:对所有按序接收的数据的确认)
TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
- 超时重传
当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
- 流量控制
TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。接收方有即时窗口(滑动窗口),随ACK报文发送
- 拥塞控制
当网络拥塞时,减少数据的发送。发送方有拥塞窗口,发送数据前比对接收方发过来的即使窗口,取小
慢启动、快恢复,快重传,拥塞控制。
TCP的流量和拥塞控制
TCP流量控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
TCP拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
为了便于讨论,做如下假设:
- 接收方有足够大的接收缓存,因此不会发生流量控制;
- 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。
1慢开始与拥塞避免
发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 …
注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。
2. 快重传与快恢复
在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。
在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。
在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。
慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。
ARQ协议
又叫地址解析协议,可以把网络层IP32位地址转换为数据链路层MAC48位地址
ARP缓存表是ARP协议和RARP协议运行关键
ARP缓存表缓存了IP地址到硬件地址之间的映射关系
ARP缓存表中的记录并不是永久有效的,有一定的期限
命令 arp -a查看arp缓存表
从浏览器中输入url之后发生了什么
- 浏览器 分析 URL
- DNS 请求解析 IP 地址
- DNS 解析出 IP 地址
- 建立 TCP 连接
- 取文件
- 服务器响应
- 释放 TCP 连接
- 浏览器显示
DNS服务器基本流程
- 客户机提出域名解析请求,并发该请求发送到本地的域名服务器
- 当本地的域名服务器收到请求后,先查询本地缓存,如果有缓存记录,则直接讲本地的域名服务器的查询结果返回
- 如果本地缓存没有该记录,则本地域名服务器把请求发到根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器地址
- 本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己缓存,如果没有该项纪录,则返回相关下级的域名服务器的地址。
- 重复第四部,一直往下查询,直到找到正确纪录
- 本地域名服务器把返回的结果保存到缓存,以备下次使用,同时把结果返回给客户。
http get和post的区别
- GET是从指定的资源请求数据。
- POST向指定的资源提交要被处理的数据
三个不同的方面
- GET请求方式将请求信息放在URL后面,请求信息与url用?隔开,安全性较低。而post请求方式将请求信息放置在报文体中,安全性比get高。由于GET中的请求信息放置在URL中,因此是有长度限制的,因为URL本身是有长度限制的。而POST中的请求信息是放置在报文体中,因此对数据长度是没有限制的。
- GET请求方式符合幂等性和安全性,(幂等性的定义:对数据库的一次操作和多次操作获得的结果是一致的,则认为符合幂等性。安全性的定义:对数据库的操作没有改变数据库中的数据,则认为符合安全性),GET请求方式是做查询操作,因此不会改变数据库中原有的数据,认为符合安全性。POST请求方式是既不幂等又不安全,首先POST请求方式往数据库中提交数据的,因此会改变数据库中的数据。其次,POST请求方式每次获得的结果都有可能不一样,因为POST请求是作用在上一级的URL上的,则每一次请求都会添加一份新资源。
- GET请求能够被缓存,而post不能被缓存。
cookies和session的关系
- Cookie通过在客户端记录信息确定用户身份**,**Session通过在服务器端记录信息确定,cookie的产生是在服务端产生的。
- cookie只是一个通行证,但并不是安全的,任何安全的校验必须要在服务端上完成,cookie只是存在客户端上面的一个唯一标识它且由服务端定制的信息,本地可以改,但是不管怎么改,最后还是需要把它拿上发送给服务端进行匹配校验
- session和cookie的存储都存在时效性,这是很有必要的
- 单个cookie保存的数据不能超过4kb,很多浏览器都限制了一个站点最多保存20个cookie
- 不管是cookie还是session,都是建立在安全性的大前提下,session中不仅仅有cookie的信息,同时会有该用户的相关重要且安全的信息存储,所以session是在服务器的,而cookie只是服务器将一些不重要的信息拿出来丢给客户的存在,以备以后快速匹配校验用。
服务器怎么知道客户端已经发送数据完毕
- 发送的包里带长度,服务端首先收到的是长度,然后根据长度接受数据
- 发送的包尾是结束符,不停的收,收到结束符后,则视该发送完毕。
摘要、非对称加密算法、数字证书、签名
摘要
定义
一段信息,经过摘要算法得到一串哈希值,就是摘要了。
相关知识点
- 摘要信息是任意长度,而摘要是定长。
- 摘要算法有MD5、SHA1、SHA256、SHA512等
- 摘要相同,信息一定相同。例:比对用户的输入密码和预设密码是否相同。这里都无需关心密码本身是什么,关注的是密码是否相同,而密码是否相同取决于摘要是否相同,所以问题转化成了摘要是否相同。将用户密码的摘要而不是密码本身保存在数据库中,因为反推很难,所以真实密码是保密的非要暴露的话,也是通过比对而不是反推。
非对称加密算法
定义
算法重要的概念是公钥和私匙。先有私钥,再用函数生成公钥。公钥包含了私钥的信息,但也掺杂了其他随机变量,因此不能反推。私匙不要泄露,公钥要告诉和你通信的对方。公钥加密,只有对应私钥能解开(保密);私钥加密,只有对应公钥能解开(不可抵赖)。
具体例子
- 对方用你的公钥加密信息,你收到后用私钥解开。只有你有私钥,所以只有你能解开,换句话说,有私钥才能看到信息,很安全。
- 你拿私钥加密信息,对方收到后用你的公钥解开。公钥是公开的,所以其他人也可以看到你的信息,不保密。私钥加密,只有对应公钥能解开。既然用你的公钥能解开,说明加密一定是你的私钥。私钥只有你有,所以一定是你发送的,你不可抵赖。
数字签名
定义
把一段信息,经过摘要算法得到一串哈希值后,再通过哈希算法,生成摘要,然后再用私钥对摘要加密就变成了数字签名。
发送步骤
- 通过哈希算法,生成摘要。
- 然后再用私钥对摘要加密就变成数字签名(发送方私钥+加密算法)。
解密步骤
- 从摘要密文(数字签名)到摘要明文(发送方公钥+解密算法)。
- 从收到的内容当场计算摘要(哈希算法),把得到的哈希值与发送的时候的摘要结果比对是否一致。
- 若内容一致,证明内容未被篡改,内容只能是私钥拥方发送,不可抵赖。
为什么摘要要加密才再发送,而不直接发摘要?摘要不可以逆向推导原文,摘要泄露了也没事
摘要泄露是没事,但不怀好意的人的目的可能并不在想要窃听你发送了什么,而是想伪造发送的内容让你相信。通过同时替换摘要和内容,很简单就实现了。所以摘要需要经过加密,不怀好意的人没有私钥,无法完成加密。或者说你收到的东西只要能用公钥解密,你才认为这个东西确实是对应私钥持有者完成的。这叫做当事人不可抵赖,同时别人无法仿冒。(数字签名:不可抵赖+无法仿冒)
为什么不直接对内容加密,而是先生成摘要,对摘要加密?
有可能内容很长,导致加密时间很长,因此摘要算法可以把无限长的内容输出成长度固定的摘要,再读摘要进行加密,这个加密时间就是可以预估的。
数字证书
证书授权中心
简称CA(Certificate Authority),它是负责管理和签发证书的第三方机构,作用是检查证书持有者身份的合法性,并签发证书,以防证书被伪造或篡改。
定义
发送方先把自己的公钥给CA,CA对其进行加密得到加密后的发送方公钥(用的是CA的私钥和CA加密算法),也就是CA的数字证书。
生成数字证书的两个加密算法有什么不同
- 一个算法是发送方加密摘要的,用于生成数字签名
- 另一个算法是CA加密发送方公钥的,用于生成数字证书。两个算法相互独立,没有必然联系。
如果数字证书是为了保证发送方公钥不是别人伪造的,那如何保证数字证书不是伪造的
CA是第三方机构,CA公钥是公开的,接收方可以跟别人比对(比如在网上查询),因此不可能伪造。但是发送方公钥,接收方是通过通信得到的,收到后无法验证。
HTTP1.0、1.1、2.0之间的区别
HTTP1.0
- 不能保存用户状态
- 这个是短连接,客户端发起一次请求,服务端响应请求后连接就会断开。
HTTP1.1
- 支持长连接,客户端发起一次请求,服务端响应请求后连接就不会断开,下次再连接的时候不用再进行三次握手,节省资源
- 请求并行发送(但不是并行传输),相应仍然需有序返回。
- 增加缓存处理(新的字段如cache-control)
- 增加Host字段,适应虚拟主机技术发展,即一台服务器支持多台主机
- 支持断点传输
HTTP2.0
- 二进制分帧
- 支持并行传输
- 多路复用(或连接共享)
- 头部压缩,encoder
- 服务器推送
HTTP状态码
类别 | 原因短语 | |
---|---|---|
1XX | Information(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常主力完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求,客户端的错误 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错,服务端的错误 |
状态码 | |
---|---|
200 | 请求正常处理,返回200OK和Json数据 |
204 | 请求正常处理,但没有资源返回 |
206 | 对资源某一部分的请求 |
301 | 对资源url的更新,永久性重定向 |
302 | 对资源url的更新,临时性重定向,发起请求时有可能从Post变为Get |
303 | 对资源url的更新,该状态码表示请求的资源存在另外一个URI,应使用GET方法定向获取请求资源 |
304 | 资源已找到,但是不符合条件请求,返回时不包含响应的主体部分 |
307 | 临时重定向,发起请求时不会从Post变为Get |
400 | 请求报文存在语法错误 |
401 | 本页面需要验证 |
403 | 不允许访问这个资源 |
404 | 服务器没有这个资源 |
500 | 服务器内部资源故障 |
503 | 服务器超负载或者正在维护 |
http请求报文有什么?
分别是响应报文和请求报文
请求报文
- 由请求行,首部行和实体体组成。
- 请求行有三个字段,分别是方法字段、URL字段和HTTP版本字段。
- 方法字段有GET、POST、HEAD、PUT、DELETE。
- 首部行指明对象所在主机,指明浏览器类型,指明用户想要得到的语言版本,若没有就返回默认版本。
- 若请求的是GET则实体体为空。POST实体体不为空,POST实体体即为用户输入的表单。
响应报文
- 由状态行、首部行和实体体组成。
- 实体体是报文的主要部分,它包含所请求的对象本身。
- 状态行有三个字段:协议版本字段、状态码和相应状态信息。
http缓存
缓存分类
数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存
浏览器缓存
强缓存
相关变量
Expires | 缓存过期时间,用来指定资源到期的时间。Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。 |
---|---|
Cache-Control | Cache-Control是一个相对时间,如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。Cache-Control与Expires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高。 |
s-maxage | 同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。 |
public | 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。 |
private | 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。 |
no-cache | 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器 |
no-store | 禁止缓存,每次请求都要向服务器重新获取数据。 |
must-revalidate | 指定如果页面是过期的,则去服务器进行获取 |
原理
命中强缓存时,浏览器并不会将请求发送给服务器,直接从缓存获取返回客户端。在Chrome的开发者工具中看到http的返回码是200,
协商缓存
原理
若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。
Last-Modify/If-Modify-Since
- 浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。
- 当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
- 如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以一致)。于是有了ETag/If-None-Match。
ETag/If-None-Match
- Etag/If-None-Match返回的是一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。
- ETag优先级比Last-Modify高,一般是先判断ETag,若相等,再判断Last-Modify。
ETag生成方法
- 文件的i-node编号,此i-node非彼iNode。是Linux/Unix用来识别文件的编号。是的,识别文件用的不是文件名。使用命令’ls –I’可以看到。
- 文件最后修改时间。
- 文件大小。
为什么有了Last-Modified还要Etag呢
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
流程图
http和https的区别
- https协议需要到CA (Certificate Authority)。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的。Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息)