文章目录
本地缓存中localStorage、sessionStorage、cookie的内容请见 链接
一、HTTP缓存
http缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
http缓存都是从第二次请求开始的。第一次请求资源时,服务器返回资源,并在respone header头中回传资源的缓存参数;第二次请求时,浏览器判断这些请求参数,命中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否命中协商缓存,命中则返回304,否则服务器会返回新的资源。
常见的http缓存只能缓存get请求响应的资源
1.1 强缓存
浏览器在第一次向服务器发送请求时,若服务器觉得该资源需要缓存,这是服务器就会在响应头response-header 里面添加一个cache-control,如设置max-age,这样浏览器就会在本地缓存中存下相应的文件。
在浏览器下一次请求同样的文件时,浏览器就会去检查 max-age 有没有过期,如果没有过期就直接从本地缓存里获取资源,不会向服务器去发请求,这样就会提升页面的加载速度。如果max-age过期了,那么浏览器又会向第一次一样去向浏览器发送请求。
这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存,所以Ctrl + F5之后就好了。
from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk。在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。
1. 强制缓存的header属性(Pragma/Cache-Control/Expires)
浏览器在请求某一资源时,会先获取该资源缓存的 header 信息,判断是否命中强缓存(cache-control 和 expires 信息),若命中直接从缓存中获取资源信息,包括缓存 header 信息,本次请求根本就不会与服务器进行通信。
- expires:这是 http1.0 时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源。
- cache-control:这是 http1.1 时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对值;资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行;cache-control 的设置与否在于服务器,都是在服务器端设置的,前端不需要做任何事情
cache-control 的常用选项
选项 | 解释 |
---|---|
max-age=100 | 缓存100秒后过期,资源缓存在本地 |
no-cache | 不使用本地缓存。使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。 |
no-store | 所有内容都不会被缓存,既不使用强制缓存也不适用协商缓存,每次用户请求该资源,都会向服务器发送一个请求,服务器再返回资源 |
public | 可以被所有的用户缓存,包括客户端和代理服务器 |
private | 只能被客户端缓存,不允许CDN等中继缓存服务器对其缓存 |
s-maxage | 覆盖 max-age,作用与max-age一样,但只用于代理服务器中缓存 |
注意:如果 cache-control 与 expires 同时存在的话,cache-control 的优先级高于 expires
1.2 协商缓存(对比缓存)
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
浏览器第一次请求的时候,若服务器使用了协商缓存的策略,则它会返回资源和资源标识,并且浏览器将返回的资源存储到本地缓存。
当浏览器再次请求该资源时,浏览器向服务器发送请求和资源标识,服务器这时就会去判断当前请求的资源浏览器本次缓存的版本跟服务器里面资源最新的版本是否一致:
- 如果版本一致,服务器返回 304 状态码,重定向让浏览器直接在本地缓存里拿资源;
- 如果版本不一致,服务器返回 200 状态码、最新的资源以及新的资源标识,浏览器更新本地缓存。
资源标识:
-
Last-Modified/If-Modified-Since
:指资源上一次修改的时间 -
Etag/If-None-Match
:资源对应的唯一字符串服务器会为每个资源生成一个唯一的标识字符串,只要文件内容不同,它们对应的 Etag 就是不同的;If-Modified-Since能检查到的精度是s级的,某些服务器不能精确的得到文件的最后修改时间,我们编辑了文件,但文件的内容没有改变。因为服务器是根据文件的最后修改时间来判断的,导致重新请求所以才出现了Etag,Etag对服务器也有性能损耗 Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
(一)Last-Modified
在浏览器第一次请求时,服务器返回资源和资源标识符Last-Modified(在响应头中)
在后续请求中,浏览器就会在请求头带上资源标识 If-Modified-Since 发起请求,If-Modified-Since的值就是上一次请求时返回的 Last-Modified 的值,这时在服务器就会去对比If-Modified-Since 和 Last-Modified 的值判断是否是最新资源。
(二)ETag
其流程跟Last-Modified 类似。
(三)对比 Last-Modified 和 ETag
优先使用 ETag,原因如下:
- Last-Modified 的值只能精确到秒级
- 文件如果每隔一段时间就重复生成,但内容相同,或者是内容修改了很多次但最终与上一次文件的内容一致,但这也改变了 Last-Modified 的值。使用Last-Modified 的话每次返回资源文件,即使内容一致。但ETag 可以判断出文件内容相同,就会使用缓存,而不用向服务器发送请求了
1.3 HTTP缓存的整个流程
二、CDN(内容分发网络)
我们的电脑访问一个网站的时候,这个网站的服务器可能距离我们十万八千里,越远的距离意味着中间要经过更多的节点,节点之间还可能会发生阻塞和丢包的情况,结果导致我们很久都打不开网页,我们就会选择关闭网页。服务器不知道哪里的用户会来访问,世界上任何角落的用户来访问都得做好准备。按卖东西的思维来说,就是多开分店,服务器也是这个策略,备份多个服务器到世界各地,但这需要场地、网络和人员来维护,因此在世界各地的服务器就形成了一个网络,就做内容分发网络。
关键词:加速加速加速!!!更快的分发用户想要的内容
CDN:内容分发网络(Content Delivery Network)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。其目的是通过在现有的 Internet 中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”(边缘服务器),使用户可以就近取得所需的内容,提高用户访问网站的响应速度。
2.1 分发的内容是什么
分发的内容可分为静态内容和动态内容
- 静态内容:长期固定的内容
- 动态内容:经常变化的内容
静态内容不是一直保存在CDN里,源服务器发送文件给 CDN 时可以利用 HTTP 头部的 cache-control,利用缓存机制,CDN 可以知道哪些资源可以保存,哪些不能等
2.2 CDN 分发的流程
静态内容
CDN 没有网站的源内容,因此源服务器就会把静态内容提前备份给CDN,也叫push,这样在世界各地用户需要访问网页的时候,就近的CDN服务器就会把静态内容提供给用户,不需要每次都去请求源服务器了。
如果源服务器没有把静态内容提前备份给CDN,那当用户访问网页时,CDN就得向源服务器索取相应的静态内容,也就是pull,源服务器还可以让CDN进行备份,CDN得到内容以后再提供给用户,因为有了备份,其他同时做出该请求的用户也可以立刻拿到内容。
动态内容
动态内容用CDN来进行分发就很困难了,因为动态内容实会根据每个用户来改变的或者根据每个时间段来变化的,源服务器就很难提前预测到每个用户的动态内容,然后提前push到CDN。如果等用户索取动态内容,CDN再向源服务器索取,这跟直接向服务器请求没有太大差别,CDN提供不了多少加速服务,就没有太大的必要。
但还是有CDN可以提供服务,比如现在要获取动态的时间,有些CDN会提供可以运行在CDN上的接口,让源服务器用这些CDN的接口,而不是源服务器自己的代码,这样用户就可以直接从CDN上获取时间。
CDN的布局相当于无形中给源服务器和用户之间增加了一道墙,用户不再直接访问服务器了,而是通过CDN进行沟通,这样就不用担心恶意的DDos攻击。
2.3 CDN 工作原理
CDN网络是在用户和服务器之间增加 Cache 层,主要是通过接管 DNS 实现,将用户的请求引导到 Cache 上获得源服务器的数据,从而降低网络的访问时间。
1. 传统的未加缓存服务的访问过程
如图可以看出,传统的网络访问的流程如下:
- 用户输入访问的域名
www.a.com
,操作系统向 LocalDns 查询域名的ip地址; - LocalDns检查缓存中是否有
www.a.com
的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向 ROOT DNS 查询域名的授权服务器。 - ROOT DNS将域名授权dns记录CNAME返回给 LocalDns;
- LocalDns得到域名的授权dns记录后,继续向域名授权dns(授权服务器)查询域名的ip地址;
- 域名授权dns (授权服务器)查询域名记录后,回应给 LocalDns;
- LocalDns 将得到的域名ip地址,回应给用户端;
- 用户得到域名ip地址后,访问站点服务器;
- 站点服务器应答请求,将内容返回给客户端。
2. 使用CDN缓存后的网站的访问过程
如上图,是使用CDN缓存后的网络访问流程:
- 用户输入访问的域名
www.a.com
,操作系统向 LocalDns 查询域名的ip地址; - LocalDns检查缓存中是否有
www.a.com
的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向 ROOT DNS 查询域名的授权服务器。 - ROOT DNS将域名授权dns记录回应给 LocalDns;
- LocalDns得到域名的授权dns记录后,继续向域名授权dns查询域名的ip地址;
- 域名授权dns 查询域名记录后(一般是CNAME),回应给 LocalDns;
- LocalDns 得到域名记录后,向智能调度DNS系统查询域名的ip地址;
- 智能调度DNS 根据一定的算法和策略(比如静态拓扑,容量等),将最适合的CDN节点ip地址回应给 LocalDns;
- LocalDns 将得到的域名ip地址,回应给用户端;
- 用户得到域名ip地址后,访问站点服务器。
从这个例子可以了解到:
(1)CDN 的加速资源是跟域名绑定的。
(2)通过域名访问资源,首先是通过 DNS 查找离用户最近的CDN节点(边缘服务器)的IP
(3)通过 IP 访问实际资源时,如果 CDN 上并没有缓存资源,则会到源站请求资源,并缓存到 CDN 节点上,这样,用户下一次访问时,该 CDN 节点就会有对应资源的缓存了。
2.4 CDN 的安全性和可靠性
CDN的出现又导致了攻击者可能攻击 CDN ,CDN宕机了怎么办。
多个CDN服务器布局在各个地方,然后监控CDN 服务器的负载状况,若是某个服务器超载了或宕机了,就会把用户的请求转移到没有超载的CDN服务器这边,以此来平均分配网络流量,也就是负载均衡。
CDN转移这些流量的方法和DNS根服务器的做法有着异曲同工之妙,用的是任播这种技术,使用了任播这种技术后,服务器对外拥有同样的IP地址,如果这个IP地址收到了用户的请求之后,请求就会由距离用户最近的服务器来响应
CDN还会采用TSL/SSL证书来给网站进行保护
2.5 应用
CDN应用广泛,支持多种行业、多种场景内容加速,例如:图片小文件、大文件下载、视音频点播、直播流媒体、全站加速、安全加速。
- 使用第三方的CDN服务:前端开源项目的CDN加速服务,第三方CDN服务
- CDN 往往被用来存放静态资源:所谓“静态资源”,就是像 JS、CSS、图片等不需要业务服务器进行计算即得的资源。而“动态资源”,顾名思义是需要后端实时动态生成的资源,较为常见的就是 JSP、ASP 或者依赖服务端渲染得到的 HTML 页面。而且我们可以写脚本结合Webpack将对应的静态资源直接放到CDN,完成一键自动部署整个项目。
- 把静态资源和业务服务器置于不同的域名下:静态服务器最好启用一个全新域名,避免每次请求都携带Cookie。
- 直播传送:直播本质上是使用流媒体进行传送,那么CDN也是支持流媒体传送的,所以直播完全可以使用CDN来提高访问速度。CDN在处理流媒体的时候与处理普通静态文件有所不同,普通文件如果在边缘节点没有找到的话,就会去上一层接着寻找,但是流媒体本身数据量就非常大,如果使用回源的方式,必然会带来性能问题,所以流媒体一般采用的都是主动推送的方式来进行。