为了让用户能够拥有更加良好的用户体验,优化页面加载速度成为前端开发过程中极其重要的一环,而网络资源的传输速度无可厚非成为了优化提速最重要的部分,知道网络传输的各个环节的来龙去脉才能更好地去优化,因此作为一名合格的前端开发人员还是有必要了解网络相关的知识。
HTTP的发展进程
HTTP0.9
HTTP0.9当时主要为了简单的用于网络之间传输HTML超文本内容,所以称为超文本传输协议,实现也相对简单
流程如下

- 基于TCP协议,客户端根据IP和端口号和服务器建立TCP连接,建立连接过程就是TCP协议的三次握手过程
- 建立好连接通过GET请求获取index.html
- 服务器接收请求信息之后,读取对应的 HTML 文件,并将数据以 ASCII 字符流返回给客户端。
- HTML文档传输完成,断开连接
HTTP1.0

- 引入请求头和回应头
由于万维网高速发展,出现了js,css以及邮件等多种形式的文本,单纯的get请求和ASCII字符流无法满足需求,通过请求头和回应头指明文件类型和字符编码以及语言等信息content-encoding content-type
- 引入状态码
有的请求服务器可能无法处理,或者处理出错,这时候就需要告诉浏览器服务器最终处理该请求的情况,这就引入了状态码。状态码是通过响应行的方式来通知浏览器的
- 提供了Cache机制
为了减轻服务器的压力,在 HTTP/1.0 中提供了Cache 机制,用来缓存已经下载过的数据。
- 加入用户代理字段
服务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了用户代理的字段。
HTTP1.1
- 改进持久连接以及CDN域名的分片机制
由于请求资源的增多,HTTP1.0的短连接方式无法满足需求,HTTP1.1增加了connection:keep-alive(默认激活,关闭改为close),同一个域名可以建立6个TCP连接(这也是为啥需要配置多个DNS域名的原因增加TCP连接量)
下图是1.0和1.1的请求对比

- 不成熟的HTTP管线化(部分浏览器尝试失败)
持久连接虽然减少了TCP的连接断开次数,但是单个TCP通道请求队列需要每个请求发送完得到回应才能进行下一个任务的请求,发生队头阻塞,所以将请求批量发送给服务器,但服务器依然需要按顺序依次处理返回
- 提供虚拟主机支持
由于一个服务器上面增设多个虚拟主机,也就是一个IP地址对应多个域名,HTTP1.1头部增加了Host字段
- 对动态生成的内容完美支持

之前传输内容需要标明内容大小,一次性传输完,随着内容的增大,引入了chunk transfer机制
- 引入cookie以及安全机制
HTTP2.0
HTTP1.1的问题
- HTTP1.1慢启动影响资源首次加载速度
TCP建立连接后,刚开始请求传输速度比较慢然后逐渐的不断提速(主要是为了防止出现网络拥堵),这样会让页面的首次渲染时间变长
- 开启多个TCP管道,出现带宽的竞态问题
多个TCP管道一起开启一旦出现网速下降,无法识别资源的优先级,出现竞态问题
- 单个TCP管道队头阻塞
由于管线化不成熟,队头阻塞依然存在
HTTP2.0的更改
- 多路复用机制
鉴于以上的问题,HTTP2.0引入二进制的分帧层机制来实现多路复用,关于多路复用的实现如下:

- 单个域名之下仍然只允许建立一个TCP管道,使用一个TCP长连接(整个页面资源下载只需要一次慢启动,而且避免了竞态)
- 浏览器准备好请求数据(请求行+请求头+请求体),然后分帧层对每个请求进行分割,将同一个请求的分割块打上相同的ID编号,通过协议栈将所有的分割体发给服务器
- 服务器端的分帧层根据ID编号进行请求组装
- 服务器的分帧层将回应数据分割按同一个回应体进行ID分割回应给客户端
- 客户端拼装回应
- 可以设置请求的优先级
客户端的分帧层对分割块标上请求的优先级
服务器推送 服务器根据请求的资源主动推送其他与该请求资源关联的资源(比如请求html,服务器顺便回应内嵌的js和css资源)
头部压缩 请求头压缩,增加传输效率
HTTP3.0
HTTP2.0虽然采用多路复用机制解决大多数问题,但是和HTTP1.1一样,TCP管道传输途中也会出现丢包问题(丢包就必须等待重新发包),造成队头阻塞,这样2.0的单个TCP长连接丢包率过高的情况下(高于2%)还不如1.1的6个管道传输效率,并且2.0的TCP建立连接三次握手以及HTTPS的TSL连接也会耗费较多时间
由于TCP协议的僵化以及底层包括中间设备的僵化,无法再进行修改,于是3.0基于UDP协议开发了QUIC协议

