如何在ExpressJS + NodeJS中禁用网页缓存?

f2uvfpb9  于 2022-11-03  发布在  Node.js
关注(0)|答案(4)|浏览(233)

默认情况下,我的浏览器缓存ExpressJS应用程序的网页。
这导致了我的登录系统出现问题(未登录的用户可以打开已登录用户的旧缓存页面)。
如何禁用此缓存?
编辑:
我的app.js(主文件):

var express = require('express');
var http = require('http');
var path = require('path');

var store = require('./routes/store');
var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3012);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('your secret here'));
  app.use(express.session());
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', store.home);
app.post('/', store.home);

app.get('/addProblem', store.addProblem);
app.post('/addProblem', store.addProblem);

app.get('/problem', store.problem);
app.post('/problem', store.problem);

app.get('/problemList', store.problemList);
app.post('/problemList', store.problemList);

app.get('/main', store.main);
app.post('/main', store.main);

app.post('/login', store.login);
app.get('/login', store.login);

app.get('/createProblem', store.createProblem);
app.post('/createProblem', store.createProblem);

app.post('/register', store.register);
app.get('/register', store.register);

app.post('/evaluate', store.evaluate);
app.get('/evaluate', store.evaluate);

app.get('/logout', store.logout);
app.post('/logout', store.logout);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
f87krz0w

f87krz0w1#

在Express.js中处理缓存时,需要考虑两件事-ETagCache-Control头。

电子标签MDN reference

如果您的动态内容不能从ETag中受益,最好禁用它,因为它会导致每个请求的开销很小。

app.set('etag', false)

高速缓存控制MDN reference

要完全禁用缓存,请使用以下标头:

app.use((req, res, next) => {
  res.set('Cache-Control', 'no-store')
  next()
})

这个头文件不影响express.static()中间件,它以自己的方式处理缓存。

vaqhlq81

vaqhlq812#

无缓存

不要浪费时间重新发明轮子,用nocache middleware代替。它已经在7 years2022)上发布了,每周下载次数超过150万次。它在github上只有100颗星,实际上是快递生态系统中的一个“无名英雄”。

安装它

npm install --save nocache

将其添加到您的应用程序:

const nocache = require('nocache');

app.use(nocache());

当作为中间件安装时,它设置了四个头文件,禁用了大量的浏览器缓存。

  • 缓存控制:无存储、无缓存、必须重新验证、代理重新验证
  • 编译指示:无缓存
  • 过期时间:0
  • Surrogate-Control:无存储

小心ETag

即使您使用nocache,ETag头也不会被删除,因为它的工作方式不同。它在请求结束时生成,可能是另一个意外缓存的来源。要处理它您有两个选择

应用程序集

第一个是使用快速内置app.set('etag', false);方法禁用它。

标题上

第二个是在将标头发送到客户端之前使用on-headers module

const onHeaders = require('on-headers');

// install it as a middleware
app.use((req, res, next) => {
    // listen for the headers event
    onHeaders(res, () => {
        this.removeHeader('ETag');
    });
});
  • 正如在评论中指出的,这实际上是一个“十行”包,但你真的想在每个express项目上复制和粘贴相同的代码块吗?或者更糟的是,发布另一个类似的包?我不这么认为,我相信你的同事也这么认为;- )*
x7yiwoj4

x7yiwoj43#

app.disable('view cache');

^^ExpressJS的程式码

osh3o9ms

osh3o9ms4#

您可以创建一个中间件,在其中设置头以便不存在缓存,并在那些需要授权的路由处理程序中使用。
中间件cookie:

const cookie = async (req, res, next) => {
  try {
    const token = req.cookies.token;

    const check = jwt.verify(token, process.env.JWT_SECRET);
    const user = await User.findOne({_id: check._id, 'tokens.token': token});

    if (!user) {
      throw new Error();
    }

    req.token = token;
    req.user = user;

    res.set({
      "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
      "Pragma": "no-cache",
      "Expires": "0",
      "Surrogate-Control": "no-store"
    });
    next();
  } catch (e) {
    res.set({
      "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
      "Pragma": "no-cache",
      "Expires": "0",
      "Surrogate-Control": "no-store"
    }).redirect(301, '/login');
  }

};

已使用:

router.get('/all/tasks', cookie, async (req, res) => {
  try {
    const task = await Task.find({owner: req.user._id});

    if (!task) {
      return res.status(404).send();
    }

    res.status(200).render('tasks', {
      title: 'Your task',
      task: task
    });
  } catch {
    res.status(500).send();
  }
});

Ps:我从nocashe库https://www.npmjs.com/package/nocache中获取了头文件

相关问题