最近做了一个应用,想要在高级浏览器下离线存储图片以及样式,遂用到了html5的manifest,其中遇到不少问题,写下来总结一下。

demo:http://blog.jnecw.com/demo/id_00012/2.html

首先就是要声明 manifest的mime类型,apache下可以在httpd.conf中加上

AddType text/cache-manifest manifest
AddType text/cache-manifest .appcache

其中.appche是manifest文件的扩展名,经测试chrmoe即使不加mime类型也可以正常的解析,但是ff或者safari则必须使用.appcache的声明,否则报错。(其中试过将这两句加入到.htaccess中,失败)

然后就可以在html中调用 manifest文件了:

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

manifest文件格式:

CACHE MANIFEST# VERSION 0.3# 直接缓存的文件
CACHE:# 需要在线访问的文件
NETWORK:# 替代方案
FALLBACK:

在CACHE后面写上要缓存的文件即可,在这里遇到两个小问题:

1.我缓存了首页index.html之后,页面上的图片全部都无法加载了。

查了一下,原来是 首页被缓存之后页面就默认访问离线资源了,因为页面内的图片没有加入到CACHE列表中,所以一个个都显示不出来了。解决办法就是在NETWORK后面加上*号
参考下面的概念:

.零个或多个在线白名单名称空间(online whitelist namespaces)的URL注:在白名单区域出现的url,或被其通配符所匹配的url,都不会从离线应用程序缓存加载资源,而总是尝试从网络中获取(HTTP Cache是有效的.).
.在线白名单通配符标记(online whitelist wildcard flag),分别为open 和 blocking注:白名单的open状态(以通配符"*"作为首个token的白名单,则进入open状态,表示匹配所有URL,如果*不作为首个token出现,会被忽略.)表示, 所有被在线白名单名称空间 ,所匹配的url,如果没有显示的出现在CACHE项中,则都视为 该资源存在于白名单中(因为进入open状态,此时这些资源,都是遵守HTTP缓存头域相关缓存策略的.). blocking状态(即白名单内容首个token不是"*"的状态.则此时白名单中是列出具体的url,或者前缀匹配的表达式的.被匹配的部分则,同open状态匹配一样.可以根据HTTP缓存头域进行正常的访问.),则表示,manifest中没有显式出现过(也不被各类通配符所匹配的)url(自然也包括没有被白名单明确匹配的URL), 会被manifest无效处理.(无效处理,浏览器的实现就是获取不能.无法下载.)参考:http://www.w3.org/TR/2011/WD-html5-20110405/offline.html#changesToNetworkingModel 中的描述.会更明确的说明,无效处理,指的就是下载不能.

这样就会加载在线资源了;

2.我要缓存的images文件夹里面有好多图片,而manifest中必须一一声明文件名,这很令人头痛。于是用php写了一个方法,遍历文件夹内的所有文件,然后生成一个manifest文件,代码如下:

<?php
function list_files( $folder = '', $levels = 100 ) {if( empty($folder) || ! $levels){return false;}$files = array();if ( $dir = @opendir( $folder ) ) {while (($file = readdir( $dir ) ) !== false ) {if ( in_array($file, array('.', '..') ) )continue;if ( is_dir( $folder . '/' . $file ) ) {$files2 = list_files( $folder . '/' . $file, $levels - 1);if( $files2 )$files = array_merge($files, $files2 );else$files[] = $folder . '/' . $file . '/';} else {$files[] = $folder . '/' . $file;}}}@closedir( $dir );return $files;
}
function echoArray($array){for($i=0;$i<count($array);$i++){echo $array[$i];}
}
?>
<?php
$img = list_files('images');
?>
CACHE MANIFEST# VERSION 1.34# 直接缓存的文件
CACHE:
<?php echoArray($img);?># 替代方案
FALLBACK:

将此php文件保存为list.php,chrome浏览器下可以直接这样写<html manifest=”list.php”>

但是其他支持manifest的浏览器则会报错,需要用此php生成一个扩展名为.appcache(前面声明的扩展名,也可以使其他)的文件供html调用就可以了。

另 外针对第一个问题有人用frame的方法来解决,搜了一下相关文档,应该是不可以的。他的思路是并不存储当前被访问的页面,而是用iframe引入一个页 面,在那个页面中调用manifest文件来达到存储列表内资源的目的,根据文档所写:“. a,b两个页面,引入相同资源,但a有使用manifest,而b没有.那么,即使a页面缓存了资源.b页面也不会有效.而且b页面强制更新了资源.a页 面的缓存也不会因为b的更新,而更新.”

也就是即使frame文件存储了当前页面所请求的资源,但是当前页面一样会从服务器上获取它们。此处为个人推论,未得到证实

最后附加上高人 Franky 给的资料

