HTTP缓存总结
在具体了解 HTTP 缓存之前先来明确几个术语:
1、缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
2、过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
3、验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
4、失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。
HTML meta标签定义缓存
例如
<META HTTP-EQUIV="Pragma" CONTENT="no-store">
含义是让浏览器不缓存当前页面。但是代理服务器不解析 HTML 内容,一般应用广泛的是用 HTTP 头信息控制缓存。
(在meta信息中定义缓存的方式对于代理服务器不起作用,所以,我们要用Http头设置缓存。)
HTTP头信息控制缓存
大致分为两种:强缓存和协商缓存。
强缓存命中缓存时,不需要和服务器端发生交互;而协商缓存不管是否命中都要和服务器端发生交互。
强制缓存的优先级高于协商缓存。
强缓存和协商缓存的匹配流程如下图:
下面具体解释这两种缓存:
一、强缓存
可以理解为无须验证的缓存策略。对强缓存来说,响应头中有两个字段 Expires/Cache-Control 来表明规则。
Expires
Expires
指缓存过期的时间,超过了这个时间点就代表资源过期。有一个问题是由于使用具体时间,如果时间表示出错或者没有转换到正确的时区都可能造成缓存生命周期出错。并且
Expires 是 HTTP/1.0 的标准,现在更倾向于用 HTTP/1.1 中定义的 Cache-Control。两个同时存在时也是
Cache-Control 的优先级更高。
Cache-Control
Cache-Control 可以由多个字段组合而成,主要有以下几个取值:
1.
max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置
Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 *
60)天,第一次访问这个资源的时候,服务器端也返回了 Expires 字段,并且过期时间是一年后。

在没有禁用缓存并且没有超过有效时间的情况下,再次访问这个资源就命中了缓存,不会向服务器请求资源而是直接从浏览器缓存中取。

2. s-maxage 同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。
3. public 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存(共享的)。
4. private 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存(非共享的),不能被代理服务器缓存。
5. no-cache 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。不是字面意思上的不缓存。
6. no-store 禁止缓存,每次请求都要向服务器重新获取数据。
二、协商缓存
缓存的资源到期了,并不意味着资源内容发生了改变,如果和服务器上的资源没有差异,实际上没有必要再次请求。
客户端和服务器端通过某种验证机制验证当前请求资源是否可以使用缓存。
浏览器第一次请求数据之后会将数据和响应头部的缓存标识存储起来。再次请求时会带上存储的头部字段,服务器端验证是否可用。
如果返回 304 Not Modified,代表资源没有发生改变可以使用缓存的数据,获取新的过期时间。
反之返回 200 就相当于重新请求了一遍资源并替换旧资源。
Last-modified/If-Modified-Since
Last-modified:
服务器端资源的最后修改时间,响应头部会带上这个标识。第一次请求之后,浏览器记录这个时间,再次请求时,请求头部带上
If-Modified-Since 即为之前记录下的时间。服务器端收到带 If-Modified-Since
的请求后会去和资源的最后修改时间对比。若修改过就返回最新资源,状态码 200,若没有修改过则返回 304。

注意:如果响应头中有 Last-modified 而没有 Expire 或 Cache-Control 时,浏览器会有自己的算法来推算出一个时间缓存该文件多久,不同浏览器得出的时间不一样,所以 Last-modified 要记得配合 Expires/Cache-Control 使用。
Etag/If-None-Match
由服务器端上生成的一段 hash 字符串,第一次请求时响应头带上 ETag: abcd,之后的请求中带上 If-None-Match: abcd,服务器检查 ETag,返回 304 或 200。

