Опубликован: 14.08.2003 | Уровень: для всех | Доступ: свободно
Лекция 8:

Программируем "за кадром"

< Лекция 7 || Лекция 8: 123
Аннотация: Рассматриваются приемы программирования на JavaScript, невидимые для читателей HTML-страниц: механизм cookie, управление фокусом, скрытая передача данных, вопросы безопасности.

Механизм cookie

Cookie являются механизмом управления обменом данных. Основная их функция - поддержка сеанса работы между клиентом (браузером) и сервером.

Что такое cookie

Формально, cookie (читается: куки ; не склоняется) - это небольшой фрагмент данных, которые веб-браузер пересылает веб-серверу в HTTP-запросе при каждой попытке открыть очередную страницу сайта. Обычно куки создаются веб-сервером и присылаются в браузер при первом запросе к сайту. Куки также могут быть созданы самой загруженной web-страницей, а именно имеющимся в ней скриптом JavaScript. Данные хранятся на компьютере пользователя в виде текстового файла, до тех пор, пока либо не закончится их срок, либо они будут удалены скриптом или пользователем. Имеются ограничения на объем и количество хранимых cookie, они зависят от браузера, но есть минимальные требования. Спецификация cookie описана в RFC 2965. На практике cookie обычно используются для:

  • аутентификации пользователя;
  • хранения персональных предпочтений и настроек пользователя;
  • отслеживания состояния сессии доступа пользователя;
  • ведения статистики о пользователях.

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

Главными атрибутами cookie являются: имя/значение куки, срок действия, путь, доменное имя, шифрование. Атрибуты записываются через точку с запятой. Обязательным является лишь имя/значение. Например:

customer=21584563; expires=Fri, 31-Dec-2010 23:59:59 GMT;
 path=/; domain=www.shop.ru; secure

Здесь customer - имя куки; 21584563 - значение куки; expires=... - срок действия куки; path=/ - путь, для которого действует эта куки (в данном случае куки действуют для любой страницы на данном сайте); domain=www.shop.ru - домен (сайт), для которого будет действовать эта куки; secure - использовать ли для передачи куки шифрованный канал (HTTPS). Если не указан expires, то куки действительна до закрытия браузера. Если не указаны path и domain, то куки действительна для текущей web-страницы. Удаляются куки путем указания истекшего срока действия (браузер сам сотрет такие куки по окончании своей работы).

Чтение cookie

Для работы с куки из сценария JavaScript используется свойство document.cookie. Следующая команда покажет все установленные куки:

alert(document.cookie);

Она выдаст нечто вроде: name1=value1; name2=value2; ..., т.е. перечисление пар имя=значение, разделенных точкой с запятой и пробелом. Как видите, нам показывают только имена и значения куки; другие атрибуты куки (срок действия, домен и т.д.) через свойство document.cookie недоступны.

Но обычно требуется больше - узнать, установлено ли значение конкретной куки, и если установлено, то прочитать его. Значит, нужно разобрать полученную выше строку с помощью методов работы со строковыми объектами. Для этого создадим две функции: existsCookie - проверяет, имеется ли куки с данным именем; CookieValue - возвращает значение куки по ее имени:

function existsCookie(CookieName)
{ // Узнает, имеется ли куки с данным именем
 return (document.cookie.split(CookieName+'=').length>1);
}

function CookieValue(CookieName)
{ // Выдает значение куки с данным именем
 var razrez = document.cookie.split(CookieName+'=');
 if(razrez.length>1)
 { // Значит, куки с этим именем существует
  var hvost = razrez[1],
       tzpt = hvost.indexOf(';'),
  EndOfValue = (tzpt>-1)? tzpt : hvost.length;
  return unescape(hvost.substring(0,EndOfValue));
}}

Мы воспользовались тем, что пары имя/значение разделены точкой с запятой, а значение куки не может содержать символ "точка с запятой" (" ; "). На самом деле, если произвести попытку установить куки со значением, содержащим этот символ, то в результате значение будет обрезано до первого вхождения этого символа. Попутно заметим, что в целях совместимости не рекомендуется использовать в значении куки символы: точка с запятой, пробел, равенство - если они все же требуются, их следует заменить на %3B, %20 и %3D, соответственно. Проще всего при создании куки пользоваться функцией escape(), которая и произведет все эти преобразования, а при чтении куки - обратной функцией unescape(), что мы и сделали выше.

