Глубокое понимание механизма и принципа кэширования HTTP

HTTP

Введение

На прошлой неделе интервьюер Али задал вопрос на собеседовании: «Можете ли вы рассказать мне о процессе 304 и какие атрибуты заголовка влияют на кеш?» OMG......Потому что я только примерно понял, что код состояния 304 означает кеш , а так как кеш не наступил на яму в процессе разработки проекта, то и этот глубоко не изучался. Поэтому, когда мне задали этот вопрос, я почувствовал себя так, как будто меня ударили по голове, и я задумался над этим. Я завербовал себя в качестве инженера-разработчика программного обеспечения в компанию. передний фундамент был почти незаметен. Уже больше года, чтобы хорошо работать на работе, я отдавал много сил своей работе.Это рутинная работа работать до 10 часов вечера, и не менее 1 дня сверхурочной работы в выходные дни ; а в свободное время я часто читаю книги, связанные с интерфейсом, чтобы восполнить основу, такие как «Продвинутое программирование на JavaScript», «Авторитетное руководство по CSS», «Практика Sass», «Программирование высокой производительности на JavaScript». ..."Практика Webpack", "Введение в Node.js" и т.д. Книг не меньше 10, широта еще задействована Их много, но есть проблемы: Я не занимался фронтендом долго, а передние знания сложные.Если у вас нет специальной подготовки, если вас вдруг спросят точку знаний, хотя вы наверняка знаете, что это такое, вам трудно узнать, что это такое , Говорите четко.
Итак, первостепенная задача следующего этапа: «заложить прочный фундамент для фронтенда и глубоко понять принципы используемого стека технологий». Не говори глупостей, учись знанию, если не понимаешь, разбирайся! Следующие «теоретические знания + практическая работа», чтобы полностью понять механизм и принцип кэширования HTTP!

2. Правила кэширования и анализ

Для удобства всеобщего понимания я предполагаю, что в браузере есть кэшированная база данных для хранения кешированной информации. Когда клиент запрашивает данные в первый раз, в базе данных кеша в это время нет соответствующих кэшированных данных, и необходимо запросить сервер.После возврата сервера данные сохраняются в базе данных кеша. Как показано на блок-схеме ниже:
В зависимости от того, нужно ли повторно инициировать запрос к серверу, правила кэширования HTTP делятся на две категории (Принудительно кэшировать,Сравнить кеш) Прежде чем подробно представить эти два правила, пусть каждый получит простое представление об этих двух правилах с помощью диаграммы последовательности.
(1) Когда кэшированные данные уже существуют, только на основеПринудительно кэшировать, процесс запроса данных выглядит следующим образом:


(2) Когда кэшированные данные уже существуют, только на основеСравнить кеш, процесс запроса данных выглядит следующим образом:


Мы можем видеть разницу между двумя типами правил кэширования,Принудительно кэшироватьЕсли он вступит в силу, нет необходимости взаимодействовать с сервером, иСравнить кешНезависимо от того, вступит ли он в силу или нет, он должен взаимодействовать с сервером.
Одновременно могут существовать два типа правил кэширования,Принудительно кэшироватьприоритет надСравнить кеш, то есть при выполненииПринудительно кэшироватьКогда правило установлено, если кеш вступает в силу, использовать кеш напрямую и больше не выполнятьСравнить кешправило.

3. Кэшировать общие поля

1. Схема кэширования в период http1.0


Уведомление:

(1) Если используетсяPragma: 'no-cache'Если это так, то установитеExpiresилиCache-Control, бесполезно, описаниеPragmaвыше двух последних.

(2) Если установленоExpiresПосле этого, когда клиенту потребуется запросить данные, он сначала сравнит текущее системное время с этимExpiresвремя, если не болееExpiresвремя кэшированные данные на локальном диске считываются напрямую без отправки запроса.

2. Схема кэширования в период http1.1

2.1, Поле управления кэшем

2.1.1, Cache-Control как поле заголовка запроса


(1) Cache-Control: без кэша

использоватьno-cacheЦель директивы — предотвратить возврат просроченных ресурсов из кеша. Если запрос, отправленный клиентом, содержитno-cacheдиректива, клиент не получит кэшированный ресурс. Каждый раз, когда делается запрос на получение ресурса с сервера, возвращается ошибка 304.  

