HTTP 实用指南|青训营笔记

71 阅读5分钟

 HTTP 实用指南| 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的第7天

 HTTP 实用指南

1. 什么是HTTP

Hyper Text Transfer Protocol 超文本传输协议
应用层协议,基于TCP协议
请求 响应
简单可扩展
无状态

image.png

HTTP协议分析

请求方式:Method

image.png

safe安全请求

使用GET、HEAD、OPTIONS请求是安全的,不会修改服务器的数据。

Idempotent幂等请求

同样的请求被执行一次和连续执行多次的效果是一样的,服务器的状态也是一样的。所有的safe请求方法都是幂等的。 幂等请求有:GET、HEAD、OPTIONS、PUT、DELETE。

什么是缓存

缓存就是一个资源副本。当我们向服务器请求资源后,会根据情况将资源 copy 一份副本存在本地,以方便下次读取。它与本地存储 localStorage 、cookie 等不同,本地存储更多是数据记录,存储量较小,为了本地操作方便。而缓存更多是为了减少资源请求,多用于存储文件,存储量相对较大。

缓存的作用

缓存最根本的作用就是减少没必要请求。有些资源,比如用户头像图片,很久才改变一次,但每次都要去请求这张一样的图片,通信一来一回增加了页面的显示时长,过多没必要请求也增加了服务器的压力。如果把这张图片直接缓存在本地,那每次就可以直接本地读取加载,不再发起请求。所以缓存的好处也就显而易见了,减少了时长从而优化用户体验,也减少了流量消耗,减轻了服务器的压力。

强缓存

直接从本地副本比对读取,不去请求服务器,返回的状态码是 200。主要包括 expires 和 cache-control。

expires

expires 是 HTTP1.0 中定义的缓存字段。当我们请求一个资源,服务器返回时,可以在 Response Headers 中增加 expires 字段表示资源的过期时间。

它是一个时间戳,当客户端再次请求该资源的时候,会把客户端时间与该时间戳进行对比,如果大于该时间戳则已过期,否则直接使用该缓存资源。

但是,有个大问题,发送请求时是使用的客户端时间去对比。一是客户端和服务端时间可能快慢不一致,另一方面是客户端的时间是可以自行修改的(比如浏览器是跟随系统时间的,修改系统时间会影响到),所以不一定满足预期。

cache-control

正由于上面说的可能存在的问题,HTTP1.1 新增了 cache-control 字段来解决该问题,所以当 cache-control 和 expires 都存在时,cache-control 优先级更高。该字段是一个时间长度,单位秒,表示该资源过了多少秒后失效。当客户端请求资源的时候,发现该资源还在有效时间内则使用该缓存,它不依赖客户端时间。cache-control 主要有 max-age 和 s-maxage、public 和 private、no-cache 和 no-store 等值。

max-age和s-maxage

两者是 cache-control 的主要字段,它们是一个数字,表示资源过了多少秒之后变为无效。在浏览器中,max-age 和 s-maxage 都起作用,而且 s-maxage 的优先级高于 max-age。在代理服务器中,只有 s-maxage 起作用。 可以通过设置 max-age 为 0 表示立马过期来向服务器请求资源。

public和private

public 表示该资源可以被所有客户端和代理服务器缓存,而 private 表示该资源仅能客户端缓存。默认值是 private,当设置了 s-maxage 的时候表示允许代理服务器缓存,相当于 public。

no-cache和no-store

no-cache 表示的是不直接询问浏览器缓存情况,而是去向服务器验证当前资源是否更新(即协商缓存)。no-store 则更狠,完全不使用缓存策略,不缓存请求或响应的任何内容,直接向服务器请求最新。由于两者都不考虑缓存情况而是直接与服务器交互,所以当 no-cache 和 no-store 存在时会直接忽略 max-age 等。

协商缓存

会去服务器比对,若没改变才直接读取本地缓存,返回的状态码是 304。

如果设置了 no-cache 和 no-store 则本地缓存会被忽略,会去请求服务器验证资源是否更新,如果没更新才继续使用本地缓存,此时返回的是 304,这就是协商缓存。协商缓存主要包括 last-modified 和 etag。

使用last-modified 有以下两个缺点:

只要编辑了,不管内容是否真的有改变,都会以这最后修改的时间作为判断依据,当成新资源返回,从而导致了没必要的请求响应,而这违背了缓存本来的作用即避免没必要的请求。 时间的精确度只能到秒,如果在一秒内的修改是检测不到更新的,仍会告知浏览器使用旧的缓存。

etag

etag 会基于资源的内容编码生成一串唯一的标识字符串,只要内容不同,就会生成不同的 etag。启用 etag 之后,请求资源后的响应返回会增加一个 etag 字段,如下:

etag: "FllOiaIvA1f-ftHGziLgMIMVkVw_" 1 当再次请求该资源时,请求头会带有 if-none-match 字段,值是之前返回的 etag 值,如:if-none-match:"FllOiaIvA1f-ftHGziLgMIMVkVw_"。服务端会根据该资源当前的内容生成对应的标识字符串和该字段进行对比,若一致则代表未改变可直接使用本地缓存并返回 304;若不一致则返回新的资源(状态码200)并修改返回的 etag 字段为新的值。

etag的缺点就是每次生成标识字符串会增加服务器的开销。