. 引入 manifest方式为 : <html manifest=”name.appcache”>
. manifest的加载是晚于页面其他资源的.
. manifest的contentType应为 : text/cache-manifest
. 建议其扩展名为 : appcache
. manifest文件本质是一个,要采用UTF-8编码方式编码的文本文件.
. 引入manifest的页面,即使没有被列入缓存清单中,仍然会被用户代理缓存.
. manifest文件从标准角度来说,是不能直接从缓存读取的.即使像上一条说的,你明确的把manifest放入另一个清单中.至少也是服务器尝试返回304.再去读缓存.(注1)
. 在线的情况下,用户代理每次访问页面,都会去读一次manifest.如果发现其改变, 则重新加载全部清单中的资源(注2).
. 对于浏览器来说,manifest的加载是要晚于其他资源的. 这就导致check manifest的过程是滞后的.发现manifest改变.所有浏览器的实现都是紧随这做静默更新资源.以保证下次pv,应用到更新.
. manifest文件必须与引入它的页面同源.
. 如果manifest文件是一个https或其他加密协议资源,则其清单中明示项(explicit section)的资源都必须和manifest同源.
. 备用项和备用名称空间,必须与当前的manifest同源.
. 备用项如果发生命中,则也会被缓存.
. 明示项和备用项优先级高于白名单.
. 白名单使用通配符”*”. 则会进入白名单的open状态. 这种状态下.所有不在相关Cache区域出现的url都默认使用HTTP相关缓存头策略.
. 白名单使用具体的前缀匹配或更具体的URL,则都属于blocking状态.这种状态下,白名单所匹配的,非Cache区域出现的URL,与open的*匹配的结果一致,但是不在白名单中,又不在整个manifest的资源,会block.也就是访问,加载不能.
. manifest中的url ,必须与manifest使用相同的协议.
. 一个manifest的明示项中可以包含另一个manifest.(但这种设计,我认为很2.)
. manifest中的url,不应有”#” 锚点部分出现(比如 abc.htm#1,如果出现#,则 #以及后面部分,会被丢弃.)
. 建议使用<!DOCTYPE html> DTD, 因为据说,某些浏览器会因为,进入非标准模式,而无视manifest.
(我本人没有实测,但我个人猜测,如果有这样一款浏览器,那么它很可能就是IE10. 因为IE10进入兼容模式,很多html5草案的API都使用不能.比如performance API)
. 被清单缓存的资源,是无视http cache 相关 头域, 或其是否是https资源的.
. 相同备用名称空间,不能重复出现在 备用区域中.
. 不应有相包含的备用名称空间出现在备用区域中(因为前缀匹配的原因.出现包含,显然是多余的,如果真有一个URL同时匹配两个通配符.那么就以更长的那个为准.).
. 备用名称空间 和 白名单名称空间 都使用前缀匹配模式.即支持通配符匹配模式.(可以放心的是 //www.a.com/abc 是不匹配 //www.a.com/ab的,因为//www.a.com/ab 实际上是//www.a.com/ab/)
. 前缀匹配对端口的匹配是宽松的.如abc.com:80/a.png 就会被 abc.com/所匹配.
. 在写相对路径的时候 不是相对 引入它的html 而是相对 manifest文件所在目录的
. 一但manifest检测,需要更新,导致所有cache资源更新。其中manifest会再次加载一次.(所以给所有缓存资源配置合理的304机制.是十分有必要的.)
. 一组不同的页面引入相同的manifest文件时,这组页面的即构构成一个group.并已document作为标识,来区分他们.其中任何一个的manifest或资源更新,甚至是检测都会触发其他页面的applicationCache的相应事件.
. applicationCache.update(), 只会立刻检测manifest文件,而不会更新相应资源.并且会遵守304相关http缓存头.
. a,b两个页面,引入相同资源,但a有使用manifest,而b没有.那么,即使a页面缓存了资源.b页面也不会有效.而且b页面强制更新了资源.a页面的缓存也不会因为b的更新,而更新.
. a页面引入manifest,缓存的资源, 在浏览器地址栏中直接访问,则也命中offline application的缓存.刷新也如此.至少chrome,FF都是如此实现的.
. a,b两个页面,分别引入A,B两个manifest文件,且分别缓存相同的一个资源R,则 如果此时更新R,然后更新B.则.b刷新后重新获取资源R,但是a的R资源缓存副本是不会被更新的.
. a,b两个页面,引用同一份manifest A. 则更新A,更新R,刷新b, b对应的R资源更新后,a的R资源副本也会随之更新. 这就是cache group的机制.因为a和b对应的application cache,同属于同一个application cache group.. 建议为manifest文件配置304相关 头域时,也配置expires和cache-control : max-age.因为chrome,safari,以及android,只有304相关头域,而没有expires 或 max-age时,不会有304,而只会是200, opera则无视一切http cache头域.总是200.
(浏览器的实现都有问题,webkit的问题是,没有遵守http协议.因为304相关头域是足矣使浏览器是具备资源副本,并做握手的. 而opera则完全无视http缓存头域.更加不靠谱. (IE10 pp2,FF系列.不方便测试))

转载于:https://www.cnblogs.com/shimily/articles/4270578.html

HTML5 离线存储实战之manifest(附缓存整个文件夹的方法)相关推荐

  1. 神奇的HTML5离线存储(应用程序缓存)

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接前端小尚,谢谢! 前言 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本. HTML5引入 ...

  2. html5离线保存需要联网吗,html5 离线存储

    在html页面中引入manifest文件 在服务器添加mime-type text/cache-manifest 如下: sample.appcache内容如下: CACHE MANIFEST #ve ...

  3. HTML5离线存储利与弊

    一.概念 离线存储是HTML5中的一个重要特性,顾名思义就是将一些资源文件保存在本地,这样后续的页面重新加载将使用本地资源文件,这样子使得你的web应用可以在用户离线的状况下进行访问,很显眼有三个好处 ...

  4. html5离线存储图片,HTML5教程 离线存储技术详解

    本篇教程探讨了HTML5教程 离线存储技术详解,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 . < 随着Web App的发展,越来越多的移动端App使用HTML5 ...

  5. [html5]离线存储

    H5的一个重要特性就是离线存储,所谓的离线存储就是将一些资源文件保存在本地,这样后续的页面重新加载将使用本地资源文件,在离线情况下可以继续访问web应用,同时通过一定的手法(更新相关文件或者使用相关A ...

  6. html离线教程,HTML5离线存储整理

    前端html部分 //canvas.html 浏览器离线存储 配置文件 CACHE MANIFEST #v1.0.5 #需要缓存的文件 CACHE: /photos/canvas.png #不需要缓存 ...

  7. HTML5 本地存储和内容按需加载的思路和方法

    HTML5 本地存储和内容按需加载的思路和方法 作者:佚名 字体:[增加 减小] 来源:互联网 时间:04-07 16:05:09 我要评论 本文将着重介绍HTML5本地存储和内容按需加载的思路和方法 ...

  8. html5 application cache 空间限制,HTML5离线存储之Application Cache

    关于html5的离线存储,大致可分为: localStorage, sessionStorage indexedDB web sql application cache 可以在chrome的debug ...

  9. HTML5 离线存储之Web SQL

    HTML5 在离线存储之Web SQL 本篇没有考虑异步,多线程及SQL注入 WebDatabase 规范中说这份规范不再维护了,原因是同质化(几乎实现者都选择了Sqlite), 且不说这些,单看在H ...

  10. 关于Nginx配置缓存后文件夹中没有缓存文件

    郑重说明: 前提1:本文只适合和我一样的小白,大手们出门左转 前提2:你已经将proxy_cache缓存最基本的配置完毕,也就是如果你ps -ef |grep nginx能看到多了个cache进程 前 ...

最新文章

  1. 使用Python,OpenCV加载图像并将其显示在屏幕上?
  2. C语言博客作业03--函数
  3. WOR文件转换成GST文件
  4. JavaFX官方教程(十三)之应用效果
  5. leetcode632. 最小区间(堆+多指针)
  6. verilog 移位运算符 说明_Verilog学习笔记基本语法篇(二)·········运算符...
  7. Qt笔记-QWebView完整加载页面及获取cookie
  8. 10折交叉验证(10-fold Cross Validation)与留一法(Leave-One-Out)、分层采样(Stratification)
  9. 前景菜谱制作的seo技巧
  10. 用C/C++写CGI程序
  11. 《Python游戏编程快速上手》一第1章 安装Python
  12. java中12个月_C中的12个月日历
  13. QQ象棋java通用版下载_QQ中国象棋
  14. tempo jsnode扩展 3d图形支持。
  15. java中modifier_Ruby中的private modifier与Java中的对比
  16. configure: error: Package requirements (sqlite3 」 3.7.4) were not met:
  17. 豆粕5连跌四月季节性偏弱,铁矿石认购翻倍,甲醇05-09季节性反套2022.3.30
  18. 《算法设计与分析》期末复习精简版
  19. 欧拉角速率与机体角速度转换详细推导
  20. Unity 六边形地图系列(二十五) :水循环

热门文章

  1. 区块链 智能合约 执行原理
  2. Hyperledger Fabric教程(11)-- 链码和背书策略
  3. kubernetes视频教程笔记 (18)-service
  4. Hyperledger Fabric blockchain explorer 重启
  5. Linux学习(4)vim编辑器的安装使用
  6. centos 编译Qt5 mysql驱动_centos7安装编译mysql的驱动的问题
  7. c++ 实现一个object类_一个Java类就能实现微服务架构的权限认证
  8. 关于点击锁(防止多次点击)
  9. Servlet chapter 1
  10. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_06-freemarker基础-遍历map数据...