Когда клиентский браузер запрашивает файл с веб-сервера, я знаю, что выполняется какая-то проверка, потому что файлы, необходимые для обслуживания веб-страницы, могут уже быть кэшированы веб-браузером. Таким образом, если файл существует в кеше, файлы не отправляются. Но если файл на сервере изменился после того, как файл был кэширован в браузере, файл все равно будет отправлен и обновлен.
Затем, если на сервере включено сжатие, такое как gzip, файлы, которые должны быть предоставлены клиенту, должны быть сжаты с помощью gzip, что потребует некоторой обработки на стороне сервера.
Но как с этим справиться? Мне кажется логичным подходом, что на веб-сервере также должен быть кеш, содержащий новейшие версии всех файлов, которые были запрошены в течение определенного промежутка времени, то есть сжатую версию этих файлов, чтобы сжатие не приходилось выполняться каждый раз, когда запрашиваются файлы.
А также, как в конечном итоге запрашиваются файлы? Запрашивает ли браузер файлы каждый раз, когда он встречает один из них в HTML-коде, а конкретный файл не сохраняется в локальном кеше, или он суммирует все файлы, которые необходимы, и запрашивает всю группу одновременно?
Но это только предположение с точки зрения программирования, и я точно не знаю.
Если ответы разных систем веб-серверов сильно различаются, меня в первую очередь интересует Apache, но приветствуются и другие ответы.
Вы можете прочитать об этом в запредельных подробностях в Спецификация HTTP, но вот суть: когда браузеру нужно запросить файл, он сначала проверяет свой локальный кеш. Есть три основных возможности:
If-Modified-Since
заголовок, содержащий время последнего обращения к файлу.If-Modified-Since
заголовок, содержащий время последнего обращения к файлу.If-Modified-Since
заголовок.Когда запрос попадает на сервер, в основном может произойти пара вещей. Если запрос не включать If-Modified-Since
заголовок, сервер продолжит и отправит файл обратно, используя код ответа HTTP 200 (OK). (Или он отправит 404 File Not Found, или 403 Forbidden, или что-то еще). Но если запрос сделал включать If-Modified-Since
заголовок, сервер знает, что он должен отправить обратно файл только в том случае, если он был изменен с момента времени, указанного в заголовке. Теперь, если файл был изменен с того времени, сервер снова отправит файл с кодом 200 или 403, 404, как угодно. Но если в файле не был изменен с указанного времени - что, помните, означает, что кешированная версия браузера все еще актуальна - сервер может ответить кодом 304 (Not Modified) и пропустить содержимое самого файла. Это экономит некоторое количество сетевого трафика.
Теперь, предполагая, что сервер собирается ответить полным содержимым файла, есть несколько способов сделать это, в зависимости от того, как сервер написан и / или настроен. Очевидно, он может просто читать файл с диска (или запускать программу для его генерации, если это динамическая страница) каждый раз, когда приходит запрос, и просто отправлять его обратно, но, как вы знаете, это неэффективно. Одна вещь, которую может сделать сервер, - это отправить обратно сжатую версию файла, если браузер указывает Accept-Encoding: gzip
в своем запросе. Для сервера действительно имеет смысл хранить кэшированную версию gzip-файла, и Apache (и, вероятно, большинство других серверов) можно настроить для этого. Когда сервер готовится отправить ответ, сжатый с помощью gzip, он проверяет время модификации кэшированной с помощью gzip версии по времени изменения исходного файла, и, если исходный файл был обновлен, он снова запустит gzip для него и заменит файл старая версия в кеше с новой версией.
Иногда серверы также могут кэшировать файлы в ОЗУ, если они часто запрашиваются. Я думаю, что Apache можно настроить для этого, но я не уверен. (Как вы уже, наверное, догадались, в Apache все дело в конфигурации.)
Что касается вашего вопроса о том, как запрашиваются файлы, браузер действительно запрашивает файлы по одному. Каждая страница HTML, файл CSS, файл Javascript, файл изображения и т. Д. Соответствует одному индивидуальному HTTP-запросу. Инструмент вроде Wireshark может фактически показать вам отдельные HTTP-запросы и ответы, поступающие на ваш компьютер и с вашего компьютера, если вам интересно. Но для экономии ресурсов соединение TCP / IP обычно остается открытым в течение всего набора запросов. Так, например, если у вас есть веб-страница с 3 изображениями и таблицей стилей CSS, вы, вероятно, получите такую последовательность:
Connection: close
заголовокВ Connection: close
Заголовок может быть отправлен любой стороной, чтобы указать, что соединение TCP / IP должно быть закрыто после завершения этого запроса.
Надеюсь, это в основном касается того, о чем вы спрашивали, но спецификация HTTP - это ОГРОМНЫЙ документ, и есть много тонкостей, которые я упустил. На самом деле я нахожу это умеренно интересным чтением, поэтому я предлагаю вам взглянуть на него (опять же, я, вероятно, немного странный).