聊聊http缓存

代码探幽鹤
• 阅读 2224

前言

  http缓存是WEB开发中比较重要的知识,缓存的作用是减少没必要的网络请求,提升页面加载速度,优化用户体验,减轻了服务器的压力,节省了带宽。我们必须掌握缓存的基本知识,才能利用好缓存,也能帮助我们解决开发中因客户端缓存导致资源不更新问题。

http缓存分为强制缓存和协议缓存

强制缓存:

  在资源文件没有过期前不会发送请求到服务器,直接使用本地缓存(磁盘、内存),强缓存通过Expires、Cache-Control 和 Pragma控制

1. Expires

  它是http1.0定义的字段,属性值是一个时间戳,当客户端再次请求该资源的时候,会把客户端时间与该时间戳进行对比,如果大于该时间戳则已过期,否则直接使用该缓存资源。
  Expires的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代,如果Cache-Control与expires同时存在,Cache-Control生效。

2. Cache-Control

这是http1.1新增的字段,常用的属性值如有:

  • max-age:单位是秒,缓存时间计算的方式是距离发起的时间的秒数,超过间隔的秒数缓存失效
  • no-cache:不使用强缓存,需要与服务器验证缓存是否新鲜
  • no-store:禁止使用缓存(包括协商缓存),每次都向服务器请求最新的资源
  • private:专用于个人的缓存,中间代理、CDN 等不能缓存此响应
  • public:响应可以被中间代理、CDN 等缓存
  • must-revalidate:在缓存过期前可以使用,过期后必须向服务器验证

3. Pragma

  也是http1.0定义的字段,只有一个属性值:no-cache,作用和Cache-Control中的no-cache一样,优先级高于 cache-control 和 expires;三者同时出现时,优先级 pragma -> cache-control -> expires

协商缓存:

  当强缓存失效或者强缓存设置no-cache等不使用强缓存情况下,如果前一次请求的response header中有Last-Modified,ETag,浏览器就会在request header中携带If-Modified-Since(上一次请求返回的Last-Modified值),If-None-Match(上一次请求返回的ETag值),服务器根据这两个参数和服务资源对比看是否过期,如果没有过期服务器返回304,浏览器使用本地缓存,否则返回200,返回服务最新的资源文件。

1. Last-Modified / If-Modified-Since

  • 当浏览器第一次请求一个url时,服务器端的返回状态码为200,同时HTTP响应头会有一个Last-Modified标记着文件在服务器端最后被修改的时间。
  • 浏览器第二次请求上次请求过的url时,浏览器会在HTTP请求头添加一个If-Modified-Since的标记,用来询问服务器该时间之后文件是否被修改过。
  • 如果服务器端的资源没有变化,则自动返回304状态,使用浏览器缓存,从而保证了浏览器不会重复从服务器端获取资源,也保证了服务器有变化是,客户端能够及时得到最新的资源。

2. ETag / If-None-Match

  • 当浏览器第一次请求一个url时,服务器端的返回状态码为200,同时HTTP响应头会有一个ETag,存放着服务器端生成的一个序列值。
  • 浏览器第二次请求上次请求过的url时,浏览器会在HTTP请求头添加一个If-None-Match的标记,用来询问服务器该文件有没有被修改。

有Last-Modified为什么还要ETag? ETag 主要为了解决 Last-Modified 无法解决的一些问题:

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET。
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
  • 某些服务器不能精确的得到文件的最后修改时间

我们通过图示看下浏览器缓存流程:

1. 浏览器第一次请求

聊聊http缓存

2. 浏览器第二次请求

聊聊http缓存

问题:

  • 问题一

A:如果response header中没有Cache-Control等强缓存字段呢,浏览器怎么处理?
Q:如果没有强缓存字段浏览器会用 (当前时间-最后修改时间)*10% 计算出来的时间当成max-age,这个缓存时间不一定的,经常开发没问题但测试或上生产会出问题,当然这个计算公式不是所有浏览器都是这样的,因为没有明确指定缓存策略,浏览器厂商就按自己认为合适的策略进行缓存。

  • 问题二

A:如何解决入口页面缓存,比如微信缓存?
Q:入口页面应该加上Cache-Control:no-cache或者设置max-age一个比较短的时间,需要在http响应头中设置,不是html页面的meta标签,meta标签有的浏览器认有的浏览器不认。

  • 问题三

A:如何解决IE8,IE9 ajax get请求缓存问题?
Q:后台接口统一返回头中统一加上Cache-Control:no-cache,百度网盘,网易邮箱等后台接口返回的header都是no-cache或max-age=0的,当然前端框架加随机数等方式也能解决,比如jquery ajax的cache:false。

