Вы не можете делать то, что вы пытаетесь сделать так, как вы пытаетесь это сделать. Последовательность ответа http состоит в отправке заголовков http, а затем начинается отправка тела ответа. Поэтому, если вы отправляете ответное тело (как и вы), вы ДОЛЖНЫ отправить заголовки первыми. Вы не можете начать посылать тело ответа, а затем передумать насчет заголовков. Они уже отправлены.
И вы не можете отправлять заголовки после того, как библиотека http уже начала отправлять тело ответа. При отправке тела ответа записывается текущее сохраненное состояние заголовков http, которые идут с этим ответом, а затем начинается запись ответа.
Насколько мне известно, единственный способ справиться с ошибкой, возникающей в середине отправки тела ответа http, - это преждевременно закрыть соединение http. Клиент увидит сокет закрытым, не видя конца ответа http, и поймет, что он получил завершенный, незаконченный ответ. У вас нет возможности отправить еще один ответ в этот момент. Обработка ошибок в этом случае должна быть на стороне клиента, чтобы решить, что делать.
Другим вариантом является предварительная выборка всех данных, которые вы хотите отправить клиенту, ДО того, как вы что-либо отправите. Это позволяет вам с наибольшей вероятностью определить, приведет ли что-либо к ошибке, прежде чем вы начнете отправлять HTTP-ответ, а затем вы сможете обработать весь ответ в соответствии с вашей ошибкой. Очевидно, вы не можете использовать что-то вроде .pipe(res)
, если собираетесь это сделать. Вместо этого вам нужно загрузить весь ответ в память (или, по крайней мере, часть ответа, если вы собираетесь отправить его порциями), и только тогда, когда он был успешно предварительно проверен, загружен и готов к работе. Вы начинаете отправлять ответ.
Кроме того, еще один способ избежать кэширования изображения ошибки - это выполнить 301 (временное перенаправление) URL-адреса изображения ошибки, а не вернуть его в качестве ответа на исходный запрос. Затем, когда браузер загружает этот перенаправленный URL-адрес и получает изображение, он не будет кэшировать его как исходный URL-адрес.