Как установить заголовки кэша, только если нет ошибки при отправке ответа в Node.js - PullRequest
0 голосов
/ 14 июня 2019

Я делаю это по существу:

app.get('/:id.:ext', (req, res) => {
  const remote = bucket.file(`images/${req.params.id}.${req.params.ext}`)
  // if (isProd)
  //   res.set('Cache-Control', 'public, max-age=604800')
  remote.createReadStream({ validation: false })
    .on('error', error => {
      console.log(error)
      res.send(`data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7`)
    })
    .pipe(res)
    .on('end', () => {
      res.set('Cache-Control', 'public, max-age=86400')
    })
})
  • Когда возникает ошибка, я просто возвращаю пустое изображение. Но в этом случае я не хочу устанавливать заголовки кэша, потому что я не хочу, чтобы чистое изображение кэшировалось.
  • Поэтому я пытаюсь установить заголовки кэша после отправки ответа, но они не проходят.
  • Если я установлю заголовки кэша перед передачей ответа, я кеширую ошибку в случае ошибки.

Хотите знать, как обойти это.

1 Ответ

1 голос
/ 14 июня 2019

Вы не можете делать то, что вы пытаетесь сделать так, как вы пытаетесь это сделать. Последовательность ответа http состоит в отправке заголовков http, а затем начинается отправка тела ответа. Поэтому, если вы отправляете ответное тело (как и вы), вы ДОЛЖНЫ отправить заголовки первыми. Вы не можете начать посылать тело ответа, а затем передумать насчет заголовков. Они уже отправлены.

И вы не можете отправлять заголовки после того, как библиотека http уже начала отправлять тело ответа. При отправке тела ответа записывается текущее сохраненное состояние заголовков http, которые идут с этим ответом, а затем начинается запись ответа.

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

Другим вариантом является предварительная выборка всех данных, которые вы хотите отправить клиенту, ДО того, как вы что-либо отправите. Это позволяет вам с наибольшей вероятностью определить, приведет ли что-либо к ошибке, прежде чем вы начнете отправлять HTTP-ответ, а затем вы сможете обработать весь ответ в соответствии с вашей ошибкой. Очевидно, вы не можете использовать что-то вроде .pipe(res), если собираетесь это сделать. Вместо этого вам нужно загрузить весь ответ в память (или, по крайней мере, часть ответа, если вы собираетесь отправить его порциями), и только тогда, когда он был успешно предварительно проверен, загружен и готов к работе. Вы начинаете отправлять ответ.

Кроме того, еще один способ избежать кэширования изображения ошибки - это выполнить 301 (временное перенаправление) URL-адреса изображения ошибки, а не вернуть его в качестве ответа на исходный запрос. Затем, когда браузер загружает этот перенаправленный URL-адрес и получает изображение, он не будет кэшировать его как исходный URL-адрес.

...