e-works数字化企业网  »  文章频道  »  基础信息化  »  移动应用

H5和移动端 WebView 缓存机制解析与实战

2017/7/2    来源:腾讯Bugly    作者:叶建升      
关键字:H5    WebView  
本文从实际web应用项目中缓存相关问题出发,较为全面地分析了html5缓存机制的原理与应用以及移动端应用webView对html5缓存机制的支持方式,以供web开发的同学们参考。
    在web项目开发中,我们可能都曾碰到过这样一个棘手的问题:
 
    线上项目需要更新一个有问题的资源(可能是图片,js,css,json数据等),这个资源已经发布了很长一段时间,为什么页面在浏览器里打开还是没有看到更新?
 
    有些web开发经验的同学应该马上会想到,可能是资源发布出了岔子导致没有实际发布成功,更大的可能是老的资源被缓存了。说到web缓存,首先我们要弄清它是什么。Web缓存可以理解为Web资源在Web服务器和客户端(浏览器)的副本,其作用体现在减少网络带宽消耗、降低服务器压力和减少网络延迟,加快页面打开速度等方面(笔者在香港求学期间看到港台地区将cache译为“快取”,除了读音相近,大概就是贴近这层含义)。他们通常还会告诉你:ctrl+F5强刷一下,但是本文下面的内容将会说明为什么强制刷新在去除缓存上不总是能奏效的,更何况对于线上项目而言,总不能让所有已经访问过的用户撸起袖子岔开两个手指都强制刷新一下吧?
 
    同时,当前原生 + html5的混合模式移动应用(hybrid APP)因可大幅降低移动应用的开发成本,并且可在用户桌面形成独立入口以及有接近原生应用的体验而大行其道,APP内嵌h5应用的开发也是本人现在工作内容重要的一部分,本文将从实际项目开发中遇到的问题出发,一窥html5和app内webview的缓存机制真容。
 
    一、协议缓存
 
    回到开头的那个问题,更新了一张图片,发布之后反复重新进页面总是看不到更新,这是为什么呢?
 
    这里我们假设已经排除了资源没有发布成功过的情况,那么第一步,我们可能会认为是http协议缓存(也称为浏览器缓存或者网页缓存)。
 
    http协议缓存机制是指通过 HTTP 协议头里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段来控制文件缓存的机制。
 
  • Cache-Control 用于控制文件在本地缓存有效时长。最常见的,比如服务器回包:Cache-Control:max-age=600 表示文件在本地应该缓存,且有效时长是600秒(从发出请求算起)。在接下来600秒内,如果有请求这个资源,浏览器不会发出 HTTP 请求,而是直接使用本地缓存的文件。

  • Last-Modified 是标识文件在服务器上的最新更新时间。下次请求时,如果文件缓存过期,浏览器通过 If-Modified-Since 字段带上这个时间,发送给服务器,由服务器比较时间戳来判断文件是否有修改。如果没有修改,服务器返回304告诉浏览器继续使用缓存;如果有修改,则返回200,同时返回最新的文件。
 
    Cache-Control 通常与 Last-Modified 一起使用。一个用于控制缓存有效时间,一个在缓存失效后,向服务查询是否有更新。
 
    Cache-Control 还有一个同功能的字段:Expires。Expires 的值一个绝对的时间点,如:Expires: Thu, 10 Nov 2015 08:45:11 GMT,表示在这个时间点之前,缓存都是有效的。
 
    Expires 是 HTTP1.0 标准中的字段,Cache-Control 是 HTTP1.1 标准中新加的字段,功能一样,都是控制缓存的有效时间。当这两个字段同时出现时,Cache-Control 是高优化级的。
 
    Etag 也是和 Last-Modified 一样,对文件进行标识的字段。不同的是,Etag 的取值是一个对文件进行标识的特征字串。在向服务器查询文件是否有更新时,浏览器通过 If-None-Match 字段把特征字串发送给服务器,由服务器和文件最新特征字串进行匹配,来判断文件是否有更新。没有更新回包304,有更新回包200。Etag 和 Last-Modified 可根据需求使用一个或两个同时使用。两个同时使用时,只要满足基中一个条件,就认为文件没有更新。
 