- 实现了类似 TCP 的流量控制、传输可靠性的功能。
- 集成了 TLS 加密功能。
- 实现了 HTTP/2 中的多路复用功能。 和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。

- 实现了快速握手功能。
HTTPS
HTTPS在HTTP基础上增加了安全层(SSL安全套接层/TSL传输层安全)
安全层的两个主要职责:对发起HTTP请求的数据进行加密操作和对接收到的HTTP内容进行解密操作

对称加密
对称加密是指加密和解密都使用的是相同的密钥
- 速度快 但 秘钥传递过程容易被中间人劫持
非对称加密
非对称加密算法有 A、B 两把密钥,如果你用 A 密钥来加密,那么只能使用 B 密钥来解密;反过来,如果你要 B 密钥来加密,那么只能用 A 密钥来解密
- 第一个是非对称加密的效率太低
- 第二个是无法保证服务器发送给浏览器的数据安全,服务器发送给客户端的数据只能用私钥加密,公钥每个人都有,所以中间人可解密服务端到客户端的数据
混合加密
在传输数据阶段依然使用对称加密,但是对称加密的密钥我们采用非对称加密来传输

- 虽然混合加密比较安全,但我们无法知道数据是否被篡改,服务端无法知道加密是否是对应客户端的随机数,客户端也无法知道获取的一定是服务端给的公钥
CA认证

- 服务器生成公钥A+私钥A,将公钥A和信息(公司、网站等)发送给CA机构认证
- CA用通过线上线下渠道确认该公司信息,审核通过然后对信息进行hash加密,生成
信息摘要,然后用自己的私钥B对信息摘要加密生成数字签名,将数字签名和信息装在一起组成数字证书发给服务器 - 服务器将数字证书发给客户端
- 首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验
- 浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
- 如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密
- 浏览器使用相同的hash算法根据证书内容计算出信息摘要,将这个计算的值与证书解密的值做对比
- 对比结果一致,则证明服务器发来的证书合法,没有被冒充。此时浏览器就可以读取证书中的公钥,用于后续加密了
- 客户端用CA的私钥B解密 得到消息摘要,并对原始信息采用同样hash算法做比较,确认公钥未被篡改
- 客户端生成随机数字采用公钥加密随机数,发给客户端
- 客户端解密获取随机数,建立对称加密信息传输通道
cookie
为啥会产生cookie?
由于HTTP1.X是一个无状态协议,也就是客户端同一个请求发送多次,服务端并不能识别是不是同一个客户端发送,为了解决无状态情况,出现了cookie
cookie设置流程
客户端请求服务端 -> 服务端回应头部set-cookie -> 客户端收到并保存到本地 -> 客户端请求携带头部字段cookie
cookie属性
| 属性 | 解释 |
|---|---|
| expires | 有效期,以客户端为准 |
| max-Age | 正数s,负数s立刻删除,0为会话cookie即关闭浏览器就是消失 |
| Domin | cookie送达的主机名 |
| Path | 携带cookie的资源路径 |
| Secure | 标记为Secure只会https发送 |
| HttpOnly | 标记为HttpOnly前端无法通过document.cookie获取,避免xss攻击 |
| SameSite | Chrome80新加入的属性 |
cookie作用
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
SameSite
比如当前网页www.renrendai.com为一方请求,请求后端必然根据设置的domin和path会携带对应的cookie,但是比如通过www.baidu.com等三方网站点击跳转到www.renrendai.com的请求会根据SameSite的设定一方请求是否携带cookie;
所谓同站(一方)就是顶级域名和二级域名相同 eg: a.taobao.com 和 b.taobao.com 顶级域名为.com, 二级域名为taobao, 也就是前面截去.后面截去顶级域名,中间部分为二级域名 a.a.xx.cn二级域名为a.xx
- 异步请求(不会改变当前页面,也不会打开新页面),比如通过
<script>、<link>、<img>、<iframe>等标签发起的请求,还有通过各种发送 HTTP 请求的 DOM API(XHR,fetch,sendBeacon)发起的请求。 - 同步请求(可能改变当前页面,也可能打开新页面),比如通过对
<a>的点击,对<form>的提交,还有改变 location.href,调用 window.open() 等方式产生的请求。
SameSite三个值
- strict所有三方的链接都不会携带cookie,比如你当前淘宝处于登录态,但是从百度跳转到淘宝的页面却没有登录态,因而无法发起csrf攻击
- lax只有同步且是get请求才可携带cookie
- none所有三方的请求都会携带cookie
Token
token解决的问题
- 完全由应用端管理,避开了同源策略
- token可以避免csrf攻击
- 可以多服务器之间共享
如何解决token过期问题
- token发送给服务端,服务端缓存过期时间,每次请求都查看过期时间,如果过期则直接推迟过期时间
- 前端将token发送给服务端,服务端发现token过期提示前端,前端调用后端的refresh刷新过期时间
token组成
JWT格式:Header.Payload.Signature
Header = {
alg: "HS256", // 签名算法
typ: "JWT" // 令牌类型
}
Payload = { // 内容提
sub: '123123',
name: 'Jone',
admin: true,
}
Signature = Hash256(`${base64(header)}.${base64(patload)}.${secret}`)
分离认证服务


