美文网首页angular
Angular 如何及时更新客户端缓存?

Angular 如何及时更新客户端缓存?

作者: 萧哈哈 | 来源:发表于2019-01-10 11:38 被阅读16次

    如果你是

    • Angular 新手
    • 或者对 Http 缓存机制理解不清晰
    • 使用 Angular CLI 开发 Angular

    请继续往下读。

    背景

    在 Angular 开发的过程中, 我们经常会发布新的功能或者 fix bug,但是由于浏览器缓存的存在, 可能用户打开的页面并不是最新发布的。 而我们想要的是用户既可以及时看到我们的更新, 又可以在我们没有更新软件时使用缓存中的资源。

    解决办法

    往往静态资源由 Nginx、apache、IIS 等提供, 我们以 Nginx(当前最新版本是 1.15.8, 请确保 Nginx 版本不低于 1.7.3 changelog) 为例,简单说来就是:

    1. 在 Nginx 配置文件 nginx.conf 中确保 Etag 开启(默认是开启的)

    2. index.html 设置响应缓存头:
      Cache-Control: no-cache

    客户端每次请求 index.html 时都要重新验证 index.html 是否发生了改变,
    如果发生了改变,就会请求新的 index.html

    css、js 文件中都有 fingerprint,比如, style.x234dff.css.

    css、js 文件改变 => fingerprint 改变 => 文件名改变 => index.html 改变 => 浏览器下载新的 index.html => 浏览器请求新的 css、js 文件。

    1. 对 css、js、图片等文件设置响应缓存头:
      Cache-Control: max-age=31536000 // 缓存一年。

    由于 css、js 文件名里有 fingerprint, 只要 css、js 文件变了, URL 就会更新,
    这里的 max-age 可以设置足够长的时间

    这是一份 Windows 下 nginx.conf 文件的配置节选:

            location = /index.html {
                add_header Cache-Control no-cache;
            }
    
            location ~\.(js|css)$ {
                root D:\dist; # 静态资源目录
                add_header Cache-Control max-age=31536000;
            }
    
            location ~\.(gif|jpg|png|ico)$ {
                root D:\dist;
                add_header Cache-Control max-age=86400;
            }
    

    补充

    在 Chrome 开发者面板中可能看到某个资源是 200 from memory cache, 而不是 304, 有些人可能会感到很困惑。

    HTTP/1.1 RFC 2616

    13.2.2 Heuristic Expiration

    Since origin servers do not always provide explicit expiration times, HTTP caches typically assign heuristic expiration times, employing algorithms that use other header values (such as the Last-Modified time) to estimate a plausible expiration time. The HTTP/1.1 specification does not provide specific algorithms, but does impose worst-case constraints on their results. Since heuristic expiration times might compromise semantic transparency, they ought to used cautiously, and we encourage origin servers to provide explicit expiration times as much as possible.

    13.4 Response Cacheability
    Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a
    successful response (see section 13.8) as a cache entry, MAY return it without validation if it is fresh, and MAY
    return it after successful validation.

    浏览器的缓存有 2 种:

    • 验证性缓存。用 ETag 、 Last-Modified 、 If-None-Match 、 If-Modified-Since 来控制,其特点是会发一个请求给服务器来确认缓存是否有效,如果有效就返回 304 ,省去传输内容的时间。

    • 非验证性缓存(强缓存)。 如果响应头中没有指定明确的过期时间(Cache-Control: max-age=、Expires), 某些浏览器会缓存成功的请求并使用 Http 头部(比如 Last-Modified)应用某种推测算法计算得出过期时间。其特点是一但有效就在有效期内不会发任何请求到服务器。非验证性缓存的优先级是高于验证性缓存的。

    Chrome 开发者面板中看到的 200 from memory cache 就是非验证性缓存, 原因是没有设置 相关的响应头。

    参考

    相关文章

      网友评论

        本文标题:Angular 如何及时更新客户端缓存?

        本文链接:https://www.haomeiwen.com/subject/jxsorqtx.html