Как отключить кеширование веб-страниц в ExpressJS + NodeJS?

По умолчанию мой браузер кэширует веб-страницы моего приложения 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'));
});

4 ответа

нокаш

Не тратьте время на изобретение велосипеда, используйте промежуточное ПО без кэша.

Установите его:

npm install --save nocache

Затем добавьте его в свое приложение:

const nocache = require('nocache');

app.use(nocache());

Это работает простым способом (из документа):

Это устанавливает четыре заголовка, отключая кеширование в браузере:

  • Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate
  • Прагма: без кеширования
  • Срок действия: 0
  • Суррогатный контроль: нет магазина

Etag

Остерегайтесь ETags: этот заголовок не удаляется с помощью вышеуказанного промежуточного программного обеспечения, потому что он работает по-другому. Он создается в конце запроса, поэтому у вас есть два варианта.

app.set

Отключение с помощью встроенного экспресс app.set('etag', false); метод

заголовки

Удаление заголовка непосредственно перед его отправкой клиенту с помощью модуля on-headers:

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.js необходимо учитывать две вещи: ETag а также Cache-Control заголовки.

ETag ( ссылка MDN)
Если у вас есть динамический контент, который не приносит пользы от ETag, лучше отключить его, потому что он несет небольшие накладные расходы с каждым запросом.

app.set('etag', false)

Cache-Control ( ссылка на MDN)
Чтобы полностью отключить кэш, используйте следующий заголовок:

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

Этот заголовок не влияет express.static() промежуточное программное обеспечение. Он обрабатывает кеш по-своему.

app.disable('view cache');

^^ код для ExpressJS

Можно создать мидлвар, в нем настроить заголовки, чтобы не было кеширования, и использовать в тех обработчиках роутов, которые требуют авторизации.

куки-файлы промежуточного ПО:

      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: заголовки взял из библиотеки nocache https://www.npmjs.com/package/nocache

Другие вопросы по тегам