网络安全
TCP/IP
TCP/IP 协议实际上是一系列网络通信协议的统称,其中最核心的两个协议是TCP和IP,其他的还有 UDP、ICMP、ARP 等等,共同构成了一个复杂但有层次的协议栈。
IP协议(Internet Protocol) 主要目的是解决寻址和路由问题,以及如何在两点间传送数据包,采用IP地址来定位互联网的每一台计算机(IPV4/IPV6)
TCP协议(Transmission Control Protocol) 它位于 IP 协议之上,基于 IP 协议提供可靠的、字节流形式的通信,是 HTTP 协议得以实现的基础。保证数据的完整性和不丢失
HTTP 是一个"传输协议",但它不关心寻址、路由、数据完整性等传输细节,而要求这些工作都由下层来处理。因为互联网上最流行的是 TCP/IP 协议,而它刚好满足 HTTP 的要求,所以互联网上的 HTTP 协议就运行在了 TCP/IP 上,HTTP 也就可以更准确地称为“HTTP over TCP/IP”。
分层
TCP/IP协议总共有四层,如下

应用层决定了向用户提供应用服务时通信的活动。 TCP/IP协议族内预存了各类通用的应用服务。比如,FTP(File Transfer Protocol,文件传输协议)和DNS(Domain Name System,域名系统)服务就是其中两类。HTTP协议也处于该层。
传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。 在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据报协议)。传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。 在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据报协议)。
网络层(又名网络互连层) 网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。 与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
链路层(又名数据链路层,网络接口层) 用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内
七层协议

工作原理

- 应用层根据请求信息生成请求报文(请求行+请求头+请求体)
- 在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。
- 网络层增加通信的Mac地址,搜索对方的地址,一边中转一边传送
- 接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的HTTP请求。
- 发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
TCP三次握手和四次挥手
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。

DNS
全称 Domain Name System ,即域名系统。在 TCP/IP 协议中使用 IP 地址来标识计算机,数字形式的地址对于计算机来说是方便了,但对于人类来说却既难以记忆又难以输入。所以出现了域名

DNS结构
- 根域名服务器(Root DNS Server):管理顶级域名服务器,返回“com”“net”“cn”等顶级域名服务器的 IP 地址;
- 顶级域名服务器(Top-level DNS Server):管理各自域名下的权威域名服务器,比如 com 顶级域名服务器可以返回 apple.com 域名服务器的 IP 地址;
- 权威域名服务器(Authoritative DNS Server):管理自己域名下主机的 IP 地址,比如 apple.com 权威域名服务器可以返回 www.apple.com 的 IP 地址。
- 本地域名服务器 (Local DNS Server),很多大公司和网络运营商建立自己的DNS服务器