关于last-modified和Etag区别,已经有很多人总结过了:
某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新。
Last-modified 只能精确到秒。
一些资源的最后修改时间改变了,但是内容没改变,使用Last-modified看不出内容没有改变。
Etag的精度比Last-modified高,属于强验证,要求资源字节级别的一致,优先级高。如果服务器端有提供ETag的话,必须先对ETag进行Conditional Request。
注意:实际使用ETag/Last-modified要注意保持一致性,做负载均衡和反向代理的话可能会出现不一致的情况。计算ETag也是需要占用资源的,如果修改不是过于频繁,看自己的需求用 Cache-Control是否可以满足。
实际应用
回到实际应用上来,首先要明确哪些内容适合被缓存哪些不适合。
考虑缓存的内容:
css样式文件
js文件
logo、图标
html文件
可以下载的内容
一些不应该被缓存的内容:
业务敏感的 GET 请求
可缓存的内容又分为几种不同的情况:
1、不经常改变的文件。
给 max-age 设置一个较大的值,一般设置 max-age=31536000
比如引入的一些第三方文件、打包出来的带有 hash 后缀 css、js 文件。一般来说文件内容改变了,会更新版本号、hash 值,相当于请求另一个文件。
标准中规定 max-age 的值最大不超过一年,所以设成 max-age=31536000。至于过期内容,缓存区会将一段时间没有使用的文件删除掉。
2、可能经常需要变动的文件。
Cache-Control: no-cache/max-age=0
比如入口 index.html 文件、文件内容改变但名称不变的资源。选择 ETag 或 Last-Modified 来做验证,在使用缓存资源之前一定会去服务器端做验证,命中缓存时会比第一种情况慢一点点,毕竟还要发请求进行通信。
注意: 这里只描述了最基本的思路,实际使用 HTTP 缓存需要后端配合配置,具体情况具体对待,而且各方的实现并不一定完全按照标准来的,踩踩坑更健康。
相关资料:
也许这样理解HTTPS更容易 https://mp.weixin.qq.com/s/E5PINP-HmHuUWsszVOG79g
HTTP缓存机制一二三 http://mp.weixin.qq.com/s/EqrFhUTIcqO804NHiqWFsg
浅谈 Web 缓存 http://mp.weixin.qq.com/s/MLmxeIlX6Zy7Uy98SEWbFw
前端跨域知识总结 http://mp.weixin.qq.com/s/NOmsbKZsryTUONQj2gBFIA
理解伪元素:before和:after http://mp.weixin.qq.com/s/YUxSKRW98Q2uvqpF6zZ3Vg
前端跨域请求原理及实践 https://mp.weixin.qq.com/s/CZgz0ya_RXhzDkEfv2_9iw
HTTP缓存总结的更多相关文章
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- ASP.NET Core 中间件之压缩、缓存
前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是 Microsoft.AspNetCore.Respons ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- [Java 缓存] Java Cache之 DCache的简单应用.
前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...
- [原创]mybatis中整合ehcache缓存框架的使用
mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- 深究标准IO的缓存
前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...
- 缓存工厂之Redis缓存
这几天没有按照计划分享技术博文,主要是去医院了,这里一想到在医院经历的种种,我真的有话要说:医院里的医务人员曾经被吹捧为美丽+和蔼+可亲的天使,在经受5天左右相互接触后不得不让感慨:遇见的有些人员在挂 ...
- .net 分布式架构之分布式缓存中间件
开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件 方便实现缓存的分布式,集群, ...
随机推荐
- Qt DLL总结【一】-链接库预备知识
1.链接库概念 静态链接库和动态链接库介绍 我们可以创建一种文件里面包含了很多函数和变量的目标代码,链接的时候只要把这个文件指示给链接程序就自动地从文件中查找符合要求的函数和变量进行链接,整个查找过程 ...
- VIM | vim操作大全
1. 关于Vim vim是Linux下第二强大的编辑器. 虽然emacs是公认的世界第一,我认为使用emacs并没有使用vi进行编辑来得高效. 如果是初学vi,运行一下vimtutor是个聪明的决定. ...
- buildscript和allprojects的作用和区别是什么?
在Android Studio的Project的build.gradle中, // Top-level build file where you can add configuration optio ...
- docker 搭建私有云盘 Seafile
缘起 现如今各种云存储服务其实挺多的,国外有经典的DropBox.Google Drive.微软的OneDrive等,国内也有可以免费使用的各种云. 那么为什么想要搭建私有云存储呢?主要是本着“自己的 ...
- vue-cli2.x版本安装vue-cli建项目
全局安装vue-cli 命令行输入: vue-cli版本在3以下 npm install --global vue-cli 安装vue-cli后,可以查看一下是否安装成功vue --version, ...
- mysql千万级数据表结构修改
当需要对表进行ddl操作如加索引.增删列时,数据量小时直接在线修改表结构影响不大当表达到百万.千万数据就不能直接在线修改表结构 下面是具体的过程:1.备份数据select * from ih_orde ...
- C2B电商三种主要模式的分析_数据分析师
C2B电商三种主要模式的分析_数据分析师 在过去的一年中电商领域血雨腥风,尤其是天猫.京东.苏宁.当当.易讯等B2C电商打得不亦乐乎.而随着B2C领域竞争进入白热化阶段,C2B模式也在天猫" ...
- 星际争霸,FF反作弊对战平台
星际一 [FF]反作弊对战平台让作弊行为无所遁形,只为星际玩家服务的反作弊对战平台目前能检查星际霸主以及其他星际争霸ZUOBI软件支持星际113版本 支持XP WIN7 WIN8 MAC 游戏外挂带来 ...
- Golang gRPC微服务02: helloworld
安装protobuf 在windows下,直接下载release版本https://github.com/protocolbuffers/protobuf/releases/tag/v3.9.0然后把 ...
- HTTP 状态代码的完整列表
1xx(临时响应) 用于表示临时响应并需要请求者执行操作才能继续的状态代码. 代码 说明 100(继续) 请求者应当继续提出请求.服务器返回此代码则意味着,服务器已收到了请求的第一部分,现正在等待接收 ...