HTML5实现应用程序缓存(Application Cache)


Posted in HTML / CSS onJune 16, 2020

为什么要使用Application Cache技术?

在HTML5之前,我们需要接入网络才能访问,这毫无疑问是网站多次请求服务器,造成速度变慢,对于PC用户,网络相对比较稳定,载入速度也不会差太多。但是移动端呢?移动端依赖无线信号、依赖信号塔、位置不固定、受附近建筑影响等。一系列导致网络的不稳定,我们不能改变用户,也不能放弃网络较慢的用户。
还有,在混合app领域,经常使用内置webview加载html页面,如果网速太慢,依然会造成上述问题。

离线存储技术

实际开发中,主要是使用Application Cache和LocalStorage技术,它们来自HTML5技术。

(1)Application Cache:通常用于静态资源(静态页面)的缓存。
(2)LocalStorage:通常用于AJAX请求缓存,存储非关键性AJAX数据。

我用一段话来赘述下为什么要使用Application Cache技术:
当页面有些元素它们是不变的,你可以使用Application Cache技术离线缓存掉,每次访问这些缓存掉的元素就不需要再请求服务器了,当有些东西经常变,那就让它们每次请求服务器吧!

HTML5 Application Cache特性

HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问。
应用程序缓存为应用带来三个优势:
(1)离线浏览:用户可在不介入网络时访问使用
(2)速度提升:已缓存资源加载得更快
(3)减少对服务器的请求:浏览器将只从服务器下载更新过或更改过的资源
支持情况:除了IE浏览器,都支持Application Cache

开始使用Application Cache

涉及角色:服务器和html文件

服务器端需要做的事情

管理维护manifest.appcache文件,检查manifest清单中是否有无法访问的文件,并及时更新,以免造成损失。

manifest文件(W3C建议文件扩展名为.appcache)
manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容)。

manifest 文件可分为三个部分:

  • CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
  • NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
  • FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)

我们梳理一下逐一进行介绍

一、CACHE MANIFEST(它是必须的)

CACHE MANIFEST
/reset.css
/logo.gif
/hx.js

manifest 文件列出了三个资源:一个 CSS 文件,一个 GIF 图像,以及一个 JavaScript 文件。当 manifest 文件加载后,浏览器会从网站的根目录下载这三个文件。然后,无论用户何时与因特网断开连接,这些资源依然是可用的。
注意:文件位置根据文件在服务器的实际目录,确保路径正确。
总结:CACHE MANIFEST列出的资源是需要在本地缓存的文件(要缓存的文件)

二、NETWORK

NETWORK:
nav.html

NETWORK 小节规定文件 “nav.html” 永远不会被缓存,且离线时不可用。

NETWORK:
*

也可以使用星号“ * ”来指示所有其他资源/文件都需要因特网连接。
注意:千万不要把首页index放入NETWORK中禁止缓存,否则插件等无法使用。
总结:NETWORD列出的资源是需要每次请求的动态资源文件(不缓存的文件)

三、FALLBACK

FALLBACK:
/index/ /404.html

FALLBACK 小节规定如果无法建立因特网连接,则用 “404.html” 替代 /index/ 目录中的所有文件。
注意:第一个 URI 是资源,第二个是替补。
总结:FALLBACK列出的资源是如果某个文件无法联网或接入失败,则使用后一个替补显示。(友好的替补页面)

完整的manifest文件

CACHE MANIFEST
# Files that need to be cached2014.6.5
/reset.css
/logo.gif
/hx.js

NETWORK:
#Files that do not need caching2014.6.5
nav.html

FALLBACK:
#Files to be replaced2014.6.5
/index/ /404.html

注意:#代表注释行,看似简单的注释行却有着很大的用处,为什么这么说呢,因为应用的缓存会在其 manifest 文件更改时被更新。如果您编辑了一幅图片,或者修改了一个 JavaScript 函数,这些改变都不会被重新缓存。更新注释行中的日期和版本号、时间戮或md5码等,是一种使浏览器重新缓存文件的办法。

html需要做的事情

只需要引入manifest.appcache文件

<!DOCTYPE HTML>
<html manifest="manifest.appcache">

Application Cache生命销毁规则

(1)用户清空浏览器的缓存,此时Application Cache本地缓存将销毁。
(2)manifest文件被修改时,因为应用的缓存会在其 manifest 文件更改时被更新。如果您编辑了一幅图片,或者修改了一个 JavaScript 函数,这些改变都不会被重新缓存,此时Application Cache本地缓存将销毁。
(3)由程序来更新应用缓存

深入manifest.appcache文件

首先提醒的就是,千万不要把index首页禁止缓存,虽然放入NETWORK也不起作用,这是一种规范,也是一种规则,请遵守。

HTTP相关的缓存头域以及https的缓存页面限制,将被manifest所无视,所以在用户代理更新页面之前,它是不会过期的,也就是说,即使是HTTPS,也可以脱机工作。

各大浏览器对应用缓存的容量限制有所不同,几乎为5MB。

当一个资源被缓存后,该浏览器直接请求这个绝对路径也会访问缓存中的资源。

