Как работает etag в expressjs
Expressjs автоматически отправляет etags. Я хотел бы знать, как генерируется etag.. основано ли это на содержимом, которое динамически генерируется подпрограммой get. или есть способ, которым я могу это воплотить, даже не проходя процесс генерации контента (динамический контент - из БД) и возвращая etag как то же самое.
может быть промежуточным программным обеспечением, которое начинается с простой проверки, является ли он действительным идентификатором сеанса, и передает обратно тот же etag, который дает клиент, или может основываться на URL-адресе + идентификаторе сеанса. Таким образом, он будет уникальным. и завершите запрос, пройдя весь вызов БД и все такое. в этом случае я должен был бы знать, что клиент делает вызов 304.
Я мог бы пойти с expires tag.but, когда сессия закончена. если кто-то открывает URL, он не должен позволять. поэтому я думаю, что etag должен также основываться на идентификаторе сессии. Как работает модификация в этом сценарии динамического контента. это может быть использовано.
2 ответа
Позвольте мне объяснить это в 2021 году с обновленной информацией и ссылками на код.
Это относительно прямолинейная и простая (без ракетостроения) концепция, но в то же время очень сложная вещь, которую, как разработчик, вы должны знать, прежде чем она вас укусит!
Что такое Etag?
Итак, Etag (согласно Wikipedia / Etag) - это HTTP-заголовок.
Его можно увидеть в разделе «Заголовки ответа» некоторых вызовов GET в DevTools, как на скриншоте ниже.
В Express это может начинаться с
Какова цель Etag?
Ах, хороший вопрос. Ответ: кеширование!
(PS. И только кэширование сетевого трафика между клиентом и сервером. Это передача данных ответа, отправляемых через HTTP(S) клиенту; не какое-либо внутреннее кеширование сервера в БД или что-то еще.)
Кеширование, как?
Механизм относительно простой.
Допустим, клиент (браузер, например Chrome) вызывает
Теперь, в следующий раз (даже через несколько дней и сеансов) клиент собирается позвонить в ту же конечную точку
Круто, но разве это не неэффективно?
Это!
Проблема в том, что если клиент отправляет весь объект JSON из кеша в запросе на сервер, это одновременно угроза безопасности и довольно неэффективно - один и тот же объект JSON с 30 полями отправляется по сети, даже, может быть, дважды!
Здесь происходит следующее: клиент (например, браузер Chrome) может вычислить хэш (скажем, MD5, который необратим и короче), а во втором запросе скажите: « Эй, если хеш MD5 JSON, который вы собираетесь отправить я вернулся это
Теперь происходит следующее: сервер будет вычислять ответ (извлечение из БД и все остальное) точно так же, как и раньше. Но ТОЛЬКО ПЕРЕД ОТПРАВКОЙ ДАННЫХ ОТВЕТА он вычисляет хэш-значение ответа (на стороне сервера), чтобы увидеть, соответствует ли оно тому, что клиент сказал, что он уже имеет. Если это так, он отправляет код ответа HTTP 304 вместо 200, что означает «ничего не изменилось».
Хороший! Это именно так?
Что ж, в приведенном выше примере, если вы внимательно посмотрите, вычисление хэша происходит как на стороне клиента, так и на стороне сервера. По крайней мере, это затруднит изменение алгоритма. Таким образом, на самом деле «хэш ответа» фактически вычисляется только на стороне сервера в первый раз и будет отправлен обратно клиенту.
Этот вычисленный хэш «текущего ответа», который возвращается с ответом, находится в заголовке ответа .
При этом всякий раз, когда клиент получает ответ, он сохраняет:
Затем в любых будущих запросах клиент отправит это значение на сервер (в некоторых заголовках, например
Итак, резюмируем:
- value - это не что иное, как безумное, но необратимое, короткое и быстрое хешируемое значение данных ответа (тела).
- Сервер отправляет
заголовок в ответе клиенту. - Клиент отправляет заголовок (значение которого было получено ранее.
значения с сервера) в запросе к серверу.
Большой! Как я могу это использовать?
По умолчанию это происходит в Express.js. Итак, расслабьтесь и наслаждайтесь!
Маловероятно, что вам нужно испортить его настройки.
Когда мне НЕ следует использовать Etag?
Ах! Добро пожаловать в мою жизнь. :D Вот как я попал сюда и провел все эти исследования.
Пакеты Экспресс использует в пакет Etag (это только один файл, управляемый теми же ребятами) , чтобы генерировать значение ETag. Внутри пакета используется
Чтобы решить, должен ли он делать 304 или 200, когда клиент сказал: «У меня уже есть эти значения в моем кеше », Express использует свежий пакет (опять же только один файл, фактически только одна функция, возвращающая логическое значение, поддерживаемое теми же ребятами ). Внутри
Круто, а в чем тогда проблема?
Проблема возникает, когда ваша архитектура и связь между клиентом и сервером полагаются на настраиваемые заголовки!
Например, вы хотите обновить токен аутентификации или сеанса для любого запроса, обновить его в фоновом режиме и отправить новый в качестве ЗАГОЛОВКИ ОТВЕТА на некоторые запросы.
ТЕКУЩАЯ РЕАЛИЗАЦИЯ ЭКСПРЕССА Etag полагается ТОЛЬКО НА ОРГАН ОТВЕТА, А НЕ НА РУКОВОДИТЕЛЕЙ ОТВЕТА. Даже настраиваемая функция, которую они позволяют использовать ( документ, код ), принимает только содержимое тела, а не заголовки ответов.
Итак, что происходит, когда ответ (например, данные профиля) не изменяется, ваш клиент может повторно использовать устаревший токен аутентификации и выгнать пользователя из-за недопустимого тега аутентификации / сеанса!
Как я могу это отключить?
Ты можешь сделать
Ваше здоровье!
PS. Заключительные примечания:
- Если задуматься, ETag очень ценны для активов (когда размер данных ответа составляет 100 КБ или более), но не для общих данных конечных точек API. Так что отключение его для конечных точек с малым откликом может быть неплохой идеей - на самом деле, возможно, стоит не платить накладные расходы.
На момент написания статьи (8 июля 2014 года) слабые ETag генерировались с использованием CRC32 ( источник), а сильные ETag генерировались с использованием MD5 ( источник).
Исходя из того, что говорит один из участников Express, вы можете указать, использовать ли сильные или слабые ETag:
app.enable('etag') // use strong etags
app.set('etag', 'strong') // same
app.set('etag', 'weak') // weak etags
Похоже, вы также можете указать свою собственную пользовательскую функцию для выполнения ETag следующим образом:
app.set('etag', function(body, encoding){ /* return valid etag */ });
Свежий пакет NPM также стоит посмотреть, так как он используется в Express для проверки свежести ( source1, source2).
Что касается вашего приложения, помните, что вы можете переопределить любые заголовки ответа, например res.set('etag', 'my-awesome-etag-value')
перед вызовом res.send()
(или аналогичная функция). Дальнейшее обсуждение (включая преимущества и недостатки) можно найти здесь: https://github.com/visionmedia/express/issues/2129