【问题标题】:Caching is not cleared for index.html未清除 index.html 的缓存
【发布时间】:2022-01-20 05:33:55
【问题描述】:

我们在 React 应用程序中遇到缓存问题。

问题

这个问题从这个项目开始就出现了,因为我们没有包含任何缓存标头...我们的客户总是必须在新的生产版本发布后刷新他们的网页。之后一直解决到下一个版本。

我们希望解决这个问题,以便客户在新的生产版本发布后不必刷新页面。

当前设置

应用程序是使用 Create-React-App 构建的,并使用默认的缓存清除实现 (filename.[hash].js/css)。 我们使用 unregister() 禁用了 serviceworker。 该应用程序在使用 docker 构建的 Nginx 上运行。

尝试修复之前的旧 Nginx 配置:

server {
  listen              443 ssl;
  ssl_certificate     /etc/nginx/ssl/server.crt;
  ssl_certificate_key /etc/nginx/ssl/server.key;

  add_header X-Frame-Options         "SAMEORIGIN";
  add_header X-Content-Type-Options  "nosniff";
  add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; manifest-src 'self'; script-src 'self'; img-src 'self'; font-src 'self' https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; report-uri /csp/report" always;

  server_tokens off;

  root  /usr/src/app;
  index index.html index.htm;

  location ~* /favicon.ico$ {
    try_files $uri $uri/ /favicon.ico =404;
  }

  location ~* /manifest.json$ {
    try_files $uri $uri/ /manifest.json =404;
  }

  location / {
    try_files $uri $uri/ /index.html =404;
  }

  location ~ .(static)/(js|css|media)/(.+)$ {
    try_files $uri $uri/ /$1/$2/$3 =404;
  }
}

我们尝试过的事情:

我们尝试在 Nginx 中更改 index.html 的标头:

  location / {
    try_files $uri $uri/ /index.html =404;

    add_header Cache-Control "no-cache, no-store, no-transform, must-revalidate, max-age=0";
    add_header Pragma "no-cache";
    add_header Expires "0";
  }

我们希望这可以解决我们对 index.html 的缓存问题。当我们在 Chrome 中打开应用程序时,它会打开旧版本。当我们按下 F5 时,Chrome 会加载带有 Cache-Control 标头的新版本。然后我们在 Chrome 中打开一个新标签页,它会再次显示旧版本的应用程序。

添加 Clear-Site-Data 标头是可行的(但仅适用于支持它的浏览器)。这至少告诉我们这是一个缓存问题。

  location / {
    try_files $uri $uri/ /index.html =404;

    add_header Clear-Site-Data "\"cache\"";
  }

这些是我们在加载带有 Cache-Control 标头的新版本应用程序后(按 F5 后)从 Nginx 返回的标头。

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 17 Dec 2021 08:51:33 GMT
Content-Type: text/html
Content-Length: 1113
Last-Modified: Thu, 16 Dec 2021 14:35:26 GMT
Connection: keep-alive
ETag: "61bb4eae-459"
Cache-Control: no-cache, no-store, no-transform, must-revalidate, max-age=0
Pragma: no-cache
Expires: 0
Accept-Ranges: bytes
Strict-Transport-Security: max-age=31536000

为什么即使我们使用这些新的缓存标头加载应用程序,Chrome 仍会加载旧的 Web 应用程序?

提前感谢您的建议/帮助。

【问题讨论】:

    标签: reactjs google-chrome nginx caching browser-cache


    【解决方案1】:

    A bug in Chrome 91 在 DevTools 中错误地将 304 服务器响应显示为 200。检查您的 Nginx 服务器日志以确保发送正确的响应。我必须明确设置if_modified_since off 以防止304 响应Chrome。在测试期间使用新的隐身 Chrome 标签页,以防止浏览器重复使用缓存页面。

    server {
      location /no-cache-test {
        add_header Cache-Control no-cache;
        etag off;
        if_modified_since off;
      }
      ...
    }
    
    $ mkdir no-cache-test
    $ touch no-cache-test/index.html
    $ curl -I https://example.com/no-cache-test/
    
    HTTP/2 200 
    server: nginx
    date: Fri, 17 Dec 2021 17:11:54 GMT
    content-type: text/html; charset=utf-8
    content-length: 0
    last-modified: Fri, 17 Dec 2021 16:53:14 GMT
    cache-control: no-cache
    accept-ranges: bytes
    
    $ sudo tail -f /var/log/nginx/example.com.access.log
    
    [17/Dec/2021:12:12:47 -0500] "GET /no-cache-test/ HTTP/2.0" 200 0 "-"
    

    【讨论】:

    • 您好,感谢您的回复。您和我的解决方案都可以在 Chrome 的隐身模式中使用。我看到它总是用 200 加载 index.html。但是我的问题是它永远不会以普通 chrome 显示新发布的版本。它不断加载旧的缓存版本。当它加载旧的缓存版本时,您在 nginx 日志中看不到它。这就是我想要摆脱的。您将如何摆脱普通用户的缓存?
    • 当您退出并重新打开 Chrome 并加载页面时会发生什么?
    • 它加载最旧的版本而不缓存标头。我们甚至部署了多个没有缓存头的版本,它只会采用没有指定缓存头的最后一个版本。
    猜你喜欢
    • 2018-06-04
    • 2012-04-07
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 2011-07-25
    • 2017-04-06
    相关资源
    最近更新 更多