(2) Cache-Control: без хранения

использоватьno-storeВ инструкции указано, что запрошенный ресурс не будет кэшироваться, и в следующий раз, когда какой-либо другой запрос получит ресурс, он все равно будет получен с сервера, возвращая 200, что и является самим ресурсом.

2.1.2, Cache-Control как поле заголовка ответа


Cache-Control: public 

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

 Cache-Control: private

когда указаноprivateПосле команды ответ нацелен только на конкретного пользователя, что совпадает сpublicДирективы ведут себя противоположным образом. Кэш-сервер будет предоставлять услугу кеширования ресурсов для конкретного пользователя, а прокси-сервер не будет возвращать кеш для запросов, отправленных другими пользователями.

 Cache-Control: no-cache 

Если ответ, возвращаемый сервером, содержит no-cache Команда, каждый раз, когда клиент запрашивает, он должен сначала подтвердить свою действительность с сервером, если ресурс не изменился, он вернет 304.

Cache-Control: no-store 

Ресурс ответа не кэшируется, то есть при следующем запросе пользователя возвращается 200, а сам ресурс возвращается. 

Cache-Control: max-age=604800 (единица измерения: секунды)

Время, в течение которого ресурс кэшируется в локальном браузере. Если время превышено, он будет снова получен с сервера.

2.2 Поля заголовка запроса и поля заголовка ответа

2.2.1 Поля заголовка запроса


2.2.2 Поля заголовка ответа


Уведомление:

(1)If-None-Matchсоотношение приоритетовIf-Modified-Sinceвысокий, поэтому, когда оба существуют одновременно, следуйте первому.

4. Экспериментальная проверка

1. Эксперимент 1. Запрошенный ресурс не изменяется, проверяются два типа кешей.
использование сервера node.js, клиент используетaxios Сделать запрос:
1.1, настройки заголовка запроса/ответа
(1) Настройки заголовка ответа сервера:
     res.setHeader('Cache-Control', 'public, max-age=10');
(2) В заголовке запроса клиента используются настройки по умолчанию.

1.2 Экспериментальные этапы
(1) Запрос 3 раза, первый раз для запроса ресурса, второй раз для запроса ресурса в течение 10 секунд и третий раз для повторного запроса ресурса через 10 секунд (во время эксперимента ресурсы сервера не изменились)

1.3 Экспериментальные результаты
Информация HTTP трех запросов показана на рисунке ниже.Из информации на рисунке можно сделать вывод, что первый запрос на ресурс получен от сервера, второй (в течение 10 секунд) запрос на ресурс полученный непосредственно из кеша браузера Ресурс (без подтверждения серверу); когда ресурс запрашивается в третий раз (через 10 секунд), поскольку время кеша ресурса (10 секунд) истекает, ресурс получается с сервера, и сервер считает, что ресурс не изменился из локально кэшированного ресурса. , поэтому верните 304 и позвольте клиенту получить ресурс непосредственно из кэша браузера; ниже подробно описан процесс взаимодействия трех операций в соответствии с HTTP информация заголовка.


1.3.1. Запрос ресурсов в первый раз
Скриншоты заголовка запроса и заголовка ответа первого запроса на ресурс показаны ниже.Поскольку ресурс не кешируется локально в первый раз, ресурс получается напрямую с сервера, из скриншота видно, что сервер возвращает измененный заголовок ответа ресурса содержит 3 атрибута, связанных с кэшированием ресурса:
(1)cache-control: public, max-age=10
Настройки правила кэширования, в нашем примере, задайте для правила кэширования значениеpublic, и установите время истечения кэша на 10 секунд;
(2)etag: W/"95f15b-16994d7ebf6"
Уникальный идентификатор ресурса, который будет содержаться в заголовке запроса при следующем доступе клиента к ресурсу.etagПерейдите на сервер, чтобы подтвердить, был ли изменен ресурс;
(3)last-modified: Tue, 19 Mar 2019 07:26:12 GMT
Время последней модификации ресурса.Когда клиент обращается к ресурсу в следующий раз, он передаст информацию в заголовке запроса на сервер для сопоставления, был ли ресурс изменен;


