HTTP缓存
浏览器的缓存原理 (强缓存以及协商缓存)
Web 服务缓存 ⼤致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 服务器缓存)、浏览器缓存。
浏览器缓存 也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。 这⾥我们只讨论 HTTP 缓存相关内容 。
HTTP缓存: (优化⻚⾯加载的效率, 如果没有缓存策略, 每次重新加载⻚⾯, 会非常慢!)
强缓存
强缓存是利⽤http的返回的响应头中的Expires或者Cache-Control (优先级更⾼) 两个字段来控制的,⽤来表示资源 的缓存时间。
Expires: 指定⼀个具体时间(2023年3⽉27⽇ 17:00), 到了这个时间了, 缓存过期了, 在时间内, 都是有效的, 可以直接读,expires是一个时间点。
Cache-Control : 指定⼀个过期时间 (3600s), 这个资源你加载到后, 可以⽤ 3600s,cache-control是一个时间段
Cache-Control是⼀个 相对时间 ,例如Cache-Control:max-age 3600,代表着资源的有效期是3600秒。
Cache-Control与Expires可以在服务端配置同时启⽤或者启用任意⼀个,同时启⽤的时候Cache-Control优先级高。
-
max-age指定⼀个时间⻓度,在这个时间段内缓存是有效的,单位是s。 -
例如设置
Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 / 60)天, -
第⼀次访问这个资源的时候,服务器端也返回了
Expires字段,并且过期时间是⼀年后。
协商缓存
上面提到的强缓存都是由本地浏览器在确定是否使用缓存,当浏览器没有命中强缓存时就会向服务器发送请求,验证协商缓存是否命中,如果缓存命中则返回304状态码,否则返回新的资源数据。
协商缓存是由服务器来确定缓存资源是否可用。 主要涉及到两对属性字段,都是成对出现的,即第一次请求的响应头带上某个字, Last-Modified 或者 Etag,则后续请求则会带上对应的请求字段 If-Modified-Since或者 If-None-Match,若响应头没有 Last-Modified 或者 Etag 字段,则请求头也不会有对应的字段
Last-modified表示本地文件最后修改时间,精确到秒,由服务器返回if-modified-since是浏览器在请求数据时返回的,值是上次浏览器返回的Last-modifiedetag表示文件的唯一标识,格式如etag: "5f2976a4-17d",当客户端第一次向服务器第一次请求时,服务器会在响应头上带上文件唯一标识etag,等到第二次客户端向服务器请求同样的资源时,客户端会在请求头上的if-none-match带上上一次请求的etag值,服务器对etag进行比较,如果时间一致,服务器返回304状态码,客户端直接在缓存中读取数据,如果不一致,服务器返回200的状态码,并更新文件
协商缓存概念图
Etag生成靠以下几种因子
- 文件的i-node编号,是Linux/Unix用来识别文件的编号
- 文件最后修改时间
- 文件大小
- ......
为什么需要ETag
你可能会觉得使⽤Last-Modified已经⾜以让浏览器知道本地的缓存副本是否⾜够新,为什么还需要Etag(实体标 识)呢?
Etag的出现主要是为了解决⼏个Last-Modified⽐较难解决的问题:
-
Last-Modified标注的最后修改只能精确到秒级 -
如果某些⽂件在1秒钟以内,被修改多次的话,它将不能准确标注⽂件的修改时间2. 有可能存在服务器没有准确获取⽂件修改时间,或者与代理服务器时间不一致等情形
-
Etag是服务器⾃动⽣成或者由开发者⽣成的对应资源在服务器端的唯⼀标识符,能够更加 准确的控制缓存。 -
不会仅仅只根据最后的修改时间判断是否进⾏使⽤缓存
-
Last-Modified与ETag是可以⼀起使⽤的,服务器会优先验证ETag,⼀致的情况下,才会继续⽐对Last-Modified, 最后才决定是否返回304。
小结
-
强缓存: 检查过期时间, 判断缓存是否失效, 如果不失效, 直接⽤, 不发请求
⼤⼤的减少了 服务器的请求次数, 在过期时间内, 直接从客户端内存中读
-
协商缓存: 强缓存命中失效了, 超过过期时间了, 拿着标识(最后的修改时间, 唯⼀标识etag), 去问服务器, 是否真的过期了
如果验证通过, 服务器会直接响应 304, 且不会返回资源
不太会变的资源 => 图⽚, ⾮常的适合应⽤强缓存 (过期时间也可以设置的很⻓)
如果是⼀些很可能会变的资源, 也希望能缓存 => 过期时间设置短⼀些, ⼀旦过期, 协商缓存
实际⼯作两者相互配合
http常⻅的状态码有哪些? 以及他们分别表示什么?
1xx 信息响应
| Http状态码 | Http Status Code | Http Status Code |
|---|---|---|
| 100 | 100 Continue | 请继续请求 |
| 101 | 101 Switching Protocols | 请切换协议 |
| 102 | 102 Processing (en-US) (WebDAV) | 将继续执行请求 |
| 103 | 103 Early Hints | 提前预加载(css、js)文档 |
2xx 成功响应
| Http状态码 | Http Status Code | Http Status Code |
|---|---|---|
| 200 | 200 OK | 请求成功 |
| 201 | 201 Created | 请求已被接受,等待资源响应 |
| 202 | 202 Accepted | 请求已被接受,但尚未处理 |
| 203 | 203 Non-Authoritative Information | 请求已成功处理,结果来自第三方拷贝 |
| 204 | 204 No Content | 请求已成功处理,但无返回内容 |
| 205 | 205 Reset Content | 请求已成功处理,但需重置内容 |
| 206 | 206 Partial Content | 请求已成功处理,但需重置内容 |
| 207 | 207 Multi-Status (en-US) (WebDAV) | 请求已成功处理,返回了多个状态的XML消息 |
| 208 | 208 Already Reported (en-US) (WebDAV) | 响应已发送 |
| 226 | 226 IM Used (en-US) (HTTP Delta encoding) | 已完成响应 |
3xx 重定向消息
| Http状态码 | Http Status Code | Http Status Code |
|---|---|---|
| 300 | 300 Multiple Choice | 请求拥有多个可能的响应。用户代理或者用户应当从中选择一个。(没有标准化的方法来选择其中一个响应,但是建议使用指向可能性的 HTML 链接,以便用户可以选择。) |
| 301 | 301 Moved Permanently | 请求资源的 URL 已永久更改。在响应中给出了新的 URL。 |
| 302 | 302 Found | 此响应代码表示所请求资源的 URI 已 暂时 更改。未来可能会对 URI 进行进一步的改变。因此,客户机应该在将来的请求中使用这个相同的 URI。 |
| 303 | 303 See Other | 对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。 |
| 304 | 304 Not Modified | 自从上次请求后,请求的网页内容未修改过。服务器返回此响应时,不会返回网页内容。(协商缓存) |
| 305 | 305 Use Proxy 已弃用 | (已弃用)必须通过代理访问 |
| 306 | 306 unused已弃用 | (已废弃)请切换代理 |
| 307 | 307 Temporary Redirect | 临时重定向,同302 |
| 308 | 308 Permanent Redirect | 永久重定向,且禁止改变http方法 |
因为post请求, 是⾮幂等的, 从302中, 细化出了 303 和 307 简⽽⾔之:
- 301 302 307 都是重定向
- 304 协商缓存
4xx 客户端错误响应
| Http状态码 | Http Status Code | Http Status Code |
|---|---|---|
| 400 | 400 Bad Request | 请求报文存在语法错误(传参格式不正确) |
| 401 | 401 Unauthorized | 权限认证未通过(没有权限) |
| 402 | 402 Payment Required | 此响应代码保留供将来使用。创建此代码的最初目的是将其用于数字支付系统,但是此状态代码很少使用,并且不存在标准约定。 |
| 403 | 403 Forbidden | 表示对请求资源的访问被服务器拒绝 |
| 404 | 404 Not Found | 表示服务器上没有找到请求的资源 |
| 408 | 408 Request Timeout | 客户端请求超时 |
| 409 | 409 Conflict | 请求的资源可能引起冲突 |
5xx 服务端错误响应
| Http状态码 | Http Status Code | Http Status Code |
|---|---|---|
| 500 | 500 Internal Server Error | 服务器遇到了不知道如何处理的情况。 |
| 501 | 501 Not Implemented | 服务器不支持请求方法,因此无法处理。服务器需要支持的唯二方法(因此不能返回此代码)是 GET and HEAD. |
| 502 | 502 Bad Gateway | 此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。 |
| 503 | 503 Service Unavailable | 表明服务器暂时处于超负载或正在停机维护,无法处理请求 |
| 504 | 504 Gateway Timeout | 当服务器充当网关且无法及时获得响应时,会给出此错误响应。 |
| 505 | 505 HTTP Version Not Supported | 服务器不支持请求中使用的 HTTP 版本。 |