Андрей
А.Аликберов
Откуда возник термин "cookie"
никто достоверно не знает, хотя
считается, что во времена
зарождения Unix-систем
где-то использовалось
словосочетание Magic Cookies. Имелись в
виду "квитанции" (token, ticket),
которыми обменивались программы.
Cookie является решением одной из
наследственных проблем HTTP
протокола (HyperText Transfer Protocol).
Эта проблема заключается в
непостоянстве соединения между
клиентом и сервером, как при FTP
или Telnet сессии, т.е. для каждого
документа (или файла) при передаче
по HTTP протоколу посылается
отдельный запрос. Включение cookie в
HTTP протокол дало частичное решение
этой проблемы. Иначе говоря,
транзакция завершается после того,
как браузер сделал запрос, а сервер
выдал соответствующий ответ. Сразу
после этого сервер "забывает"
о пользователе и каждый следующий
запрос того же пользователя
считает новым пользователем.
Используя cookie, можно
эмулировать сессию по HTTP протоколу.
Коротко принцип эмуляции сессии
таков: на первом запросе выдается
соотвествующее значение cookie, а при
каждом последующем запросе это
значение читается из переменной
окружения HTTP_COOKIE и соответствующим
образом обрабатывается.
Простой пример: есть форма, где
пользователю предлагается указать
свое имя, из нее вызывается скрипт,
прописывающий значение cookie в
браузер пользователя. При каждом
последующем заходе на основе
анализа значения cookie из браузера
пользователя на странице
появляется либо именное
приветствие (если есть
установленное значение cookie), либо
первоначальная форма с запросом
имени пользователя (если значение
cookie не установлено).
Cookie - это небольшая порция
текстовой информации, которую
сервер передает браузеру. Браузер
будет хранить эту информацию и
передавать ее серверу с каждым
запросом как часть HTTP заголовка.
Одни значения cookie могут храниться
только в течение одной сессии, они
удаляются после закрытия броузера.
Другие, установленные на некоторый
период времени, записываются в
файл. Обычно этот файл называется
'cookies.txt' и лежит в рабочей
директории установленного на
компьютер браузера. У меня, к
примеру, в этом файле содержится
следующее:
# Netscape HTTP Cookie File
# http://www.netscape.com/newsref/std/cookie_spec.html
# This is a generated file! Do not edit.
www.webclub.ru FALSE /ourweb FALSE 946683907 1 1
.bizlink.ru TRUE / FALSE 915148488 u_irads_watch 627633
.doubleclick.net TRUE / FALSE 1920499140 id 332666ae
.yahoo.com TRUE / FALSE 915144943 Y v=1&n=6jm0u5lgubh1k&l=0b8a0d3h/o&p=m29vvru7130a
.yahoo.com TRUE / FALSE 915144943 T z=3587c277
mail.yahoo.com TRUE / FALSE 943919791 YM.Login id%3d%241%24rm%24L6MDTCsrCNnk3syLZl2zo.%26sid%3dszxPh4SazGg/%250a%26ts%3dX%2588%25c3%2506%25d3%25e5I-%255d%253f%2597%25ddu
.preferences.com TRUE / FALSE 1182140165 PreferencesID 3AGN9WD1D80gQfjvjAxRuq
.geocities.com TRUE / FALSE 900743217 iTag gY6bZzWItDQAAWll3T8ASk1vbiwgMTMg
search.netscape.com FALSE / FALSE 942189477 NGUserID cfc84d2a-522-898178454-1
www.webclub.ru FALSE FALSE 913543999 visited yes
Как видно, у меня оставили cookie Российский клуб
вебмастеров, поисковая
система AltaVista,
бесплатный почтовый сервер Yahoo, Netscape Communications,
рекламные сети DoubleClick и
отечественная InterReklama. В
настоящее время большинство
браузеров поддерживает механизм
cookies. Я точно знаю, что cookie можно
использовать во всех версиях Netscape
Navigator, Microsoft Internet Explorer и NCSA Mosaic.
Что можно делать с помощью cookie?
Сами по себе cookies не могут делать
ничего, это только лишь некоторая
текстовая информация. Однако
сервер может считывать
содержащуюся в cookies информацию и на
основании ее анализа совершать те
или иные действия. Например, в
случае авторизованного доступа к
чему либо через WWW в cookies
сохраняется login и password в течение
сессии, что позволяет пользователю
не вводить их снова при запросах
каждого документа, защищенного
паролем.
На использовании cookies также
часто строят функции оформления
заказов в онлайновых магазинах, в
частности, в самом крупном
виртуальном книжном магазине Amazon Books
реализована своеобразная
виртуальная корзина покупателя,
как в обычном реальном
супермаркете, в которую сервер
записывает информацию обо всех
заказанных книгах. Пользователь
просто помечает интересующие его
книги, а затем оформляет покупку
сразу всех отмеченных книг.
Еще одна распространенная
область использования cookies - при
настройке индивидуального профиля
каждого зарегистрированного
пользователя.
И, наконец, самая последняя
область - использование механизма
cookie в рекламном бизнесе на
Интернет. Еще год назад реклама в
Интернет за деньги была довольно
экзотической услугой, а сейчас этот
бизнес уже устоялся и стремительно
развивается. Однако рекламодатели
начинают предъявлять более жесткие
условия к оценке эффективности
своих расходов. Cookie используются
для таргетинга рекламы
(определения целевой аудитории,
например, по географическому
положению пользователей),
отслеживания интересов
пользователей, учета количества
показов и проходов сквозь баннеры.
Работа с cookie
Теперь, когда с принципами действия
и областями применения cookie все
более или менее понятно, можно
приступить к изучению формата и
синтаксиса, а также способов
задания значений cookie.
Формат и синтаксис cookie
Предлагаемое мной в этой статье
описание формата и синтаксиса cookie
является вольным пересказом
изначальной спецификации Netscape
Communications "Persistent
Client State HTTP Cookies". В настоящий
момент идет разработка более
строгой спецификации для cookie. Итак,
cookie является частью HTTP заголовка.
Полное описание поля Set-Cookie HTTP
заголовка:
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
Минимальное описание поля Set-Cookie
HTTP заголовка:
Set-Cookie: NAME=VALUE;
NAME=VALUE - строка символов,
исключая перевод строки, запятые и
пробелы. NAME-имя cookie, VALUE - значение.
Не допускается использование
двоеточия, запятой и пробела.
expires=DATE - время хранения cookie,
т.е. вместо DATE должна стоять дата в
формате "expires=Monday, DD-Mon-YYYY HH:MM:SS
GMT", после которой истекает время
хранения cookie. Если этот атрибут не
указан, то cookie хранится в течение
одного сеанса, до закрытия
броузера.
domain=DOMAIN_NAME - домен, для
которого значение cookie
действительно. Например,
"domain=cit-forum.com". В этом случае
значение cookie будет действительно и
для домена cit-forum.com, и для www.cit-forum.com.
Но не радуйтесь, указания двух
последних периодов доменных имен
хватает только для доменов
иерархии "COM", "EDU",
"NET", "ORG", "GOV",
"MIL" и "INT". Для обсуждаемых
сейчас новых семи доменов первого
уровня ("FIRM", "SHOP",
"WEB", "ARTS", "REC",
"INFO", "NOM"), вероятно, это
условие сохранится. Для доменов
иерархии "RU", например,
придется указывать три периода.
Если этот атрибут опущен, то по
умолчанию используется доменное
имя сервера, на котором было задано
значение cookie.
path=PATH - этот атрибут
устанавливает подмножество
документов, для которых
действительно значение cookie.
Например, указание "path=/win"
приведет к тому, что значение cookie
будет действительно для множества
документов в директории /win/, в
директории /wings/ и файлов в текущей
директории с именами типа wind.html и
windows.shtml. Для того, чтобы cookie
отсылались при каждом запросе к
серверу, необходимо указать
корневой каталог сервера, например,
"path=/".
Если этот атрибут не указан, то
значение cookie распространяется
только на документы в той же
директории, что и документ, в
котором было установлено значение
cookie.
secure - если стоит этот маркер,
то информация cookie пересылается
только через HTTPS (HTTP с
использованием SSL - Secure Socket Level), в
защищенном режиме. Если этот маркер
не указан, то информация
пересылается обычным способом.
Синтаксис HTTP заголовка для поля
Cookie
Когда запрашивается документ с HTTP
сервера, браузер проверяет свои cookie
на предмет соответствия домену
сервера и прочей информации. В
случае, если найдены
удовлетворяющие всем условиям
значения cookie, броузер посылает их в
серверу в виде пары имя/значение:
Cookie: NAME1=OPAQUE_STRING1; NAME2=OPAQUE_STRING2 ...
Дополнительные сведения
Одновременно можно задавать
несколько значений cookie.
В случае, если cookie принимает новое
значение при имеющемся уже в
браузере cookie с совпадающими
параметрами NAME, domain и path, то старое
значение заменяется новым. В
остальных случаях новые значения
cookie добавляются к старым.
Использование expires не гарантирует
сохранность cookie в течение
заданного периода времени,
поскольку клиент (браузер) может
удалить запись из-за нехватки
выделенного места или каких-либо
других причин.
Клиент (браузер) имеет следующие
ограничения для cookies:
всего может храниться до 300
значений cookies
каждый cookie не может превышать
4Кбайт
с одного сервера или домена
может храниться до 20 значений
cookie
Если ограничение 300 или 20
превышается, то удаляется первая по
времени запись. При превышении
лимита объема в 4Кбайт корректность
значения cookie страдает - отрезается
кусок записи (с начала этой записи)
равный превышению объема.
В случае кэширования документов,
например, proxy-сервером, поле Set-cookie
HTTP заголовка никогда не кэшируется.
Если proxy-сервер принимает ответ,
содержащий поле Set-cookie в заголовке,
предполагается, что поле доходит до
клиента вне зависимости от кода
возврата 304 (Not Modified) или 200 (OK).
Соответственно, если клиентский
запрос содержит в заголовке Cookie, то
он должен дойти до сервера, даже
если жестко установлен параметр
If-modified-since.
Ниже приведено несколько
примеров, иллюстрирующих
использование cookies
Пример 1. Управление
подмножеством документов, для
которых действительны значения
cookie, и их сроком годности
Браузер запрашивает документ и
принимает от сервера в ответ:
Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
Когда браузер запрашивает URL с
путем "/" на этом сервере, он
посылает серверу:
Cookie: CUSTOMER=WILE_E_COYOTE
Браузер запрашивает документ и
принимает от сервера в ответ:
Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
Когда браузер запрашивает URL с
путем "/" на этом сервере, он
посылает серверу уже два значения
cookie:
Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
Сервер установил еще одно
значение cookie, на этот раз с другой
областью действия:
Set-Cookie: SHIPPING=FEDEX; path=/foo
Теперь браузер, запрашивая URL с
путем "/" на этом сервере,
посылает лишь два значения cookie:
Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
и лишь при запросе браузером
документов с путем "/foo" на этом
сервере посылаются все три
значения cookie:
Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
Комментарий: после закрытия
браузера в файле 'cookies.txt' останется
только одно значение cookie:
CUSTOMER=WILE_E_COYOTE
поскольку только для него
установлен срок годности - 9 ноября
1999 года. Все остальные значения не
будут сохранены.
Пример 2. Значения cookie с
одинаковыми именами, но разными
параметрами
Браузер запрашивает документ и
принимает ответ от сервера:
Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
Когда браузер запрашивает URL с
путем "/" на этом сервере, он
посылает значение:
Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
Во второй раз, запрашивая
документ, браузер принимает от
сервера значение cookie с другой
областью действия:
Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
Когда браузер запрашивает URL с
путем "/ammo" на этом сервере, он
посылает значение:
Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
Комментарий: здесь мы имеем
две пары имя/значение с одинаковым
именем "PART_NUMBER". При закрытии
браузера ни одно из этих значений
не сохранится, поскольку не задан
параметр expires.
Способы задания значений cookie
Способ задания значений cookie
зависит того, как эти значения
будут использоваться и какие
имеются серверные ресурсы. Можно
манипулировать временем жизни
выставленных cookie и устанавливать
подмножества URL (Universal Resource Locator), в
которых заданные значения
действительны. Есть несколько
способов задания, наиболее часто
используются три - через META-таги
языка HTML, JavaScript и CGI-скрипты. Любым
способом можно задавать как одно,
так и несколько значений сразу.
Сразу хочу предупредить - не
забывайте об ограничениях по
объему и количеству значений cookie, а
также параметре domain, так как помимо
основного доменного имени узла
часто бывает несколько алиасов
(alias).
1. Задание cookie с помощью META-тагов
Простейший способ выставить cookie -
использовать соответствующий
META-таг в контейнере <HEAD>...</HEAD>
любого статического HTML документа. В
общем случае это выглядит
следующим образом:
<META HTTP-EQUIV="Set-Cookie" CONTENT="NAME=value; EXPIRES=date; DOMAIN=domain_name; PATH=path; SECURE">
Такой способ задания cookie, на мой
взгляд, наиболее интересен для
создателей маленьких домашних
страничек, когда нет возможности
писать свои собственные CGI-скрипты.
А если есть поддержка SSI
(Server Side Include) или PHP/Fi,
то можно делать интерактивные
страницы вообще без использования
внешних CGI-скриптов. При наличии SSI
на узле создание интерактивности с
использованием механизма cookie
становится просто удовольствием.
С помощью <META HTTP-EQUIV="Set-Cookie"
CONTENT="..."> cookie задается на
любой статичной странице,
директивой <!--#echo var="..."-->
можно потом считать любые
переменные окружения, в том числе и
ранее заданные значения cookie
(переменная HTTP_COOKIE), а с помощью
конструкций <!--#if expr="..." -->,
<!--#elif expr="..." --> и <!--#else -->
задавать различные варианты
внешнего вида страниц. Так же
просто можно проделывать подобные
вещи, используя PHP/Fi.
Если же ни SSI, ни PHP/Fi недоступен, то
можно задавать значение cookie,
используя JavaScript.
2. Задание cookie с помощью JavaScript
Можно задавать значение cookie,
используя язык JavaScript.
Единственный недостаток этого
способа заключается в том, что не
все браузеры его поддерживают. Ниже
приведены примеры функций JavaScript,
написанные Алексеем
Александровым для скрипта
"Органайзер". Этот скрипт,
по-моему, один из лучших образцов
программирования на JavaScript с
использованием cookie, поэтому я
настоятельно рекомендую
посмотреть на работающий образец
по адресу http://www.citforum.ru/internet/javascript/exorg.shtml
Пример 3. Функция установки
значения cookie
// name - имя cookie
// value - значение cookie
// [expires] - дата окончания действия cookie (по умолчанию - до конца сессии)
// [path] - путь, для которого cookie действительно (по умолчанию - документ, в котором значение было установлено)
// [domain] - домен, для которого cookie действительно (по умолчанию - домен, в котором значение было установлено)
// [secure] - логическое значение, показывающее требуется ли защищенная передача значения cookie
function setCookie(name, value, expires, path, domain, secure) {
var curCookie = name + "=" + escape(value) +
((expires) ? "; expires=" + expires.toGMTString() : "") +
((path) ? "; path=" + path : "") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "")
if (!caution || (name + "=" + escape(value)).length
|