http cache 总结

了解Web缓存的不同类型,包括数据库缓存、CDN缓存、代理服务器缓存和浏览器缓存,及其对优化前端性能的影响。掌握HTTP响应头中与缓存相关的指令,如Expires、Cache-Control、Last-Modified、ETag等,以及如何定义最佳的Cache-Control策略。

转载自:https://blog.youkuaiyun.com/weixin_40817115/article/details/86707180

通过网络请求获取资源既慢又昂贵。大量的请求在服务端和客户端之间往返,使得资源可用时间以及浏览器可处理它们的时间都有了延迟,同时用户访问的数据成本也会增加。因此,缓存和重用已获取的资源是优化前端性能的一个关键点。

所谓缓存,就是将已经请求得到的内容放在一个就近的仓库存放起来,下次请求可以不再向服务器请求,而是直接从这个缓存仓库获取。
Web缓存主要有以下几个优势:

  • 减少网络延迟,加快页面响应速度。增强用户体验。
  • 减少网络带宽的消耗
  • 减轻服务器压力

Web缓存的种类

Web缓存类型描述
数据库缓存当web应用关系复杂,数据表蹭蹭蹭往上涨时,可以将查询后的数据放到内存中进行缓存,下次再查询时,就直接从内存缓存中获取,从而提高响应速度。
CDN缓存当我们发送一个web请求时,CDN会帮我们计算去哪得到这些内容的路径短且快。这个是网站管理员部署的,所以他们也可以将大家经常访问的内容放在CDN里,从而加快响应。
代理服务器缓存代理服务器缓存,跟浏览器缓存性质类似,但是代理服务器缓存面向的群体更广,规模更大。它不只为一个用户服务,一般为大量用户提供服务,同一个副本会被重用多次,因此在减少响应时间和带宽使用方面很有效。
浏览器缓存每个浏览器都实现了 HTTP 缓存,我们通过浏览器使用HTTP协议与服务器交互的时候,浏览器就会根据一套与服务器约定的规则进行缓存工作。当我们在浏览器中点击前进后退 按钮时,利用的便是浏览器的缓存机制。

注意:

由于当前所有浏览器都默认附带实现了HTTP缓存,这在给大家再来性能优化的同时,也可能附带一些容易忽略的坑。所以我们必须在服务端返回正确的HTTP header指令来告诉浏览器当前response的缓存策略以及其缓存时间。

Tips:

如果你在你的应用中是使用Webview来获取和显示内容,你可能需要添加其他配置以确保启用浏览器缓存, 它的大小应该与你的用例匹配,缓存持久有效。查阅相关平台文档确保配置准确无误。

在这里插入图片描述
当服务端返回响应时,同时附带发出一个HTTP header的集合,描述了它的content-type(内容类型)、Content-length(长度)、缓存指令以及验证令牌等等。如上图,服务端返回了一个长度为1024字节的response,并且提供了一个验证令牌(“x234dff”),ETag用于在响应过期后验证资源是否已被修改。

http响应头中与缓存相关的指令字段:

  • Expires : 告诉浏览器在该时间之前,可以直接从缓存中获取资源,而无需向服务器获取。注意: 该时间是GMT 时间,而不是本地时间。 缺点是 如果客户端和服务器端时间不一致,则会导致资源过早或者过晚过期。
  • Cache Control :优先级高于Expires,如果同时设置了Cache Control 和Expires, Expires会被忽略。可以代替expires,  使用max-age    相对时间 代替 Expires 绝对时间 ,避免了客户端和服务器端时间不一致的问题。
  • Last-Modified: 优点 请求服务器id时候如果发现文件真的没有修改,只返回304状态不返回数据,缺点是无法解决1秒钟修改2次的问题
  • If-Modified-Since:
  • Etag:      优点 请求服务器id时候如果发现文件真的没有修改,只返回304状态不返回数据  可以替代Last-Modified,但是如果Last-Modified获取方便并且 不考虑1秒钟2次的问题,可以使用Last-Modified。
  • If-None-Match:

