Опубликован: 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
Валерий Банатин
Валерий Банатин

function f() { var i=5; k=7; } f(); alert(k);

В примере выдается результат k=7, однако, хоть переменная и не объявлена, она внутри функции, т.е. локальная и не должна быть видима, или вторая и последующие все-таки становятся глобальными?

Дамир Кантюков
Дамир Кантюков

Изучаю курс введение в JavaScript. 4 уроке есть код, где метод присвоен переменной, почему у меня не работает, браузер гугл:

<HTML><HEAD> <SCRIPT> wid = window.open('','','width=750,height=100,status=yes'); wid.document.open(); R = wid.document.write; R('<HTML><HEAD><SCRIPT>var t;<\/SCRIPT></HEAD>'); R('<BODY><H1>Новое окно</H1></BODY></HTML>'); wid.document.close(); </SCRIPT> </HEAD> <BODY> <A HREF="javascript: wid.t=window.prompt('Новое состояние:',''); wid.document.write(wid.t); wid.focus(); void(0);" >Изменим значение переменной t в новом окне</A> </BODY></HTML>