Страница 2 из 7 Общее представление об HTTP Для того чтобы хорошо понять проблему сохранения состояния, а также выбрать наилучшее для ваших нужд решение, важно немного разобраться в лежащей в основе web'а архитектуре — протоколе передачи гипертекста (HTTP). Визит на https://www.example.org/ требует от web-браузера послать HTTP-запрос к www.example.org на порт 80. Синтаксис запроса подобен следующему: GET / HTTP/1.1 Host: www.example.org Первая строка называется строкой-запросом, а второй параметр в ней (слеш в нашем примере) — это путь к запрашиваемому ресурсу. Слеш обозначает корень дерева документов; web-сервер преобразовывает его в конкретный путь в файловой системе. Пользователи Apache'а могут быть знакомы с указанием этого пути директивой DocumentRoot. Если запрашивается https://www.example.org/path/to/script.php, то заданным в запросе путём к ресурсу является /path/to/script.php. Если корень дерева документов определён как /usr/local/apache/htdocs, то полный путь к ресурсу, используемый web-сервером, — /usr/local/apache/htdocs/path/to/script.php. Вторая строка иллюстрирует синтаксис HTTP-заголовка. В нашем случае это заголовок Host; он определяет доменное имя хоста, с которого браузер запрашивает ресурс. Этот заголовок согласно протоколу HTTP/1.1 является обязательным и помогает обеспечивать механизм поддержки виртуального хостинга — множества доменов, обслуживаемых с единственного IP-адреса (часто — единственным сервером). Существует много других (необязательных) заголовков, которые могут быть включены в запрос; вам может быть знакомо обращением к ним в вашем PHP-коде, например, $_SERVER['HTTP_REFERER'] и $_SERVER['HTTP_USER_AGENT']. Обратите особое внимание, что в запросе-примере нет ничего, что может использоваться для однозначного распознавания клиента. Некоторые разработчики прибегают к информации, полученной от TCP/IP (такой, например, как IP-адрес) для уникальной идентификации, но этот подход сопряжён с множеством трудностей. Наибольшая из них — один пользователь потенциально может использовать различные IP-адреса для каждого запроса (как это происходит с пользователями AOLа), а разные пользователи могут использовать одни и те же IP-адреса (как в случае использования во многих компьютерных лабораториях HTTP-прокси). Эти ситуации могут послужить причиной того, что единственный пользователь может выглядеть как множество, или множество пользователей — как один. Для сколько-нибудь надёжного и безопасного метода обеспечения состояния может использоваться только информация, полученная из HTTP. Первый шаг в задаче сохранения состояния — как-то однозначно идентифицировать каждого клиента. Так как единственная надёжная информация, которая может быть для этого использована, должна приходить из HTTP-запроса, что-то должно быть в самом запросе, что может использоваться для такой идентификации. Есть несколько путей реализации этого, но решением, разработанным именно для этой проблемы, являются куки. Куки Понимание того, что должен существовать метод однозначной идентификации клиентов, привёл к творческому решению проблемы — созданию кук. Куки легче всего понять, если вы примете во внимание, что они являются расширением HTTP-протокола, который и определяет точно, что же это такое. Куки определяются в RFC 2965, хотя первоначальная спецификация, написанная в Netscape wp.netscape.com/newsref/std/cookie_spec.html, более близка к поддерживаемой индустрией. Существует два HTTP-заголовка, которые необходимы для реализации механизма кук, — Set-Cookie и Cookie. Web-сервер включает заголовок Set-Cookie в ответ на запрос для того, чтобы браузер включал эту куку в последующие запросы. Браузер, в котором разрешены куки, включает заголовок Cookie во все последующие запросы (которые удовлетворяют условиям, определённым в заголовке Set-Cookie), пока кука не устареет (пока не истечёт её срок). Типичный сценарий состоит из двух транзакций (четырёх HTTP-сообщений): - Клиент шлёт HTTP-запрос.
- Сервер шлёт HTTP-ответ, включающий заголовок Set-Cookie.
- Клиент шлёт HTTP-запрос, включающий заголовок Cookie.
- Сервер шлёт HTTP-ответ.
Добавление заголовка Cookie во втором запросе клиента (пункт 3) предоставляет информацию, которую сервер может использовать для однозначной идентификации клиента. Так же в этот момент сервер (или PHP-скрипт на стороне сервера) может определить, разрешены ли у пользователя куки. Хотя пользователь может предпочесть запрет кук, достаточно безопасно будет предположить, что настройки пользователя не изменяются во время взаимодействия с вашим приложением. Этот факт, как вскоре будет продемонстрировано, может оказаться очень полезным. |