缓存包含manifest清单的页面,所以实际上,即使我们不显示的把包含manifest的页面,列在manifest缓存清单中,这个页面也会被缓存。

每次网站更新,服务器端要进行manifest.appcache文件的检查和更新,避免造成损失。

站点中的其他页面即使没有设置manifest属性,请求的资源如果在缓存中也从缓存中访问。

如果manifest文件,或者内部列举的某一个文件不能正常下载,整个更新过程都将失败,浏览器继续全部使用老的缓存。

其实,不必明确的列出Application Cache链接到的页面,默认情况下,任何包含html元素manifest属性的页面都会缓存,这些自动缓存的页面称为主条目,而清单中列出的文件称为详细条目,如果某些文件需要在线访问,可以创建 “ 白名单 ”。像在NETWORK下的条目,这些文件通常称之为网络条目,每次联网,每次都要请求服务器。

第一行CACHE MANIFEST是固定的格式,且必须要写在第一行,也必须要有,NETWORK和FALLBACK为可选项。

FALLBACK中的资源必须和manifest文件同源。

引用manifest的html必须与manifest文件同源,在同一个域下。

当manifest文件发生改变时,资源请求本身也会触发更新

注释不仅仅起到不执行的作用,上述已经详细解释了,可以是版本号,时间戳或者md5码等等。

manifest文件中的cache部分不能使用通配符,必须手动指定,没有自动化工具。

在开发过程中,通过ajax与WCF进行数据交互时,常常头一次或头几次数据加载成功,以后均加载失败。

因为启用的web离线缓存机制,所以每次ajax加载数据时是从本地缓存文件中读取的,用的是ajax的get模式,因为get模式缓存,所以不会重新向服务器请求数据,导致数据加载失败。
改成ajax post方式后,数据 never cache,所以每次刷新网站,均会向service请求数据。

报错: Application Cache Error event: Manifest fetch failed (404)

解决方法:
manifest 文件需要配置正确的 MIME-type,即 “text/cache-manifest”。
manifest 的 contentType = text/cache-manifest,扩展名建议为 .appcache
且必须在 web 服务器上进行配置,不同的服务器配置方法不一样。

页面离线,ajax更新。

首先,你可以修改下 manifest 文件来更新这个页面,但是作为文章内容页面离线以后,就会存储在本地了,如果你是一篇章的话,那么这个文章的内容页就被存下来了,你如果以相同的 url 去访问,不管你文章里面的数据更新没有,这个离线下来的页面都不会更新了 ( 除非你更新manifest 文件 ) 。所以,你所有的动态数据,都得用 ajax 方式去获取,就像客户端一样,离线的页面应该是一个没有数据的空壳,然后通过 ajax 去拉去数据填补这个空壳。然后要注意的是,ajax 的请求地址,要写到manifest 的 network 中。

离线页面的更新(长尾问题)

网站更新了,如何更新用户本地的离线页面呢?
与很多文章中说的一样,先上线你的文件,然后修改一下页面中引入的cache.manifest文件即可,比如修改下注释,修改后,如果再访问页面,就会先去校验manifest 时候有更新,如有更新,再次刷新页面的时候,页面就会更新了。
长尾问题(非常重要):
就像前面说到的一样,如果你的 manifest 文件更新了,你访问页面,需要刷新一次,更新的页面才能 load加载进来,那么这样就有一个问题,如果你的后端数据,就是给 js ajax 接口的数据变化了,你对应的 js 也修改了。那么你修改 manifest 上线的时候,第一次开页面,页面就会出 bug 了。再刷一次页面,就好了。那么,这个第一次访问的 bug ,是我们不想看到的。
而且你不能知道用户什么时候第二次再来访问你的页面,所以你的页面一旦使用 manifest 离线,就像客户端一样,这样就出现了长尾问题。还好, manifest 有一些 js 接口,可以来判断, load 更新文件。

cache.status属性返回当前离线应用状态

  • UNCACHED ( 数值 0) :未启用离线应用
  • IDLE ( 数值 1) :已开启离线应用,但本地缓存的资源是最新的,并且未标记为废弃资源
  • CHECKING ( 数值 2) :当前更新缓存的状态为 “ 检查中 ”
  • DOWNLOADING ( 数值 3) :当前更新缓存的状态为 “ 下载资源中 ”
  • UPDATEREADY ( 数值 4) :当前更新缓存的状态为 “ 更新完毕 ”
  • OBSOLETE ( 数值 5) :已开启离线应用,但缓存资源都已标记为废弃
     

如果文件超出缓存5M的大小,会造成什么。
比如我A频道维护了自己的Application Cache,B频道也维护了自己的,这个时候A频道如果使用达到了一个峰值,会导致B频道所有的缓存失效。
所以,建议Application Cache存储公共资源,不要存储业务资源!

由更新机制来说,首次更新manifest时,因为页面加载已经开始甚至已经完成,缓存更新尚未完成,浏览器仍然会使用过期的资源;浏览器是当Application Cache有更新时,该次不会使用新资源,第二次才会使用。这个时候update事件中执行window.reload事件。

