前端静态资源的缓存和更新问题解析

2020年05月29日 阅读数:6
这篇文章主要向大家介绍前端静态资源的缓存和更新问题解析,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

浏览器缓存主要有两类 
缓存协商:Last-midified ,Etag 
完全缓存:cache-control,Expires php

  缓存协商的意思是须要去服务器端询问页面有没有修改过,没有修改过则返回304直接使用缓存内容,不然返回新内容 
协商步骤: css

一、服务器发送带Last-midified:GMTtime 头的http responsehtml

二、浏览器下次请求时带上if-modified-since:GMTtime http 请求头html5

三、服务端用本地Last-midified时间与if-modified-since比较,计算浏览器数据是否过时并发送响应node

Etag的工做原理与Last-midified相似,不一样点在于Etag的值是用户可自定义的 web

  完全缓存的意思是在缓存失效以前再也不须要跟服务器交互 apache

经常使用的是Expires,Expires的值是一个绝对时间,由服务器产生 这儿存在一个问题,就是服务器的时间可能给客户端的时间不一致致使缓存时间的误差 api

要解决这个问题就要使用cache-control,它保存的是一个相对浏览器的时间 浏览器

若是同时存在cache-control和Expires怎么办呢? 浏览器老是优先使用cache-control,若是没有cache-control才考虑Expires 缓存

expire:
若是apache开启了expire模块, 当浏览器发送该资源请求的时候, apache返回资源的同时,会返回一个名为expire的http头,expire头的内容是一个时间值, 这一个值就是资源在本地的过时时间, 这个值会存在本地.
也就是说,在本地缓存阶段,在本地找到了一个对应的资源值,并且当前时间还没超过资源的过时时间, 那么就直接使用这一个资源,不会发送http请求.

cache-control:
cache-control是http协议中经常使用的头部之一,顾名思义, 他是负责控制页面的缓存机制,若是该头部指示缓存, 缓存的内容也会存在本地, 操做流程和expire类似,但也有不一样的地方, cache-control有更多的选项, 并且也有更多的处理方式.

if-modified-since 和 last-modified:
当apache接收到一个资源请求(假设是用户是第一次访问,没有任何缓存), 服务器返回资源的同时,还会发送一个last-modified的http响应头, last-modified响应头的内容值是该资源在服务器上最后修改的时间.浏览器接受到这个http头后,会
把其内容值和资源同时保存起来.
当用户第二发送资源请求(假设这里expire没有生效或者已通过期), 浏览器在本地找到了一个相同的资源,可是不能肯定该资源是否和服务器上的同样(有可能在两次访问期间,服务器上的资源已经被修改过),此时浏览器发送请求的时候,请求头内会
附带一个if-modified-since的请求头, 这个头部的内容就是上一次last-modified返回的值, 服务器把这个头的值和请求资源的最后修改时间对比,若是两个值相同,则认为资源没有修改,将会返回304,让浏览器使用本地资源.不然服务器将返回资源,并且
返回200状态

if-none-match 和 etag:
其实这两个头部和if-modified-since, last-modified的工做原理是同样的, if-none-match做为请求头, etag做为响应头.既然工做原理同样, 为何etag这对头部会出现呢?
缘由在于, last-modified请求头的内容是以文件最后修改的时间做为对比的,可是unix系统里面, 文件修改的时间只保存到了秒. 若是某些应用内存在1秒内对文件作了屡次修改,这样last-modified是不能完成比较功能的.因此要引入一个新的机制(缘由可能不止这一个);
etag的值通常由3个数值组成,资源的inode值, 最后修改时间, 资源大小,以16进制组成一个字符串, 例如:1a-182b-10f; 但这个格式不是固定的, 只要保证该值的惟一性,但不限格式.

静态资源的更新:张云龙老师的blog写的很好移步这里

 

html5离线存储

步骤:

一、配置apache让apache支持manifest文件

二、建立manifest文件test.manifest

1 CACHE MANIFEST  # wanz app v1     
2 # 指明缓存入口(指明须要缓存的文件)  
3 CACHE:  index.html  style.css  images/logo.png  scripts/main.js     # 如下资源必须在线访问  
4 NETWORK:  login.php     
5 # 若是index.php没法访问则用404.html代替  
6 FALLBACK:  /index.php /404.html

三、关联manifest文件到html文档

 1 <html manifest="test.manifest"> ... </html> 

注意:#是用来注释一行的,但它还有一个小做用,web应用的缓存只有在manifest文件被修改的状况下才会被更新,因此若是你只是修改了被缓存的文件,那么用户本地的缓存仍是不会被更新的,可是你能够经过修改manifest文件来告诉浏览器须要更新缓存了。利用这点,你能够像上面的例子中那样,写一句这样的注释一个文件版本:

# wanz app v1

优势:你能够很明确的了解离线web应用的版本
   经过简单的修改这个版本号就能够轻易的通知浏览器更新
   你能够配合JavaScript程序来完成缓存更新

CACHE:
这个是manifest文件的默认入口,在此入口以后罗列的文件 (或直接写在CACHE MANIFEST后的文件)在它们下载到本地后会被缓存起来
NETWORK:
可选的,在此节后面所罗列的文件是须要访问网络的,即便用户离线访问了也会直接跳过缓存而访问服务器
FALLBACK:
可选的,用来指定资源没法访问时的回调页面。每一行包括两个URI,第一个是资源文件URI,第二个是回调页面URI。

html5缓存的更新问题:

方法有三种:

一、用户清除了离线存储的数据,这个不必定就是清理浏览器历史记录就能够作到的,由于不一样浏览器管理离线存储的方式不一样。好比Firefox的离线存储数据要到“选项”=>“高级”=>“网络”=>“脱机存储”里才能够清除。
二、manifest文件被修改,上面说的,你修改了manifest文件里所罗列的文件也不会更新缓存,而是要替换manifest文件//修改注释更新# wanz app v1
三、使用JavaScript api编写更新程序

方法12为自动更新,方法3为手动更新

1 var appCache = window.applicationCache;     
2 appCache.update(); // 开始更新     
3 if (appCache.status == window.applicationCache.UPDATEREADY) {    
  appCache.swapCache(); // 获得最新版本缓存列表,而且成功下载资源,更新缓存到最新
}