缓存可以大幅提升用户的访问速度因此来提升用户体验。
缓存又分为浏览器端的缓存和服务器端的缓存。下面来比较一下浏览器缓存和Nginx缓存的优劣。
项目 | 优点 | 缺点 |
---|---|---|
浏览器缓存 | 1.使用本地缓存时,没有网络消耗,速度最快 2.对于失效缓存,304相应可以做到流量消耗最小化 | 仅仅提升一个用户的本地体验 |
Nginx缓存 | 1.提升所有用户的体验 2.降低上游服务的负载 3.通过304相应减少与上游服务间的流量消耗 | 用户仍然保持网络消耗 |
所以当然是要同时使用这两种缓存。
Etag头部
ETagHTTP响应头是资源的特定版本的标志服。这可以让缓存更高效,并节省带宽,因为如果内容没有改变,Web服务器不需要发送完整的响应。而如果内容发生了变化,使用ETag有助于防止资源的同时更新相互覆盖(空中碰撞)。
如果给定URL中的资源更改,则会生成新的Etag值。因此Etag类似于指纹,也可能被某些服务器用于跟踪。比较etags能快速确认此资源是否变化,但也可能被跟踪服务器永久留存。
在Nginx中的配置:
语法 | etag on/off; |
---|---|
默认 | etag on |
上下文 | http,server,location |
Etag实际上是根据上一次的修改时间和内容长度来生成的。
IF-None-Match
场景:浏览器端的缓存已经过期了,而浏览器还想赌一赌服务器端是否有更新的版本,因此浏览器将所缓存页面的etag发送给服务器,如果服务器发现这个etag就是最近的,那就直接返回304即可。
动作为:浏览器在If-None-Match头部中,填入etag,发送给服务器。
If-None-Match是一个条件式请求首部。对于get和head请求方法来说,当且仅当服务器上没有任何资源的Etag属性值和这个首部中列出的相匹配的时候,服务端才会返回所请求的资源,响应码为200
IF-Modified-Since
浏览器将自己保存缓存的时间发送给服务器,询问服务器在此时间之后是否对此资源做过修改。如果没改动过,服务器则返回一个不带消息主体的304响应,在Last-Modified首部中带上上次修改时间。
当与If-None-Match一同出现时,If-Modified-Since会被忽略掉,除非服务器不支持If-None-Match。
下面根据上图来解读一下浏览器对于缓存的处理流程:
首先,你在地址栏中输入某url,按下回车,此时浏览器会发出请求吧,在请求之前,浏览器会检查自己是否有该网站的缓存,如果存在缓存的话,检查该缓存是否过期(Expires),如果没过期的话,直接在缓存中读取然后呈现出来即可。
如果缓存过期了,首先检查是否有Etag,有的话,就向服务器发送If-None-Match,由服务器决断是否需要更新缓存。
如果没有Etag的话,那就看是否有Last-Modified,有的话,就像服务器发送If-Modified-Since,由服务器决断是否需要更新缓存。
如果浏览器这边啥都没有…那就直接请求吧。