2. Протокол HTTP – Курс PHP
Работа веб-сайта основана на клиент-серверной технологии, где браузер выполняет роль клиента, отправляющего запросы на сервер через сеть. Сервер представляет собой программное обеспечение, работающее на компьютере в сети Интернет и прослушивающее определенный порт. После получения запроса сервер отправляет обратно ответ, используя протокол TCP/IP в качестве транспортного протокола.
Здесь важно отметить, что термин “сервер” часто используется как для программного обеспечения, обрабатывающего запросы, так и для аппаратных серверов – мощных компьютеров, где это программное обеспечение работает. Обычно аппаратные серверы имеют специальные корпуса, чтобы их можно было удобно размещать в дата-центрах. В данном курсе термин “сервер” почти всегда относится к программному обеспечению.
Обмен информацией между браузером и сервером осуществляется по структурированной и понятной обеим сторонам информации. Правила и порядок этого обмена запросами и ответами определяются протоколом HTTP (HyperText Transfer Protocol, протокол передачи гипертекста). Данный протокол был разработан Тимом Бернерс-Ли, одним из основоположников Интернета, в 1989 году для передачи текстов, содержащих ссылки друг на друга. Это стало возможным благодаря языку разметки HTML, который включает инструменты для создания гиперссылок. Гиперссылки позволяют переходить от одной веб-страницы к другой, преодолевая границы сайтов и воспринимая Интернет как единую информационную сеть.
Протокол HTTP предназначен для запроса HTML-документов и сопутствующих файлов у сервера и передачи их браузеру. Часть Интернета, работающая по протоколу HTTP, называется Всемирной паутиной (World Wide Web, WWW). Разработка веб-приложений и программного обеспечения для WWW называется веб-программированием. В течение этого курса мы будем изучать именно эту область.
Протокол HTTP имеет ключевое значение для веб-программирования и, следовательно, для языка программирования PHP. Хотя большая часть HTTP-операций скрыта внутри PHP, в некоторых сложных случаях приходится напрямую работать с HTTP. Кроме того, хорошее понимание протокола HTTP помогает при изучении PHP и отладке сложных ошибок в веб-приложениях.
Зачем нужен протокол HTTP?
Протокол HTTP играет важную роль в передаче веб-страниц и связанных с ними документов от веб-сервера к браузеру. Когда я посещаю сайт и перехожу по ссылкам, я отправляю HTTP-запрос серверу. В ответ сервер отправляет HTTP-ответ, который часто содержит HTML-страницу. Эта страница содержит структурированный текст и ссылки на изображения, аудио и видео.
Для того чтобы браузер мог правильно отобразить страницу, он должен загрузить HTML-страницу и все сопутствующие ресурсы с сервера. Именно для этой цели служит протокол HTTP.
Протокол HTTP является клиент-серверным, так как на одной стороне находится клиент (браузер), а на другой – сервер. Я, в качестве клиента, отправляю HTTP-запросы, чтобы получить необходимый ресурс. Веб-сервер обрабатывает этот запрос и отправляет запрошенный ресурс в виде HTTP-ответа.
Обычно HTML-страница содержит ссылки на другие файлы, такие как таблицы стилей CSS, файлы JavaScript, изображения, видео и другие. Для загрузки каждого из этих файлов с сервера выполняется отдельный HTTP-запрос, на который веб-сервер отвечает, предоставляя нужный файл.
Ресурсы
Для формирования страницы, веб-браузер отправляет на сервер множество запросов с целью получения различных файлов. Чтобы идентифицировать каждый файл, протокол HTTP использует понятие ресурса, уникального идентификатора источника информации, например, изображения.
Каждый ресурс имеет свой адрес, который называется унифицированным указателем ресурса (URL). URL вводится в адресной строке браузера или используется в гиперссылках, позволяющих переходить с одной страницы на другую.
Вот пример URL-ссылки: https://zxkill.ru/wp-content/uploads/2023/07/cropped-2023-03-20-17.12.20-26×26.jpg
URL-ресурс состоит из следующих компонентов:
- https://: префикс, указывающий протокол обращения к ресурсу. В данном случае https – это протокол HTTP поверх SSL (безопасного шифрованного канала связи).
- zxkill.ru: доменное имя или IP-адрес, определяющий местоположение сервера с ресурсом в сети Интернет.
- /wp-content/uploads/2023/07/cropped-2023-03-20-17.12.20-26×26.jpg: путь к ресурсу на сервере, позволяющий различать один ресурс от другого.
Кроме статических файлов, ресурсами могут быть и динамические элементы. Например, ответ на запрос к поисковой системе формируется динамически, и вместо статического файла сервер отправляет браузеру HTML-страницу с актуальными результатами поиска. В таком случае ресурсом является не отдельный файл, а программное обеспечение, генерирующее ответ на лету. Это программное обеспечение может быть разработано на одном из языков программирования, например, PHP.
Предположим, мы хотим, чтобы запрашиваемый документ содержал текущую дату и время. Поскольку заранее указать их в документе невозможно из-за необходимости их актуализации при загрузке пользователем, мы можем написать программу на языке PHP, которая будет вычислять дату и время, вставлять их в документ и передавать его пользователю.
Однако в нашем механизме есть одно отсутствующее звено. Предположим, нам нужно, чтобы время на странице отображалось в соответствии с часовым поясом пользователя. Как программа на PHP сможет узнать часовой пояс региона, в котором находится пользователь? Вероятно, нам понадобится механизм, который позволит пользователю не только получать информацию, но и передавать ее серверу, например, часовой пояс.
Параметры URL
В предыдущем разделе был представлен упрощенный вариант URL, но на самом деле URL имеет более длинный формат. Он может включать дополнительную часть после вопросительного знака, называемую строкой параметров. Эта строка может содержать любую информацию, и ее длина может быть практически любой. Именно с помощью строки параметров можно передавать информацию от клиента к программе на сервере.
Пользователь может передать серверу свой часовой пояс следующим образом: https://zxkill.ru/script.php?time=+3
Сценарий с именем script.php
, который выполняется на сервере, может анализировать строку “time=+3”. Например, он может создать переменную $time
и присвоить ей значение +3, что означает смещение на 3 часа вперед. Параметры обычно задаются в формате переменная=значение
, и если нужно передать несколько параметров, они разделяются символом амперсанда (&). Например:
https://zxkill.ru/script.php?time=+5&name=Vasya
Обратите внимание, что параметры отделяются символом амперсанда (&). Это соглашение используется браузерами при обработке форм на веб-страницах.
Форма на веб-странице позволяет автоматизировать процесс передачи данных программе на сервере. Когда на странице присутствуют поля ввода и кнопка “Отправить”, данные из этих полей могут быть переданы на сервер. Серверная программа должна адекватно обработать эти параметры, провести разбор строки, создать переменные и выполнить необходимые действия.
Метод передачи параметров через URL, когда данные помещаются в командную строку URL, называется методом GET. Даже если не передаются параметры, метод GET все равно используется при загрузке статической страницы. Протокол HTTP поддерживает несколько методов передачи данных на сервер, и метод GET является одним из наиболее распространенных.
Методы
Запросы HTTP направляются на сервер с определенными командами, которые называются методами. Методы сообщают веб-серверу, какие действия следует выполнить в ответ на запрос. Вот некоторые из наиболее часто используемых методов HTTP:
- GET – запрос на получение ресурса, ответ может быть кеширован;
- POST – запрос на создание ресурса, ответ не кешируется;
- PUT – запрос на сохранение/обновление ресурса, ответ не кешируется;
- DELETE – запрос на удаление ресурса;
- HEAD – запрос на получение только HTTP-заголовков в ответе.
Не все методы поддерживаются браузерами.
HTTP-сообщения
Клиент и сервер обмениваются сообщениями по протоколу HTTP, которые состоят из трех основных частей:
- Начальная строка
- Заголовки HTTP
- Тело сообщения (необязательно)
Начальная строка и заголовки HTTP представляют собой текст, который может быть прочитан без необходимости декодирования. В теле сообщения могут содержаться бинарные или текстовые данные, в зависимости от типа ресурса, передаваемого в сообщении (например, изображение, видео или HTML-страница).
Примечание: Новый протокол HTTP/2 является бинарным, однако все современные браузеры декодируют его таким образом, что он остается легкочитаемым, аналогично протоколу HTTP 1.1.
Начальная строка запроса включает метод, ресурс на сервере и версию протокола HTTP, и имеет следующую структуру:
<Метод> <ресурс> <версия протокола HTTP>
Для примера, если мы хотим отправить запрос на корневую страницу сайта с использованием метода GET, начальная строка может выглядеть следующим образом: GET / HTTP/1.1
После указания метода следует путь (path) от корневой директории сайта до запрашиваемой страницы. Затем идет указание версии протокола: HTTP 1.1
.
Начальная строка ответа начинается с указания версии протокола HTTP, за которой следует код состояния ответа, например, 200 (успешное выполнение запроса). Структура начальной строки ответа выглядит следующим образом:
<версия протокола HTTP> <код состояния HTTP> <текстовое описание кода состояния HTTP>
Если запрос выполнен успешно, начальная строка ответа может иметь вид: HTTP/1.1 200 OK
Заголовки HTTP содержат различную мета-информацию, в то время как тело сообщения передает полезную нагрузку, такую как HTML-страница или изображение. Важно отметить, что тело сообщения может отсутствовать в случае большинства запросов, за исключением запросов POST и PUT. В ответах HTTP тело сообщения, как правило, присутствует, за исключением случаев, когда используется метод HEAD.
Для просмотра содержимого HTTP сообщений можно использовать developer tools в браузере(в Google Chrome, например, вызывается клавишей F12).
В этом инструменте отображаются отправленные клиентом HTTP запросы. Выбрав конкретный запрос, можно просмотреть заголовки запроса и ответа HTTP. На вкладке “Response” (Ответ) можно просмотреть содержимое HTTP документа.
HTTP-заголовки
Заголовки HTTP формируются в виде пар ключ-значение, разделенных двоеточием:
<название>: <значение>
В конце заголовка HTTP всегда используется последовательность CRLF (возврат каретки + перевод строки, \r\n), а не UNIX-перевод строки (\n).
Как было упомянуто ранее, существует большое количество заголовков HTTP – как с клиентской, так и с серверной стороны. В рамках этого курса мы не можем рассмотреть все заголовки HTTP подробно, так как это выходит за его рамки. Однако мы рассмотрим несколько наиболее распространенных заголовков HTTP, которые отправляются браузером серверу:
- Host: zxkill.ru – каждый клиент обязательно отправляет заголовок Host, в котором передается доменное имя сайта. Если сервер обслуживает несколько сайтов, он будет использовать этот заголовок для определения, к какому сайту относится запрос.
- Accept: text/html – этот заголовок сообщает серверу, что клиент предпочитает получить ответ в определенном формате, в данном случае – в виде HTML-страницы. Если сервер имеет несколько вариантов ответа на запрос, он выберет наиболее подходящий вариант. Если доступен только один вариант, сервер просто отправит его в ответе.
Мы рассмотрели несколько заголовков, которые отправляет браузер серверу. В ответ на такие запросы сервер отправляет заголовки в НТТР-сообщении:
- Content-Type: text/html – указывает на формат документа, который был отправлен. В данном случае это HTML-страница.
- Content-Length: 256715 – сообщает о размере загружаемого документа, позволяя браузеру оценить, насколько загружен документ.
- Server: nginx – информационный заголовок, указывающий на название веб-сервера, который обслуживает запрос.
Когда мы вводим строку “somestring” в браузере и нажимаем Enter, происходит немного больше, чем просто отправка запроса “somestring” на сервер. Браузер анализирует эту строку, извлекает из нее имя сервера, порт (и возможно имя протокола), устанавливает соединение с веб-сервером по указанному адресу (сервер:порт) и отправляет запрос, например, следующего вида:
GET somestring HTTP/1.0\r\n
key:value\r\n
keyl:value\r\n
\r\n\r\n
Здесь \r\n представляет собой символ перевода строки, а \r\n\r\n является маркером окончания заголовков запроса. Пока этот маркер не будет отправлен, сервер не начнет обрабатывать наш запрос.
После строки запроса могут следовать НТТР-заголовки, разделенные переводом строки. Некоторые заголовки предназначены для веб-сервера, чтобы помочь ему обработать запрос, например, заголовок Host, который указывает, к какому сайту адресован запрос. Однако не все заголовки обрабатываются сервером, некоторые передаются серверному скрипту РНР через переменные окружения.
Переменные окружения представляют собой именованные значения параметров, которые операционная система передает программе при ее запуске. С помощью специальных функций программа может получить значение любой установленной переменной окружения, указав ее имя. Точно так же серверная программа может получить значения заголовков запроса, используя переменные окружения.
К сожалению, некоторые заголовки нельзя получить из серверного скрипта, так как набор передаваемых переменных окружения ограничен стандартами. Такие случаи будем оговаривать особо.
Примечание: Для полноты картины стоит отметить, что системный администратор может настроить сервер таким образом, чтобы передавать серверной программе заголовки, которые обычно не передаются по стандарту.
Ниже приведены некоторые заголовки запросов с их описаниями, а также имена переменных окружения, используемые сервером для передачи их серверной программе.
- Content-Type
Формат:Content-Type: application/x-www-form-urlencoded
Переменная окружения:CONTENT_TYPE
Этот заголовок указывает тип передаваемых данных. Обычно в нем указывается значениеapplication/x-www-form-urlencoded
, которое определяет формат, в котором управляющие символы (отличные от алфавитно-цифровых и других отображаемых) кодируются специальным образом. Этот формат используется для передачи данных методами GET и POST. - Host
Формат:Host: имя_хоста
Переменная окружения:HTTP_HOST
Этот заголовок указывает имя хоста, к которому обращается браузер. В сети Интернет может быть несколько хостов на одном узле с разными доменными именами и одним IP-адресом. ЗаголовокHost
позволяет браузеру сообщить серверу, к какому хосту он хочет обратиться. - User-Agent
Формат:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0
Переменная окружения:HTTP_USER_AGENT
Этот заголовок содержит сведения о браузере и операционной системе, используемых клиентом. Однако такие сведения не всегда точны, так как множество роботов и программ маскируются под обычных пользователей. - Referer
Формат:Referer: URL_адрес
Переменная окружения:HTTP_REFERER
Через этот заголовок клиент передает серверу URL-адрес страницы, с которой был сделан текущий запрос. Это позволяет серверу узнать источник перехода, например, когда пользователь переходит по ссылке с одной страницы на другую. - Content-Length
Формат:Content-Length: длина
Переменная окружения:CONTENT_LENGTH
Этот заголовок содержит информацию о длине НТТР-тела, которое передается методом POST. Браузер использует эту информацию для правильного отображения процесса загрузки страницы или файла. - Cookie
Формат:Cookie: значения_cookies
Переменная окружения:HTTP_COOKIE
Заголовок содержит данные о куках (cookies), которые хранятся на компьютере пользователя и отправляются вместе с каждым запросом на сервер. Куки используются для сохранения состояния сессии, а также для хранения некоторой информации на клиентской стороне. - Accept
Формат:Accept: text/html, text/plain, image/gif, image/jpeg
Переменная окружения:HTTP_ACCEPT
В этом заголовке браузер перечисляет типы документов, которые он может обработать. Браузер указывает предпочтительные типы контента, и сервер может выбрать подходящий формат для ответа.
HTTP-коды ответов
Каждый ответ сервера сопровождается НТТР-кодом ответа. Эти коды являются трехзначными числами и начинаются с цифры от 1 до 5 (см. таблицу). С примером кода 200 мы уже встречались – это код успешно обработанного запроса. Однако есть и другие коды, например, код 201, который сообщает об успешном создании запрошенного ресурса, такого как комментарий или статья. Коды, начинающиеся с цифры 3, обозначают различные типы переадресации. Когда браузер получает такой код, вместе с ним приходит заголовок Location
, в котором указан адрес, на который нужно перейти для получения запрашиваемого ресурса.
HTTP-коды | Описание |
1xx | Информационные коды, сервер пребывает в процессе обработки запросов |
2xx | Коды успешного выполнения запроса |
3xx | Коды переадресации |
4xx | Коды ошибочного запроса со стороны клиента |
5xx | Коды ошибок на стороне сервера |
НТТР-код 301 сообщает о постоянной переадресации, в то время как код 302 указывает на временную переадресацию.
Коды, начинающиеся с цифры 4, сообщают о неверном запросе со стороны клиента. Например, если запрашиваемая страница отсутствует, сервер вернет код 404. Если доступ к странице закрыт, сервер вернет код 403. Некорректный запрос со стороны клиента, например, слишком длинный, может вызвать статус 400.
Коды, начинающиеся с цифры 5, указывают на ошибку на стороне сервера. Это может быть связано с его конфигурацией или с ошибками в коде программы. Если возникнет ошибка или исключение в программе на сервере, пользователю может быть показан ответ 500 со стороны сервера.
Утилита curl
Для исследования возможностей протокола HTTP, веб-разработчиками часто используется командная строковая утилита curl
. Это особенно удобно, когда требуется выполнить запросы типа POST, DELETE или PUT, которые не всегда удобно выполнять через браузер.
Для выполнения GET-запроса с помощью curl
достаточно просто указать команду “curl” и указать URL ресурса, который нужно загрузить. Например: curl https://zxkill.ru
Это пример запроса к главной странице сайта zxkill.ru, и в ответ будет получено содержимое HTML-страницы.
Если же нужно исследовать HTTP-заголовки, которые сервер присылает в ответ на запрос, можно добавить параметр -I
: curl -I https://zxkill.ru
В этом случае будет выполнен метод HEAD вместо GET, и в ответ вернутся только HTTP-заголовки без тела документа.
Чтобы передать на сервер собственный HTTP-заголовок, можно воспользоваться ключом -H
: curl -H 'Host: www.zxkill.ru' https://www.zxkill.ru/
А для выполнения POST-запроса с помощью curl
, требуется использовать параметр -X
для указания метода (в данном случае “POST”) и параметр -d
для передачи данных в теле запроса.
Приведу примеры:
- POST-запрос с параметрами в виде JSON-структуры:
curl -X POST -d '{"login": "admin", "password": "password"}' https://www.example.com/
- POST-запрос с параметрами в виде пар ключ-значение:
curl -X POST -d 'login=admin&password=password' https://www.example.com/
- Если нужно отправить файл на сервер, используется параметр
-F
, где указывается название поля, в котором сервер ожидает файл, и абсолютный путь к файлу на локальном компьютереcurl -X POST -F "file=@/path/to/file/image.jpg""https://www.example.com/"
curl
является мощным и широко используемым инструментом для выполнения HTTP-запросов из командной строки. Однако, существуют и другие инструменты для работы с HTTP-запросами, как в консольной среде, так и с графическим интерфейсом.
Некоторые из них:
wget
: Как вы уже упомянули,wget
– это еще один популярный консольный инструмент для загрузки файлов и рекурсивной загрузки целых веб-сайтов. Он поддерживает различные протоколы, включая HTTP и HTTPS.httpie
: Это еще один консольный инструмент, который обладает простым и интуитивным синтаксисом для выполнения HTTP-запросов. Он также поддерживает интерактивный режим, что делает его более удобным для пользователей, не знакомых с командной строкой.Postman
: Это графический инструмент для работы с API, который предоставляет удобный пользовательский интерфейс для создания, отправки и отладки HTTP-запросов. Postman позволяет сохранять запросы, организовывать их в коллекции, а также анализировать и отображать ответы от сервера.Insomnia
: Это еще один графический HTTP-клиент с подобными функциональными возможностями, как Postman. Он также позволяет создавать и отправлять запросы, сохранять и организовывать их, а также анализировать ответы от сервера.
Каждый из этих инструментов обладает своими уникальными особенностями и применяется в разных сценариях веб-разработки и тестирования API.
Резюме
На этом всё, мы получили базовое представление о протоколе HTTP и том, как он используется для взаимодействия с веб-сайтами. Поэкспериментуируйте немного с утилитой curl, либо программой Postman, попробуйте отправлять и получать заголовки, POST запросы, чтобы лучше понять работу протокола HTTP на практике.
Подписывайтесь на мой телеграмм канал, чтобы оперативно узнавать о выходе новых уроков и не только https://t.me/SamuraisGoal
Заходите в чат для обсуждений https://t.me/SamuraisGoalChat