Веб-сервер

Программа, которая умеет отвечать на HTTP-запросы.

Время чтения: 10 мин

Кратко

Скопировано

Веб-сервер — это специальная программа, которая принимает запросы пользователей, обрабатывает их и отправляет ответ обратно по протоколу прикладного уровня HTTP.

Как понять

Скопировано

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

Веб-приложения — это набор текстовых файлов, которые пересылаются пользователю специальной программой — веб-сервером. Понятие веб-сервер появилось в 1991 году с появлением первой такой программы.

Веб-сервер работает по следующей схеме:

Схема работы веб-сервера

Сервер получает запросы от клиентов и отправляет им ответы. В основе работы веб-сервера лежит протокол HTTP.

Протокол HTTP

Скопировано

Протокол HTTP (HyperText Transfer Protocol — протокол передачи гипертекста) работает с текстовыми сообщениями, которые пересылаются от клиента к серверу (HTTP-запрос) и обратно (HTTP-ответ). Структура сообщения следующая:

  1. Стартовая строка (Starting line) говорит нам, запрос или ответ содержит сообщение;
  2. Заголовки (Headers) описывают тело сообщения, параметры передачи и прочие сведения;
  3. Тело сообщения (Message Body) содержит данные.

Стартовая строка

Скопировано

В стартовой строке запроса указывается метод, ссылка и версия протокола, разделённые пробелом, например:

        
          
          GET /tools/web-server HTTP/2.0
          GET /tools/web-server HTTP/2.0

        
        
          
        
      

Порядок важен:

  1. Метод запроса;
  2. Путь на сайте (тот, что указывается после доменного имени);
  3. Протокол, который используется.

Методы HTTP-запроса устанавливают назначение запроса. Среди наиболее используемых GET, POST и OPTIONS. Когда вы набираете адрес в адресной строке браузера и переходите по ссылке, обычно вы пользуетесь методом GET, то есть методом для получения запрашиваемой информации. POST часто используется для отправки данных из форм, а OPTIONS — для определения набора методов на сервере, доступных по адресу.

Адрес, который вы вводите в адресной строке браузера, в протоколе HTTP определяется как URI (Uniform Resource Identifier), то есть последовательность символов, идентифицирующая абстрактный или физический ресурс.

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

Стартовая строка HTTP-ответа содержит:

  1. информацию о версии протокола, как в запросе;
  2. код состояния (Status Code), который однозначно определяет реакцию сервера на запрос;
  3. пояснение (Reason Phrase) к коду ответа для пользователя (является необязательным).

Во время отладки веб-приложений вы часто будете встречать коды ответов 200, 404 и 500. Коды ответов, которые начинаются на 2xx, сервер возвращает, если запрос клиента был удачным. Запросы 4xx сообщают клиенту об ошибке, а 5xx — о том, что веб-сервер не справился с запросом клиента.

Заголовки

Скопировано

В заголовках содержится информация о домене, о сжатии, шифровании и формате данных, кодировке и прочая важная информация, которая используется для запроса или ответа. Каждый заголовок в HTTP-сообщении представляется отдельной строкой с параметром и значением, разделёнными двоеточием.

Пример заголовков запроса:

        
          
          Accept-Language: en-usAccept-Encoding: gzip, deflate, br
          Accept-Language: en-us
Accept-Encoding: gzip, deflate, br

        
        
          
        
      

Пример заголовков ответа:

        
          
          Content-Type: text/html; charset=UTF-8Content-Encoding: gzip
          Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip

        
        
          
        
      

Тело сообщения

Скопировано

В теле сообщения содержатся данные, которые требуется передать. Тело всегда отделяется от заголовков хотя бы одной пустой строкой. В теле, например, может передаваться HTML-документ или JSON с данными. Пример:

Запрос:

        
          
          GET /wiki/Web_server HTTP/1.1Host: en.wikipedia.org
          GET /wiki/Web_server HTTP/1.1
Host: en.wikipedia.org

        
        
          
        
      

Ответ:

        
          
          Date: Wed, 02 Jun 2021 00:41:41 GMTContent-Language: enLast-Modified: Tue, 25 May 2021 15:08:46 GMTContent-Type: text/html; charset=UTF-8Content-Encoding: gzip...Accept-Ranges: bytesContent-Length: 27606Connection: keep-alive<!DOCTYPE html><html class="client-nojs" lang="en" dir="ltr"><head><meta charset="UTF-8"><title>Web server - Wikipedia</title>...
          Date: Wed, 02 Jun 2021 00:41:41 GMT
Content-Language: en
Last-Modified: Tue, 25 May 2021 15:08:46 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
...
Accept-Ranges: bytes
Content-Length: 27606
Connection: keep-alive

<!DOCTYPE html>
<html class="client-nojs" lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Web server - Wikipedia</title>
...

        
        
          
        
      

Модули и расширения

Скопировано

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

Сжатие данных

Скопировано

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

В последние годы браузеры стали поддерживать ещё два формата: zopfli и brotli. Наиболее перспективным и эффективным является brotli, он поддерживается всеми современными браузерами.

С помощью сжатия можно оптимизировать загрузку страниц для текстовой части данных: HTML, CSS и JavaScript. Остальные ресурсы, как правило, уже подготовлены для загрузки в браузере. Например, для картинок должны быть найдены оптимальное соотношение визуального качества и степени сжатия, подходящие размеры и плотность пикселей.

Шифрование данных

Скопировано