一、使用ETags验证缓存的response

  • 服务器使用http header ETag来传递验证令牌;
  • 有了验证令牌,可以有效的进行资源更新的检查; 如果资源没有更改,则不会传输任何数据。
    例如:

浏览器发起上一次的get请求已经超过了120s(Cache-Control:max-age=120),并且浏览器发起对同一资源的新请求。
首先,浏览器检查本地缓存并找到先前的响应。但是响应已过期,无法使用之前的response。此时,浏览器可以发起新的请求并获取新的完整的响应结果,但是效率相对低下,因为资源并没有被修改,没有必要重复下载已经存在缓存中的资源。

这就是ETag会解决的问题。服务器生成并返回任意ETag,该ETag通常是文件内容的散列或其他指纹。客户端不需要知道ETag是如何生成的;它只需要在下一个请求时将其发送到服务器。如果ETag的值仍然相同,则资源未更改,可以跳过下载,访问本地缓存资源。
在这里插入图片描述
如上图,客户端在HTTP请求头中自动提供了If-None-Match,这个If-None-Match就是上次请求服务器时,服务器返回的Etag。服务端根据当前所访问的资源检查ETag。如果没有改变,则服务端返回304 Not Modified,告诉浏览器当前所访问的资源并没有发生修改,可以继续用浏览器中的缓存,并将缓存时间重新计时120s。此时,浏览器不会在下载response,可以节省时间和带宽

作为Web开发人员,如何进行有效的重新验证呢?在这里,浏览器已经帮我们完成了全部工作。浏览器会自行检测先前是否已经指定验证令牌,并在发出请求时将验证令牌附加到Http请求头中,并根据从服务端收到的response更新缓存时间戳。唯一需要做的事情是需要确保服务端会提供必要的ETag令牌。

Tips:

