NodeJS/Express: 缓存和304状态代码

当我重新加载一个用 Express 制作的网站时,我会得到一个用 Safari (而不是 Chrome)制作的空白页面,因为 NodeJS 服务器会给我发送一个304状态码。

怎么解决这个问题?

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

为了生成页面,我使用了 Jade 和 res.render

Update: It seems like this problem occurs because Safari sends 'cache-control': 'max-age=0' on reload.

更新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);
}
}
131271 次浏览

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

当浏览器以为自己的网站在缓存中,但实际上并没有时,我在使用 chrome 时也遇到过类似的问题。

使服务器响应为304的 http 请求部分是 etag。看起来 Safari 发送了正确的标签却没有相应的缓存。

我在 Safari 和 Chrome (我测试过的唯一两个浏览器)中也遇到过同样的问题,但是我只是做了一些看起来有用的事情,至少在我添加了解决方案之后我还没有能够重现这个问题。我所做的是在头部添加一个元标记,并生成一个时间戳。看起来不太对,但很简单:)

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

更新 附言 据我所知,当我删除我的节点代理(代理我的意思是既 Express.vhost 和 http-agent 模块)时,问题就消失了,这很奇怪..。

正如您所说,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;

我分叉节点新鲜和快速包括这个修复在我的项目的 package.json通过 npm,你可以做同样的事情。这是我的叉子,例如:

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

Safari-reload-fix 分支基于3.4.7标记。

最简单的解决办法:

app.disable('etag');

如果你想要更多的控制权,这里有另一个解决方案:

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

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

在浏览器中使用 Shift 键 + 重新加载按钮可以很容易地解决空白页面的问题。

空白页面可能是下列原因造成的:

  • a bug in your code
  • 当测试时,您提供了一个空页面(您不能 remember) that is cached by the browser
  • a bug in Safari (if so, 请向苹果报告,不要试图自己修复它)

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

  • 操作系统: Windows
  • Browser: Chrome

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

MDN 网络文档台:

”HTTP304未修改的客户端重定向响应代码指示 不需要重新传送所请求的资源 隐式重定向到缓存资源。”

// just add * in URL
    

app.get('/api*', (req, res)=>{


// do something


});