DNS查询过程
iOS设备请直接跳到第三步骤
首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
如果本地Host文件中没有那么操作系统会把这个域名发送给这里设置的LocalDNS,也就是本地区的域名服务器。这个DNS通常都提供给你本地互联网接入的一个DNS解析服务。这个专门的域名解析服务器性能都会很好,它们一般都会缓存域名解析结果,当然缓存时间是受域名的失效时间控制的,一般缓存空间不是影响域名失效的主要因素。
如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。
根域名服务器返回给本地域名服务器一个所查询的域的主域名服务器(gTLD Server)地址。gTLD是国际顶级域名服务器,如.com,.cn、.org等。全球只有13台左右。
本地域名服务器(Local DNS Server)再向上一步返回的gTLD服务器发送请求。
接受请求的gTLD服务器查找并返回此域名对应的Name Server域名服务器的地址,这个Name Server通常就是你注册的域名服务器,例如你在某个域名服务提供商申请的域名,那么这个域名解析任务就由这个域名提供商的服务器来完成
Name Server域名服务器会查询存储的域名和IP的映射关系表,正常情况下都根据域名得到目标IP记录,连同一个TTL值返回给DNS Server域名服务器。
返回该域名对应的IP和TTL值,Local DNS Server会缓存这个域名和IP的对应关系,缓存的时间由TTL值控制。
返回该域名对应的IP和TTL值,Local DNS Server会缓存这个域名和IP的对应关系,缓存的时间由TTL值控制。

CDN
CDN,全称Content Delivery Network,根本的作用是将网站的内容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。他-有别于镜像,它比镜像更智能,可以这样做一个比喻:CDN=镜像(Mirror) + 缓存(cache) + 整体负载均衡(GSLB),因而,CDN可以明显提高Internet中信息流动的效率。目前CDN都以缓存网站中的静态数据为主,如CSS、JS、图片和静态网页等数据。用户在从主站服务器请求到动态内容后再从CDN上下载这些静态数据,从而加速网页数据内容的下载速度,如淘宝有90%以上的数据都是由CDN来提供的。这里引用一个网上比较形象的例子:A家的网速 100M的,但他只用了10M的速度,B家的网速是10M的,但是他需要15M的速度才行。怎么办呢。 C是一家CDN服务商,在A家有个节点(就像A是一个赞助商一样)B在C家买了CDN加速服务。当B的速度不够的时候,CDN加速就会选择有节余的节点来帮B,提高B的速度。这样B的速度就能达到或超过15M ,皆大欢喜。A没浪费,B速度有了,C赚了钱。 当C的节点在全国都有,非常多的时候。那么你用C家的CDN加速服务,你就会健步如飞了。
CDN工作流程
一个用户访问某个静态文件(如CSS),这个静态文件的域名假如是www.baidu.com,而这个域名最终会被指向CDN全局中CDN负载均衡服务器,再由这个负载均衡服务器来最终分配是哪个地方的访问用户,返回给离这个访问用户最近的CDN节点。之后用户就直接去这个CDN节点访问这个静态文件了,如果这个节点中请求的文件不存在,就会再回到源站去获取这个文件,然后再返回给用户。
代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理不改变请求URI,会直接发送给前方持有资源的目标服务器。持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过代理服务器后再传给客户端。
代理服务器种类
- 匿名代理:完全“隐匿”了被代理的机器,外界看到的只是代理服务器;
- 透明代理:顾名思义,它在传输过程中是“透明开放”的,外界既知道代理,也知道客户端;
- 正向代理:靠近客户端,代表客户端向服务器发送请求;
- 反向代理:靠近服务器端,代表服务器响应客户端的请求;
代理可以做的事情
- 负载均衡:把访问请求均匀分散到多台机器,实现访问集群化;
- 内容缓存:暂存上下行的数据,减轻后端的压力;
- 安全防护:隐匿 IP, 使用 WAF 等工具抵御网络攻击,保护被代理的机器;
- 数据处理:提供压缩、加密等额外的功能。
网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务。利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。
隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。
HTTP请求方式

