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

时间:2013-09-15 10:24:39

标签: node.js caching safari express http-status-code-304

当我重新加载使用快递制作的网站时,我得到一个使用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);
    }
}

8 个答案:

答案 0 :(得分:74)

最简单的解决方案:

app.disable('etag');

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

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

答案 1 :(得分:3)

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

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

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

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

答案 2 :(得分:2)

我在Safari和Chrome中遇到了同样的问题(我测试过的唯一的问题),但我刚刚做了一些似乎有用的东西,至少我没有能够重现问题,因为我添加了解决方案。我所做的是使用生成的timstamp向标头添加元标记。看起来不对,但很简单:)

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

<强>更新 P.S 据我所知,当我删除我的节点代理(通过代理我的意思是express.vhost和http代理模块)时,问题就消失了,这很奇怪......

答案 3 :(得分:1)

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

当浏览器认为它的网站位于缓存中但实际上没有使用Chrome时,我遇到过类似的问题。

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

答案 4 :(得分:0)

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

使用浏览器上的Shift键和重新加载按钮可以轻松解决空白页。

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

  • 代码中的错误
  • 在测试期间,您提供了一个空白页(您不能 记住),它是由浏览器缓存的
  • Safari中的错误(如果是, 请向苹果报告,请勿尝试自行修复)

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

答案 5 :(得分:0)

这...这是最简单的方法...

function force200Responses(req, res, next) { req.headers['if-none-match'] = 'no-match-for-this'; next(); }

app.use(force200Responses)

将来,不客气。

答案 6 :(得分:0)

  • 操作系统:Windows
  • 浏览器:Chrome

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

MDN Web Docs

<块引用>

"HTTP 304 Not Modified 客户端重定向响应代码表明 不需要重新传输请求的资源。它是一个 隐式重定向到缓存资源。”

答案 7 :(得分:0)

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

// do something 

});