Github项目 [h5bp/server-configs](https://github.com/h5bp/server-configs)包含了流行服务器的配置文件示例代码,并配有详细的注释。你可以在其中找到自己所使用的服务器,并查找相应的配置来确认自己的服务器配置是否准确。
在这里插入图片描述

二、Cache-Control

  • 每个资源都可以通过http header Cache-Control来定义其缓存策略。
  • Cache-Control指令指明了谁来缓存响应、缓存条件以及缓存时间。

从性能优化的角度来看,最好的请求是不需要与服务端进行交互——一个本地的响应副本可以消除所有的网络延时并避免数据传输时的数据费用。 因此,HTTP规范允许服务器返回[Cache-Control] (https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9)指令,该指令用来控制浏览器及其他中间缓存件如何缓存单个响应以及缓存多长时间。

Tips:

Cache-Control标头被定义为HTTP / 1.1规范的一部分,并且取代了原先用于定义response缓存策略的Expire等,现在所有的现代浏览器都支持HTTP Cache-Control。

2.1 “no-cache”和“no-store”

在这里插入图片描述
no-cache:有缓存,但是不直接使用缓存,需要经过校验。
如果资源已经发生更改,在没有与服务端进行校验前,浏览器不能用前面返回的response用于满足对同一URL的后续请求。如果浏览器提供了正确的ETag,当配置了no-cache时,客户端会先发出请求向后端验证资源是否发生更改,如果资源未更改,则可以取消下载。
no-store:完全没有缓存,所有的资源都需要重新发请求
当服务端对资源设置了no-store时,不允许浏览器和所有中间层缓存response。。例如:一些类似于银行及其他隐私数据不适合缓存,每次的用户请求都需要发送到服务端,下载全部的response。

2.2 “public” 和 “private”

public
如果response被标记为“public”,那么,即使有与其相关的HTTP认证信息或者返回的response是不可缓存的status code,它依然可以被缓存。大多数情况下,public并不是必需的,因为其他具体指示缓存的信息,如max-age会表明当前的response在任何情况下都是要缓存的。
private
相比之下,浏览器可以缓存private的response。但是,这些响应通常只用于单个用户,因此不允许其他中间缓存对齐进行缓存。例如:一个用户的浏览器可以带有用户私有信息的HTML页面,但是CDN无法缓存页面。

2.3 max-age

max-age指令指定了允许重用缓存的response的最长时间(以秒为单位)。例如,max-age=60表示response可以缓存,并且在接下来的60s内可以被重用,无需发出新的request请求。

三、 定义最佳的Cache-Control策略

在这里插入图片描述
遵循上面的流程图为应用程序中使用的特定资源或一组资源制定最佳缓存策略。理想的情况下,我们应该在客户端上在尽可能长的时间中缓存尽可能多的响应,并为每个响应提供验证令牌(ETag),从而实现有效的重新验证。

Cache-Control指令和解释

指令解释
max-age=86400Response can be cached by browser and any intermediary caches (that is, it’s “public”) for up to 1 day (60 seconds x 60 minutes x 24 hours).
private, max-age=600Response can be cached by the client’s browser only for up to 10 minutes (60 seconds x 10 minutes). 不能被代理服务器缓存。
public响应可以被任何缓存区缓存。
no-cache浏览器对请求回来的response做缓存,但是每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性
no-storeResponse is not allowed to be cached and must be fetched in full on every request. 禁止一切缓存。

根据HTTP档案,排名前300,000(按照Alexa)的网站中,浏览器可以缓存几乎一半的下载响应,这对于网页的重复浏览和访问来说是个巨大的节省。当然,这并不意味着你的应用程序可以缓存50%的资源。有些网站的静态资源几乎不会变动,可能可以缓存超过90%的资源;其他网站可能有很多私有的或者是时间敏感的数据完全不能使用缓存。

审核自己的页面,确认哪些资源是可以缓存的并且确保它们返回了合适的Cache-ControlEtag

四、作废和更新缓存的response

  • 本地缓存的response可以一直被使用,直到资源expires
  • 在URL中嵌入一个文件内容的指纹可以强制客户端不使用缓存,更新response
  • 每个应用程序都需要定义自己的缓存层次结构来获得最佳性能。

所有从浏览器发出去的请求首先要路由到浏览器缓存中,检验是否存在可以用来完成该请求的有效缓存。如果有匹配的缓存,则response从缓存中读取,从而消除网络延迟和传输引起的数据成本。

如何作废或者更新一个缓存的response
例如: 你已经告知访问者缓存一个css样式表24h(max-age = 86400),但是开发者刚刚提交了你希望向所有用户提供的更新。这时该如何通知访问者更新原有的缓存呢?此时,如果不改变资源的URL,无法更新资源。因为浏览器认为当前的缓存尚未过期。

浏览器缓存响应之后,直到根据max-age或者expire指示,缓存已过期或者缓存被清理调,都会使用缓存的资源。因此,在页面构建时,或者说在访问某个网站时,不同的用户可能使用不同版本的资源。刚刚获取资源的用户使用的是最新版本,但缓存了早期资源(仍然有效)的用户依然使用旧版本的资源。

如何充分利用“客户端缓存”和“快速更新”?
在资源内容更改时,改变资源的URL,强制用户下载新的response。通常,我们可以通过在文件名中嵌入版本号或者其他文件指纹来实现改变URL,例如:style.x234dff

定义每个资源的缓存策略(定义缓存结构层次),不仅可以控制每个资源的缓存时长,还可以控制访问者获取和查看新版本的速度。
在这里插入图片描述
如上图中的例子:

  • HTML文件被标记为no-cache,意味着浏览器对于每个请求都会重新验证文档,如果资源内容发生改变,就会拉取最新版本。 此外,在HTML标记中,在css和javascript资源的URL中嵌入了指纹:如果这些文件的内容发生更改,HTML文件也会更改,从而加载一个HTML 响应的新副本。
  • CSS允许浏览器和其他中间缓存(例如:CDN)进行缓存,过期时间为1年。其实,我们也可以使用far future expires of 1 year, 因为我们在文件名中嵌入了文件指纹,如果CSS文件发生更新,其请求的URL也会发生改变。
  • js文件的过期时间也设置为1年,但是标记为private,可能是因为它里面包含了一些CDN不应缓存的私有用户数据。
  • 图片文件中没有加版本和独一无二的hash指纹,直接进行缓存。缓存时间设置为1天。

结合ETagCache-Control独一无二的URL,可以实现最好的缓存策略:更长的过期时间、控制特定资源的缓存以及缓存位置、按需更新。

五、缓存设置清单

世界上没有最好的缓存策略。根据你的流量模式、所提供的数据类型以及应用程序对于资源新鲜度的特定需求,我们需要对每个资源以及整体的“缓存层次结构”制定适当的缓存策略。

制定缓存策略时的一些提示和技巧:

  1. 使用一致的URL(hash/version:如果对于内容完全相同的资源使用不同的URL,那么这个资源会不停地被获取和存储。Tips:URL需要区分大小写。
  2. 确保服务端提供了验证令牌(ETag): 验证令牌的存在避免了在服务端资源没有任何修改时传输完全相同的字节内容。
  3. 确定哪些资源可以被中介缓存(public/private:对于所有用户都相同的response可以在CDN和其他中介缓存中缓存。
  4. 确定每个资源的最佳缓存时长(max-age):不同的资源可能具有不同的新鲜度要求。审核并确认每个资源合适的max-age
  5. 确定当前网站的最佳缓存层次结构:结合资源的URL 和资源内容的指纹以及HTML的短缓存或者no-cache, 我们可以控制客户端获取和更新资源的速度。
  6. 减少混乱:有些资源的更新频率要高于其他资源。如果有一部分资源(比如:一个javascript函数或者一组CSS样式)需要经常更新,可以考虑将这一部分代码作为单独的文件。这样做,其余部分的资源(例如:不经常更新的库代码)就可以从缓存中提取。当获取更新时,使得需要下载内容的数量最小化

 

 

获取资源时,Http method 该用 get 还是 post?

如果参照 restful 标准,获取资源时 http method 应使用 get,但是有时候考虑到参数过长问题,部分时候会使用 post。正常情况,只是 定义不同,获取方式不同,实际对缓存策略也是有影响的。

==获取资源能用 GET 别用 POST==
因为 GET API 请求有 cache 机制支持,所以这是为什么请求不建议使用 POST。
POST 请求不提交 If-None-Match,所以 cache 不生效。另外参数不在URL,每次请求因为参数变化导致的 response 内容变化,ETag 也变化,cache 基本作废

 

<think>好的,我现在需要帮用户获取HTTP协议的简要总结和核心概念。首先,我应该回忆一下HTTP协议的基础知识,确保覆盖主要方面。用户要求简明,所以不能太冗长,但又要核心概念。 首先,HTTP的定义和基本特性。HTTP是应用层协议,基于请求-响应模型,无状态的,使用TCP作为传输层协议,默认端口80或443。这些都是基本点,需要提到。 接下来,核心概念部分。请求方法如GET、POST、PUT、DELETE等,状态码分类比如1xx到5xx。可能需要举几个常见的状态码例子,比如200、404、500。然后,报文结构,请求报文和响应报文的组成部分,比如请求行、首部字段、实体主体等。 然后,协议版本演变,从HTTP/1.0到HTTP/2和HTTP/3的主要改进,比如持久连接、头部压缩、二进制分帧、多路复用,以及HTTP/3使用QUIC协议基于UDP。这些变化对性能的影响需要简要说明。 安全性方面,HTTPS的加密机制,SSL/TLS的作用,以及证书的重要性。这里可能需要提到混合加密,即对称和非对称加密的结合,确保数据安全。 缓存机制,像Cache-Control和ETag这些头部字段的作用,如何帮助减少带宽和提高性能。 无状态和有状态管理,虽然HTTP本身无状态,但通过Cookie、Session和Token来维持状态,比如用户登录状态。这部分需要解释清楚无状态的限制和解决方案。 另外,参考用户提供的引用内容,引用[2]提到互联网的网际层是IP层,这可能和HTTP所在的层次有关,但HTTP属于应用层,所以需要明确分层结构。引用[4]中的哈希链可能和安全性相关,但不确定是否需要在这里提及,可能HTTPS的证书验证会涉及哈希,但简明总结的话可能不需要深入。 用户还希望生成相关问题,我需要考虑常见的问题,比如版本区别、HTTPS工作原理、状态码意义、Cookie机制等,确保问题覆盖核心概念的延伸。 检查是否有遗漏的重要点,比如持久连接、管线化、队头阻塞问题在HTTP/2中的解决,或者HTTP/3的改进。但简明总结可能需要简化这些内容,提到关键改进即可。 最后,组织内容结构,先定义,再核心概念分点,每个点简明扼要,使用中文,符合格式要求,行内公式用$...$,独立公式用$$...$$,但HTTP总结可能不需要太多数学公式,可能状态码用行内,比如状态码$200$,不过可能不需要。根据示例,可能用户希望代码块用```python,但这里可能用不到,除非举例请求报文结构,但用户示例中的快速排序用了代码块,但HTTP总结可能更多是文字描述,所以可能不需要代码块,除非展示示例请求和响应,但用户没有明确要求,可能保持文字即可。 确保引用正确,引用[2]提到IP层,可以用于说明HTTP在应用层,基于TCP/IP协议栈,所以可以添加引用标识。例如,在提到TCP作为传输层时,引用[2]关于IP层的描述,说明分层结构。 然后检查是否符合用户指令:使用中文,结构清晰,分核心概念,相关问题和回答真实可靠。 现在整理内容,确保每个部分简洁,核心概念分点明确,使用正确的格式,如加粗标题,列表项等。最后生成相关问题,围绕HTTP的核心概念,如版本差异、HTTPS、状态码、Cookie等。</think>### HTTP协议简明总结 **HTTP(超文本传输协议)** 是互联网应用层协议,基于客户端-服务器架构,通过请求-响应模式传输数据(如HTML、JSON等)[^2]。核心特性包括: 1. **无状态**:默认不保留会话信息,依赖额外机制(如Cookie)管理状态 2. **基于TCP**:默认端口80(HTTP)或443(HTTPS),HTTP/3开始支持基于UDP的QUIC协议 3. **可扩展性**:通过首部字段(Header)扩展功能 --- ### 核心概念 1. **请求与响应结构** - **请求报文**:方法(GET/POST等) + URL + 协议版本 + 首部字段 + 实体主体 ``` GET /index.html HTTP/1.1 Host: example.com ``` - **响应报文**:状态码(如$200$、$404$) + 状态描述 + 首部字段 + 实体主体 ``` HTTP/1.1 200 OK Content-Type: text/html ``` 2. **请求方法** - 基础方法:`GET`(获取资源)、`POST`(提交数据)、`PUT`(更新资源)、`DELETE`(删除资源) - 扩展方法:`PATCH`、`HEAD`(仅获取首部) 3. **状态码分类** - $1xx$:信息响应(如$101$协议切换) - $2xx$:成功(如$200$成功、$201$已创建) - $3xx$:重定向(如$301$永久重定向、$302$临时重定向) - $4xx$:客户端错误(如$400$请求无效、$404$资源未找到) - $5xx$:服务器错误(如$500$内部错误、$503$服务不可用) 4. **协议版本演进** - **HTTP/1.0**:短连接(每次请求新建TCP连接) - **HTTP/1.1**:持久连接、管线化(请求并行发送)[^2] - **HTTP/2**:二进制分帧、头部压缩、多路复用(解决队头阻塞) - **HTTP/3**:基于QUIC协议(UDP实现低延迟传输) 5. **安全性(HTTPS)** - 通过SSL/TLS加密通信,采用混合加密(非对称加密交换密钥 + 对称加密传输数据) - 数字证书验证身份,防止中间人攻击 6. **缓存机制** - 通过首部字段(如`Cache-Control`、`ETag`)控制资源缓存策略,减少重复请求 --- ### 应用场景与局限 - **场景**:网页浏览、API交互、文件传输 - **局限**:明文传输(HTTP不安全)、无状态需额外机制(如Token鉴权) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值