Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос нашим менторам. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете
Протокол HTTP

HTTP 1.0

HTTP – текстовый протокол, с помощью которого взаимодействуют клиент, например, браузер и сервер. Работает это так. Пользователь шлёт определенный запрос на сервер, запрашивая или передавая нужные данные, а сервер, в зависимости от запроса, выполняет нужную логику и возвращает результат, обычно это HTML-страница либо редирект.

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

Для того, чтобы посмотреть, как работает HTTP, мы сделаем запрос к серверу google и разберём, как он выглядит. Для этого используется специальная утилита, которая называется telnet (пример HTTP-запроса, выполненного с помощью утилиты telnet).

# Передаем адрес сайта и указываем tcp порт
# После этого происходит подключение к серверу по протоколу tcp
$ telnet google.com 80

HTTP протокол прикладного уровня. Другими словами, он предназначен для общения между двумя программами (клиентом и сервером) находящимися на разных компьютерах. Но, сам по себе, HTTP не может соединять два удаленных компьютера, для этого используются другие протоколы среди которых TCP. Именно TCP позволяет соединить программы на удаленных компьютерах, создав канал для общения друг с другом. Для этого нужно знать два параметра: ip-адрес компьютера к которому нужно подключиться и порт на котором "висит" нужная программа.

Команда telnet выше, делает именно это, она выполняет соединение по TCP и только после этого входит в режим взаимодействия по HTTP. При условии что указан правильный ip-адрес и порт для соединения. И на этом моменте возникает два вопроса:

Мы передали адрес сайта, откуда берется ip-адрес? Любой адрес сайта это просто имя, за которым скрывается ip-адрес. Имя задано для удобства, так его проще запомнить. Однако все сетевые программы, среди которых браузеры и telnet, выполняют преобразование имени сайта в его ip-адрес. Делается это с помощью системы DNS, еще одного столпа интернета.

# Пример того как можно узнать ip-адрес с помощью утилиты ping
# В вашем случае адрес может быть другим, ip-адреса могут меняться
$ ping google.com # 74.125.21.139
# Затем можно использовать его для соединения с сервером
$ telnet 74.125.21.139 80

Почему порт имеет номер 80? Это общепринятое соглашение. Сайты доступные по HTTP доступны на порту 80, а по HTTPS – на порту 443. Именно поэтому в браузерах порты не указываются.

Теперь, когда мы установили соединение, то видим, что произошло соединение с веб-сервером, программой которая обслуживает http-запросы к google.com:

$ telnet google.com 80
Trying 74.125.21.139...
Connected to google.com.
Escape character is '^]'.

После подключения веб-сервер входит в режим ожидания http-запроса. Осталось его послать.

Что из себя представляет сам запрос?

HTTP запрос

Запрос состоит из нескольких частей. Первая часть — request line. Вторая — заголовки.

В request line мы указываем специальное слово, ещё говорят метод. В HTTP описаны разные методы, но мы сейчас не будем вдаваться в подробности. Просто скажем, что они определяют, как реагировать на этот запрос. И в данном случае мы будем использовать метод HEAD. Он очень простой, и просит только отдать данные. Более распространённым является GET. Именно с помощью GET мы запрашиваем сайт. Отличие HEAD от GET в том, что при HEAD возвращаются только заголовки без тела ответа (например, содержимого страницы).

После метода указывается строка запроса query string. Если мы указываем /, это обозначает просто корень сайта. Дальше всё, что нужно сделать, это указать название протокола и его версию. Сейчас активно используется версия 1.1, на подходе версия 2.0, но мы начнём с версии 1.0. Между ними есть принципиальные отличия, которые нужно хорошо знать и понимать. Версия 1.0 продолжает использоваться в различных целях различными утилитами. В принципе этого достаточно, и для 1.0 больше ничего делать не нужно:

HEAD / HTTP/1.0

