美文网首页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 如何及时更新客户端缓存?

    如果你是 Angular 新手 或者对 Http 缓存机制理解不清晰 使用 Angular CLI 开发 Angu...

  • 数据库和缓存数据一致性问题

    业务使用Redis做缓存,当有数据更新时,如何保证缓存及时更新 读数据流程 请求到来,业务代码会先查Redis,查...

  • 解决微信入口文件缓存问题

    目前微信会对页面进行缓存,会导致代码在服务器更新后,用户无法及时加载到,因为访问的还是用户客户端缓存的数据。如果后...

  • 实现缓存最终一致性的两种方案

    一、重客户端 写入缓存: image.png 应用同时更新数据库和缓存 如果数据库更新成功,则开始更新缓存,否则如...

  • 实现缓存最终一致性的两种方案

    一、重客户端 写入缓存: 应用同时更新数据库和缓存 如果数据库更新成功,则开始更新缓存,否则如果数据库更新失败,则...

  • 实现缓存最终一致性的两种方案

    一、重客户端 写入缓存: 应用同时更新数据库和缓存 如果数据库更新成功,则开始更新缓存,否则如果数据库更新失败,则...

  • JS和CSS缓存的问题

    项目上线一段时间后如果更新JS或CSS文件,而客户端已经对该文件缓存过了,那就有可能会无法及时更新而继续采用旧的J...

  • 烂笔头

    angular双向绑定数据,视图不能及时更新时,进行强制更新 (1)从core中导入ChangeDetectorR...

  • 部分Android机html设置no-cache还是缓存了

    .html设置了返回码是304,部分安卓机更新页面后没有及时更新,存在缓存 查看了html响应头缓存设置为:Cac...

  • WebSocket

    在解决什么问题 客户端如何及时更新服务端更新的数据。 用 Ajax 的做法是定时器加反复轮询,检查服务器数据是否更...

网友评论

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

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