2. 如果缓存名单已过期(根据它的HTTP头),那么你的浏览器将会询问服务器是否有新版本,如果有,浏览器将会下载它。要做到这一点,你的浏览器产生一个包含此缓存名单last-modified数据的HTTP请求,你的网络服务器将浏览器下载名单文件的最后时间包含在HTTP响应头中。如果网络服务器判断从那个时间之后没有被更改,它将简单的返回一个304(未改变)状态。同样的,这不是离线网络应用程序所特有的。它发生于实质上每种类型的网络资源。
3. 如果网络服务器认为名单文件在那个时间之后有被更改,它将返回一个200(OK)HTTP状态码,后面是新文件的内容和新的Cache-Control头,以及一个新的last-modified时间,因此,第1步和第2步将可能在下次发生。(HTTP非常酷,网络服务器总是为将来做打算。如果你的网络服务器绝对需要给你传送一个文件,他尽所有可能确认他不需要无故传送第二次。)一旦下载了新的缓存名单文件,你的浏览器将根据它上次下载的副本检测内容。如果缓存名单文件的内容跟上次的一样,你的浏览器将不会重新下载此名单中列出的任何资源。
当你开发和测试你的离线网络应用程序时,这些步骤的任意一个都可能让你犯错误。例如,比如说你发布了一个新版本的缓存名单文件,10分钟后,你发现你需要在里面添加另一个资源。没问题,对吧?仅仅添加另一行并重新发布。这是将要发生的事情:你重新载入页面,你的浏览器发现了manifest属性,它触发了checking事件,然后…没啥了。你的浏览器坚持认为缓存名单文件并没有被更改。为啥?因为你的网络服务器可能由于默认配置,告诉浏览器需要缓存静态文件几个小时(通过HTTP语义,使用Cache-Control头)。这意味着你的浏览器将不会通过三相进程中的第1步。当然,网络服务器知道文件已经更改,但你的浏览器甚至不会有足够的时间去询问网络服务器。为啥?因为你的浏览器上次下载了缓存名单,网络服务器告诉它需要缓存这个资源几个小时(通过HTTP语义,使用Cache-Control头)。那么10分钟后,这就是你的浏览器确切会做的事情。
你必须清楚,这不是错误,而只是个特性。一切都按照它应该的方式工作着。如果网络服务器没有办法告诉浏览器(和中间代理)去缓存资源,网络可能很快崩溃。但没人来安慰你花上几个小时去尝试想出为啥你的浏览器没有注意到你更新过的缓存名单。(实际上,如果你等待得足够久,它将神秘重新开始工作!因为HTTP缓存过期了!就像它应该的那样!杀了我!现在杀了我!)
所以,这儿有一件你必须要做的事情:重新配置你的网络服务器,以便你的缓存名单文件不会因为HTTP语义而可缓存。如果你使用基于Apache的网络服务器,你.htaccess文件中的这两行将会达到目的:
ExpiresActive On
ExpiresDefault “access”
这将会使每一个在此目录和所有其子目录中的文件缓存失效。这可能是你在制作中所不希望的,所以你应该使用一个
一旦你使缓存名单文件本身的HTTP缓存失效,你将仍然看到过时的却已在应用程序缓存中更改的某个资源,只因为它仍然以相同的URL存在于你的网络服务器。这里,三相进程中的第2步将会欺骗你。如果你的缓存名单文件没有被更改,浏览器将不会注意到之前缓存的某个资源已被更改。注意下面的例子:
CACHE MANIFEST
# rev 42
clock.js
clock.css
如果你更改了clock.css并重新发布,你不会看到更改,因为缓存名单文件本身没有更改。每次你对离线应用程序中的某个资源进行更改,你需要对缓存名单文件本身做出修改。这跟改变一个单字符一样简单。我发现完成这件事最简单的方法就是包含一个有修订编号的注释行。更改这个注释中的修订编号,那么网络服务器将返回最新更改的缓存名单文件,并且将使进程开始重新下载名单中列出的所有资源。
CACHE MANIFEST
# rev 43
clock.js
clock.css