H5 和移动端 WebView 缓存机制解析与实战
 
    一个比较形象的理解:
 
    翠花:狗蛋,你几岁了?
 
    狗蛋:我18岁了。(200)
 
    翠花记住了狗蛋18岁(200 from cache)
 
    =================================
 
    翠花:狗蛋 ,你几岁了?我猜你18岁。
 
    狗蛋:靠,知道还问我!(304)
 
    =================================
 
    翠花:狗蛋 ,你几岁了?我猜你18岁。
 
    狗蛋:翠花 ,我已经19岁了。(200)
 
    不过有两种情况比较特殊:
 
    手动刷新页面(F5),浏览器会直接认为缓存已经过期(可能缓存还没有过期),在请求中加上字段:Cache-Control:max-age=0,发包向服务器查询是否有文件是否有更新。
 
    强制刷新页面(Ctrl+F5),浏览器会直接忽略本地的缓存(有缓存也会认为本地没有缓存),在请求中加上字段:Cache-Control:no-cache(或 Pragma:no-cache),发包向服务重新拉取文件。
 
    当然,各个浏览器对于刷新和强制刷新的实现方式也有一些区别。
 
    那么,如果线上更新了web资源,如何能让尽快更新呢?(要知道像图片这样比较少更新的资源一般缓存时间都设置得比较长,比如game.gtimg.cn域名下是一天,有问题的图片在用户侧缓存这么长时间是不可接受的)
 
    方法一 修改请求header头,比如php添加:
 
H5 和移动端 WebView 缓存机制解析与实战
 
    方法二 修改html的head块:
 
H5 和移动端 WebView 缓存机制解析与实战
 
    方法三:添加随机参数:
 
    对于图片或者css,可使用如下方式:
 
H5 和移动端 WebView 缓存机制解析与实战
 
    对于js则可以直接使用时间戳:
 
H5 和移动端 WebView 缓存机制解析与实战
 
    二、应用缓存
 
    除了http协议缓存,HTML5 提供一种应用程序缓存机制,使得基于web的应用程序可以离线运行。为了能够让用户在离线状态下继续访问 Web 应用,开发者需要提供一个 cache manifest 文件。这个文件中列出了所有需要在离线状态下使用的资源,浏览器会把这些资源缓存到本地。例如以下页面:
 
H5 和移动端 WebView 缓存机制解析与实战
 
    其对应的 calender.manifest代码
 
H5 和移动端 WebView 缓存机制解析与实战
 
    cache manifest 格式遵循以下原则:
 
    1.首行必须是 CACHE MANIFEST。
 
    2.其后,每一行列出一个需要缓存的资源文件名。
 
    3.可根据需要列出在线访问的白名单。白名单中的所有资源不会被缓存,在使用时将直接在线访问。声明白名单使用 NETWORK:标识符。
 
    4.如果在白名单后还要补充需要缓存的资源,可以使用 CACHE:标识符。
 
    5.如果要声明某 URI 不能访问时的替补 URI,可以使用 FALLBACK:标识符。其后的每一行包含两个 URI,当第一个 URI 不可访问时,浏览器将尝试使用第二个 URI。
 
    6.注释要另起一行,以 # 号开头。
 

责任编辑:李欢
本文为授权转载文章,任何人未经原授权方同意,不得复制、转载、摘编等任何方式进行使用,e-works不承担由此而产生的任何法律责任! 如有异议请及时告之,以便进行及时处理。联系方式:editor@e-works.net.cn tel:027-87592219/20/21。
兴趣阅读
H5    WebView  
相关资料
e-works
官方微信
掌上
信息化
编辑推荐
新闻推荐
博客推荐
视频推荐