当前位置: 首页 > 科技观察

如何使网站使用HTML5Manifest

时间:2023-03-15 10:03:37 科技观察

Manifest用于制作离线页面。即使断网也能正常打开页面。使用方便,但在实际使用中存在以下问题:(1)如何自动缓存所有页面资源?因为manifest不能使用*通配符进行缓存(2)如果网站资源有更新,manifest文件如何自动更新?否则,如果用户不清除缓存,即使联网也会加载旧页面。我想很多网站都不用Manifest是因为上面说的有人试过,但是用起来比较麻烦,离线应用价值好像也不是很大。但是使用Manifest还是有很多优势的,尤其是偏向展示的网站,比如博客,或者在线APP。这类网站数据动态变化的频率比较低,不需要频繁向服务请求数据。这样,当用户需要频繁返回首页或频繁在多个页面之间来回切换时,由于几乎所有资源都在本地,所以加载是瞬时的。1.使用ManifestManifest的使用很简单,就是在html标签中添加一个manifest属性:这个属性指向一个manifest文件,它指定了哪些资源当前页面需要离线缓存,home.appcache如下:CACHEMANIFEST#9/27/2017,3:04:25PM#htmlhttps://github.com/#imghttps://assets-cdn.github.com/图像/模块/站点/universe-octoshop.pnghttps://assets-cdn.github.com/images/modules/site/universe-wordmark.png#csshttps://assets-cdn.github.com/assets/frameworks-bedfc518345231565091.css#jshttps://assets-cdn.github.com/assets/compat-94eba6e3cd1fa18902d9.jsNETWORK:*FALLBACKhttps://github.com//html/manifest/html/home.html这个文件的***行必须以CACHEMANIFEST开头,否则浏览器在解析的时候会报错,注释以#开头,后面是这一行下面需要缓存的资源,后面的NETWORK表示需要加载到哪些资源上线。一般需要写成NETWORK*,表示除了CACHE之外的所有资源都需要联网,包括对于一些动态请求,如果不写*,而是写具体路径,那些既不在CAHCE中的norinNETWORK会报loadingfailure错误,如下图:即使连上了网络也是一样,所以一般写成*.FALLBACK表示替代资源。如果无法加载这些资源,则更换加载哪些资源。比如上面的文件https://github.com无法访问,使用静态html访问:https://github.com/html/manifest/html/home.html。打开一个支持Manifest的网站,比如https://fed.renren.com,可以在Chrome控制台观察缓存的过程:然后刷新页面,你会发现页面上几乎所有的资源都被缓存了本地,如下图提示:并且你断开网络,刷新页面,页面依然可以正常加载。这在Chrome/Firefox/Safari等浏览器中是受支持的。除了Manifest,还有一种缓存的手段,就是设置HTTP头的Cache-Control字段进行缓存。这样可以缓存JS/CSS/图片资源,但是如果你也缓存HTML,就会出现问题,如果用户不清除缓存,即使你的页面更新了,用户还是会加载旧的页面,直到缓存设置的Max-Age时间到了。所以使用Manifest可以解决这个问题。Manifest怎么知道当前页面的数据已经更新了呢?只需更改清单文件,例如上面的home.appcache。浏览器在打开页面时将加载此文件。一旦发现文件发生变化,下次就会刷新。时间会重新加载所有的Cache文件,最简单的方法就是把评论里的时间改成现在的时间:#9/29/2017,9:08:49AM这样当网站的资源发生变化的时候,就可以改变内容了此清单,然后可以更新连接到Internet的浏览器。使用Manifest时,需要注意以下问题:(1)Manifest有大小限制,实际上被认为是本地存储。本地存储一般每个域名空间有限,PCChrome是5Mb。参考下表:(2)home.appcahce等Manifest文件不能跨域。如果跨域需要支持CORS(3)ManifestCache资源不能跨域。同样,如果资源需要支持跨域CORS,一般浏览器会自动处理。2.解决Manifest的自动生成和更新问题,由于Manifest不能使用通配符匹配资源,所以需要将要缓存的资源一一列出,而网站内容经常动态更新,所以这个比较麻烦。为此,作者写了一个自动生成manifest的npm包generate-manifest,使用起来非常简单:npminstall-gggenerate-manifestgenerate-manifest--url=https://github.com会生成一个Manifest文件对于home.appchache,此文件包含页面上img/js/css的资源链接:CACHEMANIFEST#9/27/2017,3:04:25PM#htmlhttps://github.com/#imghttps://assets-cdn.github.com/images/modules/site/universe-octoshop.pnghttps://assets-cdn.github.com/images/modules/site/universe-wordmark.png#csshttps://assets-cdn.github.com/assets/frameworks-bedfc518345498ab3204d330c1727cde7e733526a09cd7df6867f6a231565091.css#jshttps://assets-cdn.github.com/assets/compat-91f98c37fc84eac24836eec2567e9912742094369a04c4eba6e3cd1fa18902d9.jsNETWORK:*FALLBACKhttps://github.com//html/manifest/html/home.html还可以支持其参与数据制定,请参阅:generate-manifest。这样就解决了自动生成的问题,自动更新怎么办?由于本人是博客站点,站点内容的变化主要包括:1.发布/更改博客;2、用户发表评论;3.网站浏览量变了,第一个解决办法是写一个接口,只要你发个博客调整这个接口生成一个新的manifest文件即可:https://fed.renren.com/refresh-manifest.php?link=https://fed.renren.com/2017/09/26/manifest/然后会调整上面的generate-manifest包生成一个manifest.appcache文件,这是html中路径的最后一部分确定清单的名称:2?$uriArray[count($uriArray)-2]:"home";?>manifest=>这个和生成的文件名一一对应。第二个问题:用户发表评论-在调用表界面自动调整这个界面。需要注意的是这个接口需要防止脚本注入,否则比较危险。第三题:读取数据变化-写一个linux定时任务,使用crontab添加定时任务,执行crontab-e添加:03***/home/fed/manifest/update-all.sh上面的意思是每天3:00运行update-all。sh脚本,这个脚本写了所有页面更新命令:generate-manifest--url=https://fed.renren.comgenerate-manifest--url=https://fed.renren.com/page/2/generate-manifest--url=https://fed.renren.com/page/3/#..Other...***点提到的发表的文章也会在这个脚本中加入一行命令。由于阅读量数据不是很重要,所以每天更新一次就足够了。这样就可以缓存用户当天的操作。如果您第二天回来,请更新。所以自动更新的问题基本解决了。还有一个问题是Manifest改完后第一次刷新还是老页面,只有第二次刷新是正确的,所以我们希望Manifest改完之后一刷新就新了,而不是之前。缓存的不需要刷新两次。那我们该怎么办呢?清单有一个更新事件。一旦manifest文件更新,就会触发这个事件,所以我们可以监听这个事件,然后自动刷新页面重新加载页面。下面的代码:);}这样我们就很好用Manifest做了一个离线页面应用,解决了自动生成和自动更新的问题。即使用户不离线,第二次加载的资源也会缓存在本地,所以当用户在几个页面之间来回切换时,速度非常快,比如很多人可能在首页的列表之间和内容页来回切换。虽然Manifest已经被弃用并被ServiceWorker取代,但由于它的易用性和良好的兼容性,我们仍然可以使用它。原文链接:https://fed.renren.com/2017/09/29/manifest/【本文为专栏作者“人人网FED”原创稿件,转载请联系原作者获得授权】点击在这里看文章作者更多好文章