1.3.2 Второй запрос ресурсов (в течение 10 секунд, то есть до истечения времени кэширования)
Скриншоты заголовка запроса и заголовка ответа второго запроса ресурса показаны ниже.Поскольку ресурс запрашивается во второй раз, локальный кеш ресурса не был инвалидирован, поэтому ресурс получается непосредственно из браузера. кеш.


1.3.3 Третий запрос ресурсов (через 10 секунд, то есть после истечения времени кэша)
Скриншоты заголовка запроса и заголовка ответа третьего ресурса запроса показаны ниже.Поскольку ресурс запрашивается в третий раз, локальный кеш ресурса был признан недействительным, поэтому он добавляется в заголовок запроса. If-Modified-Since иIf-None-Match свойство, чтобы проверить с сервером, был ли изменен ресурс.



2. Эксперимент 2. Измените запрошенные ресурсы, чтобы проверить наличие двух кэшей.
использование сервера node.js , клиент используетaxios Сделать запрос:
2.1, настройки заголовка запроса/ответа
(1) Настройки заголовка ответа сервера:
     res.setHeader('Cache-Control', 'public, max-age=20');
(2) В заголовке запроса клиента используются настройки по умолчанию.

2.2 Экспериментальные этапы
(1) Запросите 3 раза, первый раз для запроса ресурса, затем измените запрошенный ресурс на сервере, второй раз для запроса ресурса в течение 20 секунд и третий раз для повторного запроса ресурса через 20 секунд.

2.3 Экспериментальные результаты
Информация HTTP трех запросов показана на рисунке ниже.Из информации на рисунке можно сделать вывод, что первый запрос на ресурс получен от сервера, второй (в течение 20 секунд) запрос на ресурс получен непосредственно из кеша браузера Ресурс (без подтверждения серверу); когда ресурс запрашивается в третий раз (через 20 секунд), поскольку время кеша ресурса (20 секунд) истекает, ресурс получается с сервера, и сервер считает, что ресурс отличается от локально кэшированного ресурса, поэтому снова вернитесь к ресурсу; ниже подробно описан процесс взаимодействия трех операций в соответствии с информацией заголовка HTTP.


2.3.1. Запрос ресурсов в первый раз
Скриншоты заголовка запроса и заголовка ответа первого запроса ресурсов показаны ниже Конкретные детали такие же, как в разделе 1.3.1, и повторяются здесь.


2.3.2 Второй запрос ресурсов (в течение 20 секунд, то есть до истечения времени кэширования)
Скриншоты заголовка запроса и заголовка ответа второго ресурса запроса выглядят следующим образом (Примечание. Даже если ресурс на сервере изменился в это время, срок действия ресурса, кэшированного в браузере, не истек, поэтому он все равно возвращается из кеш.старый ресурс).


2.3.3 Третий запрос ресурсов (через 20 секунд, то есть после истечения времени кэша)
Скриншоты заголовка запроса и заголовка ответа третьего ресурса запроса показаны ниже.Поскольку ресурс запрашивается в третий раз, локальный кеш ресурса был признан недействительным, поэтому он добавляется в заголовок запроса. If-Modified-Since и If-None-Match атрибут, чтобы подтвердить серверу, был ли изменен ресурс, как видно из рисунка ниже, атрибут заголовка ответаetag с атрибутами заголовка запроса If-None-Matchразные, свойства заголовка ответа If-Modified-Since с атрибутами заголовка запросаlast-modified отличается; поэтому сервер возвращает последний ресурс для этого ресурса.


V. Резюме

1. Для обязательного кеширования сервер уведомляет браузер о времени кеша. В течение времени кеша следующий запрос будет использовать кеш напрямую. Если это не в пределах времени, политика кеша будет сравниваться.
2. Для кеша сравнения данные Etag и Last-Modified в кеше отправляются на сервер через запрос, и сервер проверяет его.Когда возвращается код состояния 304, браузер напрямую использует кеш.
Сводная блок-схема выглядит следующим образом:


Если у вас есть какие-либо вопросы, пожалуйста, оставьте сообщение для обсуждения, если вы считаете, что это полезно для вас, пожалуйста, поставьте лайк и поддержите ~