Давайте рассмотрим, как выглядят заголовки. Мы указываем имя и через двоеточие какое-то значение: refer:value. Заголовки часто указывают заглавными буквами, но регистр здесь не важен. Порядок заголовков также не специфицирован. В каком бы порядке мы не передали заголовки, тело ответа будет разбираться только всё вместе.

Браузерами используется много заголовков, например user-agent. Этот заголовок используется для аналитики, а также, когда необходимо адаптировать страницы сайта под разные экраны или браузеры. Но и без него все должно работать:

HEAD / HTTP/1.0
User-Agent: google сhrome

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

Важно понять, поскольку это протокол, и у него есть определенные правила, то нарушать их нельзя. HTTP — текстовый протокол. Все правила основаны на простых соглашениях. Например, несколько заголовков отделяются друг от друга переводом строки (и никак иначе!). Мы не можем записать их в одну строку, через запятую или как-то ещё. Всё очень строго. А каким образом сервер поймёт, что вы закончили передавать данные? Это должен быть какой-то маркер, определитель. В HTTP это делается с помощью двух переводов строки. После этого сервер считает что все данные были отправлены и больше данных не будет. То есть фактически два перевода строки (перевод после последнего заголовка и пустая строка) приводят к отправке данных.

Что из себя представляет ответ?

HTTP ответ

Давайте сделаем запрос и посмотрим, что нам вернётся в ответ. Сделаем HEAD запрос и посмотрим, что будет возвращено:

$ telnet google.com 80
Trying 64.233.164.100...
Connected to google.com.
Escape character is '^]'.
HEAD / HTTP/1.0

HTTP/1.0 200 OK
Date: Sat, 18 Jan 2020 09:24:50 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: 1P_JAR=2020-01-18-09; expires=Mon, 17-Feb-2020 09:24:50 GMT; path=/; domain=.google.com; Secure
Set-Cookie: NID=196=wsHLMAMfnAaSyF7zduokI8TJeE5UoIKPHYC58HYH93VMnev9Nc2bAjhRdzoc4UhmuOd7ZVCorDnzGDe51yPefsRMeVyOFnYdHYYgQNqI8A1dYuk4pDK4OJurQgL4lX8kiNGSNi_kkUESFQ-MqLCB_YspxA9JRejhZdkTRtGyHNk; expires=Sun, 19-Jul-2020 09:24:50 GMT; path=/; domain=.google.com; HttpOnly
Accept-Ranges: none
Vary: Accept-Encoding

Connection closed by foreign host.

В ответ к нам приходит response. Он состоит из status line HTTP/1.0 200 OK. Это строка ответа, в которой указан протокол (здесь он совпадает) и статус ответа 200 OK. В HTTP определено множество различных статусов (400, 500 и т.д.). Они могут информировать, что информация была не найдена, были ошибки на сервере и т.д. Все статусы имеют мнемоническое название, которое передается так же последним значением. 200 и OK обозначает, что всё прошло хорошо — success!

Далее выводится большое количество различных заголовков. В них нет ничего сложного, и их не нужно все учить (есть какие-то общие, и они достаточно понятны). Все заголовки состоят из ключа, двоеточия и значения. Можно заметить, что есть вещи связанные с кодировкой, кешированием. Некоторые заголовки специфичны для текущего сервера. Например, X-XSS-Protection: 0, где X указывает на кастомный заголовок. Но никакой веб-сервер, никакой веб-браузер не будут ломаться при посылке таких дополнительных заголовков.

Именно в HTTP 1.0 в конце после получения данных происходит закрытие соединения.

В конце мы видим одну интересную деталь: Connection closed by foreign host. Запрос соединения был закрыт внешним хостом. Так работает практически всё в интернете. Обычно сервера настроены на 30-секундный интервал и закрывают соединение, если в течении этого интервала ничего не приходит.

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


Дополнительные материалы

  1. DNS

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят менторы из команды Хекслета или другие студенты.

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, даст возможность обращаться за помощью к менторам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».