常见状态码
- 1××:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
- 2××:成功,报文已经收到并被正确处理;
- 3××:重定向,资源位置发生变动,需要客户端重新发送请求;
- 4××:客户端错误,请求报文有误,服务器无法处理;
- 5××:服务器错误,服务器在处理请求时内部发生了错误。
| 状态码 | 含义 |
|---|---|
| 200 OK | 表示从客户端发来的请求在服务器端被正常处理了。 |
| 220 No Content | 该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。 |
| 206 Partial Content | 该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。 |
| 301 Moved Permanently | 永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。也就是说,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。 |
| 302 Found | 临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。和301 状态码相似,但302状态码代表的资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的URI将来还有可能发生改变。比如,用户把URI保存成书签,但不会像301状态码出现时那样去更新书签,而是仍旧保留返回302状态码的页面对应的URI。 |
| 304 Not Modified | 该状态码表示客户端发送附带条件的请求[插图]时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)。304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系 |
| 400 Bad Request | 该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像200 OK一样对待该状态码。 |
| 401 Unauthorized | 该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。另外若之前已进行过1次请求,则表示用户认证失败。返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询(challenge)用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。 |
| 403 Forbidden | 该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。 |
| 404 Not Found | 该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。 |
| 500 Internal Server Error | 该状态码表明服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障。 |
| 503 Service Unavailable | 该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入Retry-After首部字段再返回给客户端。 |
首部字段
| 首部字段名 | 说明 |
|---|---|
| 通用首部字段 | |
| Cache-Control | 控制缓存的行为 |
| Connection | 逐跳首部、连接的管理 |
| Date | 创建报文的日期时间 |
| Pragma | 报文指令 |
| Trailer | 报文末端的首部一览 |
| Transfer-Encoding | 指定报文主体的传输编码方式 |
| Upgrade | 升级为其他协议 |
| Via | 代理服务器的相关信息 |
| Warning | 错误通知 |
| 请求首部字段 | |
| Accept | 用户代理可处理的媒体类型 |
| Accept-Charset | 优先的字符集 |
| Accept-Encoding | 优先的内容编码 |
| Accept-Language | 优先的语言(自然语言) |
| Authorization | Web认证信息 |
| Expect | 期待服务器的特定行为 |
| From | 用户的电子邮箱地址 |
| Host | 请求资源所在服务器 |
| If-Match | 比较实体标记(ETag) |
| If-Modified-Since | 比较资源的更新时间 |
| If-None-Match | 比较实体标记(与lf-Match相反) |
| If-Range | 资源未更新时发送实体Byte的范围请求 |
| If-Unmodified-Since | 比较资源的更新时间(与lf-Modified-Since相反 |
| Max-Forwards | 最大传输逐跳数 |
| Proxy-Authorization | 代理服务器要求客户端的认证信息 |
| Range | 实体的字节范围请求 |
| Referer | 对请求中URI的原始获取方 |
| TE | 传输编码的优先级 |
| User-Agent | HTTP客户端程序的信息 |
| 响应首部字段 | |
| Accept-Ranges | 是否接受字节范围请求 |
| Age | 推算资源创建经过时间 |
| ETag | 资源的匹配信息 |
| Location | 令客户端重定向至指定URI |
| Proxy-Authenticate | 代理服务器对客户端的认证信息 |
| Retry-After | 对再次发起请求的时机要求 |
| Server | HTTP服务器的安装信息 |
| Vary | 代理服务器缓存的管理信息 |
| WWW-Authenticate | 服务器对客户端的认证信息 |
| 实体首部字段 | |
| Allow | 资源可支持的HTTP方法 |
| Content-Encoding | 实体主体适用的编码方式 |
| Content-Language | 实体主体的自然语言 |
| Content-Length | 实体主体的大小(单位:字节) |
| Content-Location | 替代对应资源的URI |
| Content-MD5 | 实体主体的报文摘要 |
| Content-Range | 实体主体的位置范围 |
| Content-Type | 实体主体的媒体类型 |
| Expires | 实体主体过期的日期时间 |
| Last-Modified | 资源的最后修改日期时间 |
浏览器缓存
缓存优点
- 减少冗余的数据传输
- 减少服务器的负担,大大提升了网站的性能
- 加快了客户端加载网页的速度
分类
强缓存

流程
客户端首次请求,服务端回应头部附带expires/Cache-Control
客户端缓存资源,二次请求直接在内存缓存查找,未找到则在磁盘缓存查找
问题
expires由于为绝对时间,服务器和客户端可能存在时间偏差,导致缓存发生混乱
Cache-Control优先级高于expires
Cache-Control的常用值

协商缓存
Last-Modified --> If-Modified-Since
ETag --> If-None_match

Last-Modified流程
客户端首次请求,服务端回应头部附带Last-Modified:Date表示该资源的最后修改时间
客户端后续请求都会头部附带If-Modified-Since:Date,服务器通过比对最后修改时间
命中则返回304,否则返回资源并附带新的Last-Modified
ETag流程
客户端首次请求,服务端回应头部附带ETag:文件唯一标识符
客户端后续请求都会头部附带If-None-Match:文件唯一标识符
服务端对比标识符来判断是否文件发生了更改
命中回应304
问题
- 编辑了资源但资源内容未发生改变,也会被当做修改了,重新缓存
- 修改文件速度太快,if-modified-since只能识别1s以上的时间差