总结&实践

  1. 对于前端,入口页面使用no-cache或max-age设置为较短时间,js,css本身设置max-age为较长时间,引用js,css通过打包工具加hash版本号方式,这样浏览器只会请求修改的文件,没有修改的直接用缓存。
  2. 对于后端接口,最好都加上no-cache,这样在老旧的浏览器上不会出问题。
  3. 明确指定强制缓存字段和协商缓存字段,对不同资源制定合适的缓存策略,而不是依赖浏览器的默认规则有助于解决很多缓存兼容问题。
点赞
收藏
评论区
推荐文章
3A网络 3A网络
2年前
缓存三大问题及解决方案
1.缓存来由随着互联网系统发展的逐步完善,提高系统的qps,目前的绝大部分系统都增加了缓存机制从而避免请求过多的直接与数据库操作从而造成系统瓶颈,极大的提升了用户体验和系统稳定性。2.缓存问题虽然使用缓存给系统带来了一定的质的提升,但同时也带来了一些需要注意的问题。2.1缓存穿透缓存穿透是指查询一个一定不存在的数据,因为缓存中也无该数据的信息,则会
浅谈 HTTP 缓存与 CDN 缓存的那点事
HTTP缓存与CDN缓存一直是提升web性能的两大利器,合理的缓存配置可以降低带宽成本、减轻服务器压力、提升用户的体验。而不合理的缓存配置会导致资源界面无法及时更新,从而引发一系列的衍生问题。本文将分别将从HTTP缓存与cdn缓存的规则、流程、配置
东方客主 东方客主
4年前
一文读懂http缓存(超详细)
前端缓存前端缓存可分为两大类:http缓存和浏览器缓存。我们今天重点讲的是http缓存,所以关于浏览器缓存大家自行去查阅。下面这张图是前端缓存的一个大致知识点:(https://imghelloworld.osscnbeijing.aliyuncs.com/3e161cfcbe560b9608064ec91077346
东方客主 东方客主
4年前
彻底弄懂HTTP缓存机制及原理
Http缓存机制作为web性能优化的重要手段,对于从事Web开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能。但是对于很多前端同学来说,仅仅只是知道浏览器会对请求的静态文件进行缓存,但是为什么被缓存,缓存是怎样生效的,却并不是很清楚。在此,我会尝试用简单明了的文字,像大家系统的介绍HTTP
Stella981 Stella981
3年前
Http 缓存策略
1)浏览器缓存策略浏览器每次发起请求时,先在本地缓存中查找结果以及缓存标识,根据缓存标识来判断是否使用本地缓存。如果缓存有效,则使用本地缓存;否则,则向服务器发起请求并携带缓存标识。根据是否需向服务器发起HTTP请求,将缓存过程划分为两个部分:强制缓存和协商缓存,强缓优先于协商缓存。强缓存,服务器通知浏览器一个缓存时间,在
Stella981 Stella981
3年前
Django框架深入了解_05 (Django中的缓存、Django解决跨域流程(非简单请求,简单请求)、自动生成接口文档)
一、Django中的缓存:前戏:    在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力.缓存是将一些常用
Wesley13 Wesley13
3年前
JS浏览器不缓存页面的几种方法
我们需不需要浏览器缓存?浏览器缓存,有时我们需要,有时我们不需要,就比如股票类型的网页就需要实时刷新数据,不能让页面从缓存里读取数据,如果对于一些不需要实时更新数据的网站来说,浏览器缓存可以提高加载速度,带来更好的用户体验,到底需不需要浏览器缓存,让我们自己操作!meta方法//不缓存<METAHTTPEQU
小白学大数据 小白学大数据
12个月前
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
缓存策略的重要性缓存策略在网络爬虫中扮演着至关重要的角色。合理利用缓存可以显著减少对目标网站的请求次数,降低服务器负担,同时提高数据抓取的效率。Scrapy提供了多种缓存机制,包括HTTP缓存和Scrapy内置的缓存系统。HTTP缓存HTTP缓存是基于HT
京东云开发者 京东云开发者
6个月前
真实案例解析缓存大热key的致命陷阱
作者:京东零售曹志飞引言在现代软件架构中,缓存是提高系统性能和响应速度的重要手段。然而,如果不正确地使用缓存,可能会导致严重的线上事故,尤其是缓存的大热key问题更是老生常谈。本文将探讨一个常见但容易被忽视的问题:缓存大热key和缓存击穿问题。我们将从一个
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(