При передаче данных пользователей важно их шифровать. Интернет построен так, что пакеты данных пользователей проходят множество сетевых узлов, прежде чем окажутся на целевом устройстве. Если данные не зашифрованы, то каждый из промежуточных узлов может просматривать их в открытом виде. Подробнее о безопасности использования Интернета написано в статье «Безопасность веб-приложений и распространённые атаки».

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

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

Подключение сертификата настраивается на стороне веб-сервера, поскольку владелец сайта должен позаботиться о своих пользователях.

Проксирование

Скопировано

Современные веб-серверы способны не только отправлять файлы по запросу пользователя, но и перенаправлять запросы клиентов другой программе. Например, можно передать данные другому веб-серверу, который будет специализироваться на определённом типе файлов, или программе-интерпретатору, которая будет исполнять код, получать нужные данные, отдавать их веб-серверу с целью передать их, в конечном счёте, клиенту. Само перенаправление запросов и ответов называется проксированием.

В статье «Виды веб-приложений» рассказывается о статических и динамических сайтах. Один из способов реализации динамического сайта — отдельная программа, которой веб-сервер передаёт HTTP-запрос. Программа обрабатывает запрос и формирует ответ, который отдаётся веб-серверу. Веб-сервер сформированный ответ передаёт клиенту.

Куки

Скопировано

Веб-сервер не только отдаёт данные. Например, можно получить доступ к кукам браузера пользователя со стороны веб-сервера. Это позволяет сохранять промежуточные данные, которые могут помочь улучшению пользовательского опыта. Существуют и проблемы такой модели, которые связаны с приватностью пользователей в Интернете и их безопасностью.

Аутентификация и авторизация

Скопировано

С помощью заголовков в HTTP-сообщениях можно осуществлять аутентификацию и авторизацию пользователей. В современных системах всё чаще применяют более сложные способы аутентификации и авторизации, а этот способ называют базовым (basic auth).

Для аутентификации пользователей нужно отдать веб-серверу учётные данные пользователя, то есть представиться и предъявить пару имени пользователя и пароля в качестве доказательства, что это тот самый пользователь.

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

Вы наверняка видели на сайтах аутентификацию через социальные сети или сторонний сервис. Аутентификация при этом происходит не на сервере, а на стороннем ресурсе. В результате аутентификации формируется токен, который передаётся серверу. После подтверждения личности, пользователю предоставляются определённые права (процедура авторизации), назначается специальный токен сессии, который также передаётся в заголовках вместе с запросами от клиента.

Пример заголовка для авторизации клиента на сервере:

        
          
          Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
          Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

        
        
          
        
      

При использовании кук на клиенте создаётся отдельная запись, в которой указывается уникальный токен сессии. Веб-сервер имеет доступ к этому токену, что позволяет всегда проверить факт авторизации.

Есть и другие способы аутентификации и авторизации, которые поддерживаются веб-сервером.

Кэширование

Скопировано

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

Веб-серверы могут обеспечить кэширование и на стороне клиента, чтобы снизить нагрузку на сеть. Для работы с кэшированием используются специальные заголовки. Например, сервер может передать заголовок клиенту:

        
          
          Cache-Control: public, max-age=31536000
          Cache-Control: public, max-age=31536000

        
        
          
        
      

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

На практике

Скопировано

Игорь Коровченко советует

Скопировано

Простой веб-сервер

Скопировано

Самый простой способ запустить веб-сервер, если уже уставлена платформа Node.js, использовать http-server. Достаточно установить этот веб-сервер глобально:

        
          
          npm install --global http-server
          npm install --global http-server

        
        
          
        
      

Теперь, нужно зайти в любую директорию, в которой находится собранный сайт или отдельный HTML-файл, и запустить веб-сервер командой:

        
          
          http-server
          http-server

        
        
          
        
      

В браузере вы можете видеть свой сайт по адресу http://localhost:8080 или http://127.0.0.1:8080. Это специальный адрес локального сервера на вашем компьютере.

Ваш локальный сервер не будет видно в интернете, но вы можете открыть его на устройствах, подключённых к одной и той же локальной сети, например, по Wi-Fi. Для этого нужно воспользоваться IP-адресом, который ваш роутер выдал компьютеру, на котором запущен сервер.

        
          
          Available on:  http://127.0.0.1:8080  http://192.168.1.56:8080
          Available on:
  http://127.0.0.1:8080
  http://192.168.1.56:8080

        
        
          
        
      

Первый адрес доступен только для компьютера с сервером, второй — для всех устройств сети.

Если надо больше

Скопировано

browser-sync удобно использовать и при разработке, и при тестировании проектов, потому что это избавляет разработчиков от необходимости повторять рутинные действия вручную на нескольких экранах или устройствах. При взаимодействии пользователя с сайтом на одном из устройств все действия будут немедленно воспроизводиться и на других устройствах. Например, если вы прокрутили страницу на смартфоне, она прокрутится и на других устройствах в сети. То же случится, если вы перейдёте на другую страницу сайта или будете взаимодействовать с формами.

browser-sync устанавливается глобально командой:

        
          
          npm install --global browser-sync
          npm install --global browser-sync

        
        
          
        
      

После установки необходимо перейти в директории, где находится сайт, и выполнить команду:

        
          
          browser-sync start --server
          browser-sync start --server

        
        
          
        
      

Но эти веб-серверы используются для локальной разработки. Сайты и сервисы используют веб-серверы, которые способны выдерживать большие нагрузки (большое количество запросов, сессий соединения, потоков данных и так далее) и модули для обработки различных запросов. О наиболее известных написаны статьи на сайте: