Когда я ввожу URL-адрес сайта в адресную строку браузера, браузер отправляет запрос на получение ресурса по URL-адресу. Но когда я захожу на разные веб-сайты (google.com, amazon.com и т. Д.), Запросы, инициализирующие страницу, имеют разные заголовки для разных сайтов.

Где браузер получает набор заголовков запроса для загрузки страницы, если браузер имеет только информацию об URL-адресе этого ресурса при первой инициализации?

Например, когда я захожу на google.com, браузер отправляет такие заголовки запросов:

:authority: www.google.com
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7
cache-control: max-age=0
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36

Для amazon.com заголовки запроса разные:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7
Connection: keep-alive
Host: amazon.com
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
1
Denys Koval 15 Июн 2020 в 00:23

1 ответ

Лучший ответ

Когда вы вводите URL-адрес в адресную строку, его необходимо преобразовать в HTTP-запрос.

Таким образом, ввод www.google.com означает, что вам нужно GET открыть страницу по умолчанию (/) с этого сервера. Это в основном все, что описано в первых 4 строках первого запроса.

Браузер также знает, какие типы форматирования он может accept. В основном мы доставляем обратно HTML, поэтому text/html определенно присутствует, но мы также принимаем и другие форматы, включая полностью общий */*, кстати! :-)

Запросы часто сжимаются (с использованием формата gzip, deflate или более нового формата brotli (br)), поэтому браузер сообщает серверу, какой из них он поддерживает, в заголовке accept-encoding. .

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

Затем есть несколько заголовков безопасности (я не буду вдаваться в подробности).

Наконец, у нас есть заголовок user-agent. в основном здесь браузер сообщает серверу, что это Chrome, Firefox или что-то еще. Но по историческим причинам он намного длиннее, чем просто «Chrome».

Таким образом, в основном заголовки запросов - это то, что браузер отправляет на сервер, чтобы предоставить ему дополнительную информацию о браузере и его возможностях. Для запроса, который только что введен в браузер, заголовки запроса будут в основном одинаковыми, независимо от того, какой URL-адрес. Для дополнительных запросов, сделанных страницей - например, по коду JavaScript они могут отличаться, если он добавляет больше заголовков.

Что касается различий между двумя приведенными вами примерами запросов:

Google использует HTTP / 2 (или QUIC, если используется Chrome, но пока это в основном HTTP / 2, что касается этого вопроса). вы можете увидеть это, если добавите столбец с опциями «Протокол» в инструменты разработчика.

HTTP / 2 имеет несколько отличий от HTTP / 1, а именно:

  • Имена заголовков HTTP в нижнем регистре. Технически в HTTP / 1 они нечувствительны к регистру, но по соглашению многие инструменты, такие как браузер, используют регистр заголовков (заглавная буква каждого слова).
  • Запрос (например, GET / HTTP/1.1) преобразуется в псевдозаголовки, начинающиеся с двоеточия (:method: GET, :path: / ... и т. Д.).
  • Host - это в основном :authority в HTTP / 2.
  • :scheme в основном новинка в HTTP / 2, поскольку раньше она не была явно частью HTTP-запроса и обрабатывалась на уровне соединения.
  • Connection не работает в HTTP / 2. Даже в HTTP / 1.1 по умолчанию используется keep-alive, поэтому указанный заголовок не нужен, но многие браузеры и другие клиенты отправляли его по историческим причинам.

Думаю, это объясняет все различия.

Итак, как браузер узнает, использовать ли HTTP / 2 или HTTP / 1.1? Какой уже имеет ответ на Stack Overflow, но в основном это решается, когда устанавливается сеанс HTTPS, если сервер сообщает, что он может поддерживать HTTP / 2, и браузер хочет его использовать.

0
Barry Pollard 15 Июн 2020 в 14:58