问题 表达视图缓存表现有趣


我正在使用express / Jade中的视图缓存遇到一些有趣的东西。控制器通过Mongoose从MongoDB中获取一篇文章并将其交给res.render函数。但是,在运行几分钟后,Express开始为该路由的所有请求提供相同的编译模板。这甚至发生在各种模板中使用的共享.jade包含。

数据库正在获取正确的文章,如果我将一些随机字符串传递给模板并不重要,我总是得到相同的输出。

这是控制器功能:

exports.show = function(req, res) {
  var articleId;
  articleId = req.params.id;
  Article.findOne({
    _id: articleId
  }).populate('author').exec(function(err, article) {
    if (err) {
      console.log(err);
    } else {
      res.render('articles/show', {
        article: article,
        articleId: article.id
      });
    }
  });
};

这就是路线:

app.get('/articles/:id', articles.show);

无论我是在生产模式还是在开发模式下运行,都会发生同样的事情。

有没有人用Express / Jade遇到这种骚扰?


1244
2018-06-04 16:19


起源

使用“相同的编译模板”,你的意思是一样的 呈现 模板?我不确定它是视图缓存,因为在开发模式下运行时它不活动(除非你明确启用它?)。此外,视图缓存仅存储已编译(但未呈现)的模板,它们仍将针对每个请求单独呈现。您的应用设置是什么样的?可能导致问题的任何其他中间件(或者可能是Node前面的代理服务器)? - robertklep
我同意@robertklep。我猜你的代理是缓存。如果您看到任何缓存标头,是否可以检查响应的标头?另外,尝试在服务器端设置以下标头。缓存控制:无缓存,无存储,必须重新验证Pragma:no-cache Expires:0看看它是否适合您?stackoverflow.com/questions/49547/... - Pradeep Mahdevu


答案:


编辑: 请注意,express为生产启用了视图缓存: 看到 表达文档

view cache启用视图模板编译缓存,启用   默认生产

尝试在您的应用配置部分添加此行:

app.disable('view cache');

此外,尝试添加缓存控制标头

res.setHeader('Cache-Control', 'no-cache');
res.render('articles/show', {
...

w3.org 文档:

Cahce-控制

Cache-Control通用标头字段用于指定指令   沿着所有缓存机制必须遵守   请求/响应链。指令指定了旨在的行为   防止缓存对请求产生负面干扰或   响应。这些指令通常会覆盖默认缓存   算法。缓存指令是单向的,即存在   请求中的指令并不意味着相同的指令   在答复中给出。

如果您需要更高级的控件,请考虑其他字段,如max-age, 这个问题 也是一个很好的资源,你会发现不同的浏览器可能会实现这个rfc略有不同。


7
2017-10-29 15:21



浏览器缓存不是问题。我说看看四篇不同的博文。稍后,所有URL将开始提供相同的博客帖子。就像jade正在缓存模板而不打扰使用我传递给它的对象......它只是使用最后的已知值。 - MikeSmithDev
好的,我明白你的观点,标题不只是浏览器缓存,想象你有生产中的清漆,或者你的DNS有像Cloudflare这样的缓存机制,必须遵守响应中的这个标题。但我明白你的观点。然后我会替换jbs或其他的玉来丢弃这是一个模板引擎问题。或者查看Jade repo以查看缓存是否存在已知问题。 - alfonsodev
是的,我想我必须走这条路。 - MikeSmithDev
跟进:我结束了 点。 - MikeSmithDev


TL; DR:试试

let articleId;

代替

var articleId;

我只是Node.js的另一个新版本,但我刚刚用“var”关键字代替“let”解决了同样的问题。问题是“var”创建一个由函数作用的变量,而“let” - 作用于当前块1。每次执行块时都会重新创建,这很重要,因为Node.js的异步性质。


2
2018-01-03 00:22