window.applicationCache.addEventListener("updateready", function(){
    window.location.reload()
});

由上例可以知道,缓存的不只是显示定义的文件,比如上例中的applicationcache/时便会默认保存index.html为映射的数据,并且包含demo.appcache文件,很多时候会遇到一次文件更新线上老是不更新,这个时候随便在manifest配置文件中做一点修改即可更新。
做一下代码更改:

<html  manifest="A.appcache">
=>
<html  manifest="B.appcache">

这个时候如果不做A.appcache的更新的话,缓存将不会更新,原因是index.html被缓存了,检测的仍然是原manifest清单
各个页面统一管理自己的manifest清单,意思是a页面配置了common.js,b页面也配置了common.js,意思是a页面更新后,
b页面的manifest不更改的话,b页面依旧读取的是老版本的文件,这个有一定道理却也有一定浪费,需要公共页面做处理。

HTML5实现应用程序缓存(Application Cache)

到此这篇关于HTML5实现应用程序缓存(Application Cache)的文章就介绍到这了,更多相关HTML5应用程序缓存内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
CSS3 中filter(滤镜)属性使用详解
Apr 07 HTML / CSS
CSS3实现线性渐变用法示例代码详解
Aug 07 HTML / CSS
HTML5 File接口在web页面上使用文件下载
Feb 27 HTML / CSS
html5配合css3实现带提示文字的输入框(摆脱js)
Mar 08 HTML / CSS
Html5中localStorage存储JSON数据并读取JSON数据的实现方法
Feb 13 HTML / CSS
解析浏览器的一些“滚动”行为鉴赏
Sep 16 HTML / CSS
详解HTML5常用的语义化标签
Sep 27 HTML / CSS
详解canvas.toDataURL()报错的解决方案全都在这了
Mar 31 HTML / CSS
详解HTML5.2版本带来的修改
May 06 HTML / CSS
HTML5 Blob对象的具体使用
May 22 HTML / CSS
CSS font-variation 可变字体的魅力(实例详解)
Mar 03 HTML / CSS
HTML 里 img 元素的 src 和 srcset 属性的区别详解
May 21 HTML / CSS
html5实现九宫格抽奖可固定抽中某项奖品
Jun 15 #HTML / CSS
HTML5页面无缝闪开的问题及解决方案
Jun 11 #HTML / CSS
Html5导航栏吸顶方案原理与对比实现
Jun 10 #HTML / CSS
浅析图片上传及canvas压缩的流程
Jun 10 #HTML / CSS
原生canvas制作画图小工具的踩坑和爬坑
Jun 09 #HTML / CSS
h5移动端调用支付宝、微信支付的实现
Jun 08 #HTML / CSS
使用SVG实现提示框功能的示例代码
Jun 05 #HTML / CSS
You might like
PHP 设计模式系列之 specification规格模式
2016/01/10 PHP
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
2016/04/07 PHP
JavaScript中逗号运算符介绍及使用示例
2015/03/13 Javascript
js实现刷新iframe的方法汇总
2015/04/27 Javascript
jquery中object对象循环遍历的方法
2015/12/18 Javascript
jquery实现列表上下移动功能
2016/02/25 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
AngularJS过滤器详解及示例代码
2016/08/16 Javascript
jQuery实现table中两列CheckBox只能选中一个的示例
2017/09/22 jQuery
微信小程序获取手机系统信息的方法【附源码下载】
2017/12/07 Javascript
js实现一个简单的MVVM框架示例
2018/01/15 Javascript
深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域
2018/08/28 Javascript
详解Vue CLI3 多页应用实践和源码设计
2018/08/30 Javascript
微信小程序实现简单跑马灯效果
2020/05/26 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
2019/04/14 Javascript
怎样使你的 JavaScript 代码简单易读(推荐)
2019/04/16 Javascript
使用 Vue 实现一个虚拟列表的方法
2019/08/20 Javascript
vue element-ui实现动态面包屑导航
2019/12/23 Javascript
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
关于Python中异常(Exception)的汇总
2017/01/18 Python
pyQT5 实现窗体之间传值的示例
2019/06/20 Python
Python3 tkinter 实现文件读取及保存功能
2019/09/12 Python
Flask模板引擎Jinja2使用实例
2020/04/23 Python
详解向scrapy中的spider传递参数的几种方法(2种)
2020/09/28 Python
python实现企业微信定时发送文本消息的实例代码
2020/11/25 Python
CSS3实现王者荣耀匹配人员加载页面的方法
2019/04/16 HTML / CSS
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
英国豪华针织品牌John Smedley的在线销售商:The Outlet by John Smedley
2018/04/08 全球购物
园林设计师自荐信
2013/11/18 职场文书
刚毕业大学生自荐信范文
2014/02/20 职场文书
初一学生评语大全
2014/04/24 职场文书
法制宣传标语
2014/06/23 职场文书
幼儿老师求职信
2014/06/30 职场文书
单位工作证明书格式
2014/10/04 职场文书
安全责任协议书范本
2016/03/23 职场文书
Mysql 8.x 创建用户以及授予权限的操作记录
2022/04/18 MySQL