Создание или изменение cookie

Далее мы хотим создавать или менять cookie. Разработчики языка JavaScript позаботились о web-программистах и реализовали свойство document.cookie довольно интеллектуально. Если выполнить простую команду присвоения:

document.cookie='ИмяКуки=Значение; expires=дата; path=путь; domain=домен; secure';

то прежние хранившиеся куки не будут стерты, как можно заподозрить. Вместо этого браузер проверит, не имеется ли уже в document.cookie куки с именем ИмяКуки. Если нет, то новая куки будет добавлена в document.cookie ; если да, то для куки с этим именем будут обновлены указанные в команде параметры (значение, срок действия и т.д.). Это поведение куки демонстрирует следующий пример:

document.write(document.cookie+'<BR>');
document.cookie = 'basket=SiemensA35';
   document.write(document.cookie+'<BR>');
document.cookie = 'customer=Ivanov';
   document.write(document.cookie+'<BR>');
document.cookie = 'basket=Nokia3310';
   document.write(document.cookie+'<BR>');

Напишем универсальную функцию для задания куки, которой Вы можете пользоваться на практике. Первые два ее аргумента ( name и value ) обязательны, остальные необязательны. В ней используется функция escape(), которая преобразует специальные символы в их коды, например, пробел в %20, равенство в %3D и т.д.

function setCookie(name, value, exp, pth, dmn, sec)
{ // Создает cookie с указанными параметрами
 document.cookie = name + '=' + escape(value)
 + ((exp)? '; expires=' + exp : '')
 + ((pth)? '; path='    + pth : '')
 + ((dmn)? '; domain='  + dmn : '')
 + ((sec)? '; secure'         : ''); }

Остается научиться передавать этой функции время истечения срока действия куки в правильном формате (пример см. выше). В этом нам поможет метод toGMTString() объекта Date. На практике заранее известно не время истечения срока действия куки, а сам срок действия (в днях, часах, минутах и т.д.), отсчитывая от текущего момента. Напишем функцию, которая по этим данным возвращает точный момент времени, причем в нужном нам формате:

function TimeAfter(d,h,m)
{ // Выдает время через d дней h часов m минут
 var now = new Date(),    // объект класса Data
   nowMS = now.getTime(), // в миллисекундах (мс)
   newMS = ((d*24 + h)*60 + m)*60*1000 + nowMS;
   now.setTime(newMS);    // новое время в мс
   return now.toGMTString(); }

Удаление cookie

Удалить куки - значит в качестве времени истечения куки указать какой-либо прошлый момент времени, например, "сутки назад". Напишем соответствующую функцию:

function deleteCookie(CookieName)
{ // Удаляет куки с данным именем
 setCookie(CookieName,'',TimeAfter(-1,0,0)); }

Демонстрационный пример

Теперь у нас есть весь арсенал функций работы с куки; сохраните их в единый файл cookies.js. Мы создадим две независимые web-страницы, которые благодаря куки смогут обменяться информацией. Первая страница запрашивает имя пользователя и записывает его в куки сроком на 1 минуту.

<SCRIPT SRC='cookies.js'></SCRIPT>
<SCRIPT>
setCookie('customername', 
          prompt('Введите ваше имя',''), 
          TimeAfter(0,0,1)  );
alert('Мы Вас запомнили!');
</SCRIPT>
8.1. Запись имени пользователя в cookie

Вторая страница приветствует пользователя по имени, которое она прочитает из cookie. Убедитесь, что она узнает пользователя, даже если перед открытием страницы закрыть браузер. Однако если открыть эту страницу через 1 минуту, то она уже не сможет узнать пользователя.

<SCRIPT SRC='cookies.js'></SCRIPT>
<SCRIPT>
if(existsCookie('customername'))
     alert('Приветствуем Вас, ' +CookieValue('customername')+ '!');
else alert('Извините, мы Вас уже не помним...')
</SCRIPT>
8.2. Чтение имени пользователя из cookie
< Лекция 7 || Лекция 8: 123
Валерий Банатин
Валерий Банатин
Видимость переменной
Дамир Кантюков
Дамир Кантюков
Не работают методы при обращении через переменную
Анатолий Федоров
Анатолий Федоров
Россия, Москва, Московский государственный университет им. М. В. Ломоносова, 1989
Ольга Ремез
Ольга Ремез
Латвия, Рига