React 前端 Nginx 缓存配置

2,825 阅读2分钟

最新用React开发钉钉微应用,上线后发现 2 个问题:

1.每次更新后,需要用户手动刷新获取最新的 HTML 和最新的 js,经常被客户吐槽为什么 bug 还没改,其实早已经改了,只是客户手机上跑的还是旧版。

2.不设置缓存策略的情况下,无论本地是否有缓存,华为手机上竟然每次都重新请求 js、css,每次打开很慢,体验极差。

为了解决这两个问题,将 HTML 文件的缓存策略设置为协商缓存,也就是每次都会询问服务器本地是否最新,如果最新,服务器返回 304 而不传输文件,本地加载缓存文件;如果本地文件非最新,服务器就会返回最新文件,本地展示最新文件并更新本地缓存。浏览器询问本地是否最新用到了 ETag 和 Last-Modified。

ETag 由 Nginx 生成,生成规则为:

文件最后修改时间 16 进制-文件长度 16 进制。例:ETag: “59e72c84-2404” 文件长度

10进制为->9220
转为16进制->2404

文件最后修改时间:

标准日期格式->Sat, 21 Oct 2017 09:14:34 GMT
转为秒->1508322436
转为16进制->59e72c84

由此可见,只要更新了 html 文件,浏览器一定会重新加载 HTML,不会出现更新之后,用户跑的还是旧版的问题,解决问题 1。

由于华为手机默认不使用缓存,并且为了节省带宽,提高用户加载速度,js、css 以及常用的静态资源应该强制使用缓存。由于 react 每次打包后,只要代码更改了,js 和 css 文件名一定会变化,所以也不用担心由于强缓存导致浏览器运行旧版代码的问题,这样就解决了第二个问题。

以下是设置 HTML 文件协商缓存,js、css 强缓存的 Nginx 配置

location /test/ {

  ...
  #其他配置
  ...

  if ($request_uri ~* .*[.](js|css|map|jpg|png|svg|ico)$) {
    add_header Cache-Control "public, max-age=2592000";#非html缓存1个月
  }

  if ($request_filename ~* ^.*[.](html|htm)$) {
    add_header Cache-Control "public, no-cache";
    #html文件协商缓存,也就是每次都询问服务器,浏览器本地是是否是最新的,是最新的就直接用,非最新的服务器就会返回最新
  }
}

附上浏览器缓存规则:


参考: juejin.cn/post/684490…