ChatGPT解决这个技术问题 Extra ChatGPT

NodeJS/express:缓存和 304 状态码

当我重新加载使用 express 制作的网站时,我会在 Safari(不是 Chrome)中看到一个空白页面,因为 NodeJS 服务器向我发送了一个 304 状态代码。

如何解决这个问题?

当然,这也可能只是 Safari 的问题,但实际上它在所有其他网站上都可以正常工作,所以它也必须是我的 NodeJS 服务器上的问题。

为了生成页面,我将 Jade 与 res.render 一起使用。

更新:似乎出现此问题是因为 Safari 在重新加载时发送 'cache-control': 'max-age=0'

更新 2:我现在有一个解决方法,但有更好的解决方案吗?解决方法:

app.get('/:language(' + content.languageSelector + ')/:page', function (req, res)
{
    // Disable caching for content files
    res.header("Cache-Control", "no-cache, no-store, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", 0);

    // rendering stuff here…
}

更新 3:所以完整的代码部分目前是:

app.get('/:language(' + content.languageSelector + ')/:page', pageHandle);

function pageHandle (req, res)
{
    var language = req.params.language;
    var thisPage = content.getPage(req.params.page, language);

    if (thisPage)
    {
        // Disable caching for content files
        res.header("Cache-Control", "no-cache, no-store, must-revalidate");
        res.header("Pragma", "no-cache");
        res.header("Expires", 0);

        res.render(thisPage.file + '_' + language, {
            thisPage : thisPage,
            language: language,
            languages: content.languages,
            navigation: content.navigation,
            footerNavigation: content.footerNavigation,
            currentYear: new Date().getFullYear()
        });
    }
    else
    {
        error404Handling(req, res);
    }
}
304不是问题。它只是意味着您的响应没有被修改,并且您的浏览器转向缓存以获取资源。您能否发布发生异常的相关代码。
是的,实际上它没有被修改,但是 Safari 在 CMD + R (重新加载)上清空了它的缓存,服务器只说它没有改变。
空白页与 304 状态码有什么关系? Node 也会向其他浏览器发送 304。
这是相关的,因为 304 没有发送正文并且浏览器使用它的缓存,但是由于没有缓存,所以你得到一个空白页面
@AkshatJiwanSharma 开发任何程序都是为了完全符合产品所有者的合同。产品负责人是拥有代码并付钱的人,而不是某个撰写没人关心的论文的组织。如果合同上写着“200”,那么绝对任何不等于“200”的状态都是错误。当出现错误时,我必须重写代码,直到一切都完全符合预期。 W3C在这件事上没有发言权。

b
blented

最简单的解决方案:

app.disable('etag');

如果您想要更多控制权,请在此处替代解决方案:

http://vlasenko.org/2011/10/12/expressconnect-static-set-last-modified-to-now-to-avoid-304-not-modified/


您能否解释“最简单的解决方案”或就其影响提供参考?
@SamuelMéndez 它基本上禁用缓存,etag 上的 wiki 有很多很好的信息en.wikipedia.org/wiki/HTTP_ETag
为我工作:)
这是有道理的。我相信 etag 没有被正确地重新计算,因为我没有设置最后修改日期,如 vlasenko 的链接中所述。当我按如下方式更新代码时,我的问题就消失了: const headers = { 'Last-Modified': (new Date()).toUTCString() }; app.get('/*', (req, res) => { res.sendFile(join(DIST_FOLDER + '/index.html'), { headers }); });
s
sbugert

尝试在 Safari 中使用隐私浏览或删除整个缓存/cookie。

当浏览器认为它的缓存中有网站但实际上没有时,我在使用 chrome 时遇到了一些类似的问题。

使服务器响应 304 的 http 请求部分是 etag。似乎 Safari 在没有相应缓存的情况下发送了正确的 etag。


当我尝试删除整个缓存时,这对我有用,谢谢
u
user907567

我在 Safari 和 Chrome(我测试过的唯一一个)中遇到了同样的问题,但我只是做了一些似乎可行的事情,至少自从我添加了解决方案后,我无法重现该问题。我所做的是使用生成的时间戳将元标记添加到标题中。似乎不对,但很简单:)

<meta name="304workaround" content="2013-10-24 21:17:23">

更新 PS 据我所知,当我删除我的节点代理(代理我指的是 express.vhost 和 http-proxy 模块)时,问题就消失了,这很奇怪......


我也使用 Apache 代理,这可能是问题所在。我的解决方法是禁用带有 http 标头的内容站点的缓存。
通过标头禁用缓存绝对是要走的路。起初它对我不起作用,但现在它起作用了。换句话说,我一定是第一次在某个地方犯了错误:)
J
J. Scott Elblein

如您所说,Safari 在重新加载时发送 Cache-Control: max-age=0。 Express(或者更具体地说,Express 的依赖项,node-fresh)在接收到 Cache-Control: no-cache 标头时会考虑缓存陈旧,但它不会对 Cache-Control: max-age=0 执行相同的操作。据我所知,它可能应该。但我不是缓存专家。

解决方法是将 node-fresh/index.js 的第 37 行(当前是什么)从

if (cc && cc.indexOf('no-cache') !== -1) return false;  

if (cc && (cc.indexOf('no-cache') !== -1 ||
  cc.indexOf('max-age=0') !== -1)) return false;

我通过 npm 分叉 node-fresh 和 express 以将此修复程序包含在我的项目的 package.json 中,您也可以这样做。这是我的叉子,例如:

https://github.com/stratusdata/node-fresh https://github.com/stratusdata/express#safari-reload-fix

safari-reload-fix 分支基于 3.4.7 标签。


做得好!我看到 express 3.5.1 包含您通过 node-fresh 0.2.2 进行的修复。
实际上,我错了,您的修复已恢复,实际上并没有达到 0.2.2。仍然没有新鲜/快速修复。
C
Codebeat

老问题,我知道。不需要禁用缓存工具,也不是管理问题的最佳方法。通过禁用缓存设施,服务器需要更加努力地工作并产生更多流量。此外,浏览器和设备需要更加努力地工作,尤其是在移动设备上,这可能是个问题。

在浏览器中使用 Shift 键+重新加载按钮可以轻松解决空白页面。

空页可能是以下原因造成的:

您的代码中的错误

在测试时,您提供了一个由浏览器缓存的空页面(您不记得了)

Safari 中的错误(如果有,请向 Apple 报告,不要尝试自行修复)

首先尝试 Shift 键盘键 + 重新加载按钮,看看问题是否仍然存在并查看您的代码。


H
Hasan Gökçe

操作系统:Windows

浏览器:铬

我使用了 Ctrl + F5 键盘组合。通过这样做,而不是从缓存中读取,我想得到一个新的响应。解决方案是硬刷新页面。

MDN Web Docs

“HTTP 304 Not Modified 客户端重定向响应代码表示不需要重新传输请求的资源。这是对缓存资源的隐式重定向。”


S
Slava Rozhnev
// just add * in URL
    
app.get('/api*', (req, res)=>{

// do something 

});