【问题标题】:Express static server cache control with max-age=0,must-revalidate使用 max-age=0 表示静态服务器缓存控制,必须重新验证
【发布时间】:2017-11-20 08:10:22
【问题描述】:

我已经使用 express 设置了一个简单的静态服务器。

var location = path.join(__dirname, 'public');
app.use(express.static(location, { cacheControl: true, setHeaders: function(res, path) { 
    res.setHeader("Cache-Control","max-age=0,must-revalidate");  
} }));

请求标头与If-None-MatchIf-Modififed-Since 一起发送,如果我在不修改文件的情况下重新加载页面,我还可以在Chrome 的响应中看到304 Not Modified。如果我修改其中一个文件,我会收到 200 OK

但是当状态码是 304 Not Modified 时,为什么我的 Chrome 网络选项卡显示下载文件的大小而不是显示 (from memory cache)

如果文件未修改,我希望文件从缓存中加载,如果修改,则从服务器提供。

感谢任何帮助和指导。

【问题讨论】:

    标签: node.js express http-caching


    【解决方案1】:

    @sBanda 很好地描述了这种情况。由于指定的cache-control 策略将文件声明为过时,因此预计会收到 304,但 ETag 检查显示它没有更改。您得到 304 是因为您可能没有请求特定资源,但您却请求了,浪费了带宽和 CPU 负载。

    你应该做些什么来避免它是这样的:

    const express       = require('express');
    
    
    const server        = express();
    const oneHour       = 3600000;    // 3600000msec == 1hour
    
    server.use(express.static('www', { maxAge: oneHour })); // Client-side file caching
    
    server.get('/', function(req, res) {
      res.sendFile(__dirname + '/index.html');
    });
    
    server.listen(8080);
    

    Source

    【讨论】:

    • 但是将其设置为 oneHour 将在一个小时后从服务器重新加载文件并重置其缓存,如果缓存在一小时内被修改,我希望缓存被重新加载到新文件中跨度>
    • 啊哈,现在我们到了某个地方;) 向Cache Invalidation 问题问好,这个问题和计算机科学本身一样古老。 Web 开发人员通常所做的是将 maxAge 设置为一个巨大的值(1 年),当文件更改时,他们将其重命名为 main.css -> main_v2.css。而且因为这变得越来越快,我们通常会使用 gulp 等构建工具自动将文件名附加到文件 main_4abed1c996f46e1b2ad61757af46ece4.css 的哈希值,这样任何更改都会自动使缓存无效。
    • 但这已经超出了您最初问题的范围,并且在线提供了大量编写良好的资源,如果已经回答并且您仍然需要缓存方面的帮助,您最好关闭此问题失效,然后制作一个新的。 :)
    • 在 Fiddler 中检查时,304 响应只有标题而不是正文,我是否正确地假设在 304 的情况下内容没有从服务器传输到浏览器。
    • 是的,内容尚未传输。但 ETag 已发送并评估。这会浪费资源,最重要的是会延迟您网站实际需要的资源的加载,因为往返时间延迟会无缘无故地阻止浏览器的网络线程。如果您在 3G 或 2G 网络上浏览您希望网站发出尽可能少的获取请求,这尤其糟糕,因为响应有 非常 很大的延迟,即使只是返回 304 .
    【解决方案2】:

    当浏览器将某些内容放入其缓存中时,它还会存储来自服务器的 Last-Modified 或 ETag 标头。然后,此标记用于发送带有 If-Modified-Since 或 If-None-Match 标头的请求,如果内容仍然具有该 ETag,则实际上告诉服务器发送 304。

    在您的情况下,Chrome 正在发出请求以询问服务器是否应使用其缓存 有一篇旧帖子解释了这个here

    您可能想查看website,了解如何通过 HTTP 缓存标头提高应用程序性能。

    【讨论】:

    • 我得到了所有这些,它按预期完成了所有事情。但即使内容具有相同的 ETag 并且服务器发送 304,我希望浏览器从其缓存中获取而不是再次从服务器获取。
    • 浏览器需要检查它是否会使用缓存或是否有新文件可供下载。如果您希望从缓存中使用它而无需检查,您应该使用 ExpiresCache-Control max age
    • 如果未修改,我希望它从缓存中使用,否则如果修改,则从服务器中使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2017-07-16
    • 2011-02-25
    • 2015-12-04
    • 2022-01-22
    • 1970-01-01
    • 2012-11-21
    相关资源
    最近更新 更多