Работа с атрибутами элементов

Метод createAttribute()

Метод setAttribute()

Метод removeAttribute()

Метод getAttribute()

Дополнительные методы в Internet Explorer 5

Все атрибуты узла-элемента (за исключением атрибута STYLE) составляют коллекцию attributes. W3C определяет эту коллекцию как массив с доступом по именам элементов, напрмер, oNode.attributes.align или oNode.attributes["align"] возвращает значение атрибута ALIGN узла oNode. Имя атрибута надо набирать прописными буквами вне зависимости от того, в каком регистре они набраны в HTML-источнике. Свойство nodeName для узлов-атрибутов возвращает название атрибута, а nodeValue - значение атрибута. Свойство атрибутов specified позволяет узнать, определен или нет этот атрибут. Если, например, у узла oNode атрибут ALIGN определен, то oNode.attributes["align"].specified возвращает true, а если не определен, то false.

Метод setAttribute()

Атрибуты как новых элементов, так и тех, что заданы через HTML, можно задать либо традиционным способом - присваивая значение свойству (атрибуту) узла, либо с помощью методаsetAttribute(). Оба способа демонстрируются ниже для атрибутаID. Так, любая из строк кода

oNode.id= "newItem"

oNode.setAttribute("id","newItem")

задает для элементаoNodeв качестве идентификатора строку"newItem". Метод setAttribute()требует два параметра. Первый параметр -- строка, которая задает название атрибута. Второй параметр - строка, число или булево выражение соответствует значению атрибута.

Метод removeAttribute()

Удалить атрибут у элемента можно, активизируя метод removeAttribute(), который требует в качестве параметра название этого атрибута. Если удаленный атрибут имеет значение по умолчанию, то оно восстанавливается. Согласно документации в Internet Explorer 5, по умолчанию в параметре набор строчных и прописных букв должен совпадать с использованным ранее в названии атрибута. Зависимость от регистра можно отменить, задав в качестве второго параметра метода число 0. Метод возвращает true при успешном выполнении действия и false в противном случае.

Метод getAttribute()позволяет узнать текущее значение атрибута у элемента и требует в качестве параметра название этого атрибута.

Работа с формой

<!-- пример pr32: -->

<html> <head>

<title>Checkbox Inspector</title>

<script type="text/javascript">

function inspectBox(form) {

if (form.checkThis.checked) {

alert("The box is checked.");

} else {

alert("The box is not checked at the moment.");

}

}

</script>

</head>

<body>

<form>

<input type="checkbox" name="checkThis" />Check here

<p><input type="button" name="boxChecker" value="Inspect Box"

onclick="inspectBox(this.form)" /></p>

</form>

</body> </html>

<!-- пример pr33: открытие документа в новом окне -->

<html>

<head>

<title>Radio Button onClick Handler</title>

<script type="text/javascript">

var ShempOPhile = false

function initValue() {

ShempOPhile = document.forms[0].stooges[3].checked;

}

function fullName(form) {

for (var i = 0; i < form.stooges.length; i++) {

if (form.stooges[i].checked) {

break;

}

}

alert("You chose " + form.stooges[i].value + ".");

}

function setShemp(setting) {

ShempOPhile = setting;

}

function exitMsg() {

if (ShempOPhile) {

alert("You like SHEMP?");

}

}

</script>

</head>

<body onload="initValue()" onunload="exitMsg()">

<form> <b>Select your favorite Stooge:</b>

<p><input type="radio" name="stooges" value="Moe Howard"

checked="checked" onclick="setShemp(false)" />Moe

<input type="radio" name="stooges" value="Larry Fine"

onclick="setShemp(false)" />Larry

<input type="radio" name="stooges" value="Curly Howard"

onclick="setShemp(false)" />Curly

<input type="radio" name="stooges" value="Shemp Howard"

onclick="setShemp(true)" />Shemp</p>

<p><input type="button" name="Viewer" value="View Full Name..."

lick="fullName(this.form)" /></p>

</form>

</body>

</html>

<!-- пример pr34: -->

<html> <head>

<title>Submit and Reset Confirmation</title>

<script type="text/javascript">

function allowReset() {

return window.confirm("Go ahead and clear the form?");

}

function allowSend() {

return window.confirm("Go ahead and mail this info?");

}

</script>

</head>

<body>

<form method="POST" enctype="text/plain"

action=mailto:[email protected] onReset="return allowReset()"

onsubmit="return allowSend()">

Enter your first name:<input type="text" name="firstName" />

<p>Enter your last name:<input type="text" name="lastName" /></p>

<p>Enter your address:<input type="text" name="address" /></p>

<p>Enter your city:<input type="text" name="city" /></p>

<p><input type="radio" name="gender" checked="checked" />Male <input type="radio" name="gender" />Female<<p>

<input type="checkbox" name="retired" />I am retired</p>

<p><input type="reset" /> <input type="submit" /></p>

</form>

</body>

</html>

JavaScript и AJAX

Технология AJAX (Asynchronous JavaScript And XML) позволяет создавать интерактивные веб-приложения: пересылаемая сервером клиенту страница может полностью не перегружаться, а перегружается лишь часть, содержащая изменившиеся данные. Все новые сервисы Google, в том числе GMail, Orkut, Google Groups, Google Maps, Google Suggest, Google Finance , являются AJAX-приложениями. Базисом технологии являются:

· использование модели DOM для отображения и обновления содержимого.

· обмен и обработка данных в виде XML

· асинхронные запросы к серверу через интерфейс XMLHttpRequest.

· использование JavaScript.

Рассмотрим отличия классической модели веб-приложения и модели AJAX.

Классическая модель веб-приложения:

- Пользователь загружает в браузер веб-страницу и вызывает событие.

- Браузер отправляет HTTP запрос серверу.

- В ответ сервер генерирует новую веб-страницу и возвращает ее браузеру.

- В результате отображается новая страница.

Модель AJAX:

В этом случае между загруженной в браузер страницей и сервером появляется еще одна прослойка - уровень AJAX.

-Пользователь загружает на web-страницу.

-По действию пользователя генерируется событие.

-Скрипт определяет, какая информация необходима для обновления страницы и передает ее уровню AJAX.

-AJAX, используя браузер, отправляет соответствующий запрос на сервер.

-Сервер возвращает уровню AJAX только ту часть документа, на которую пришел запрос или только данные в формате XML.

-Уровень AJAX вызывает скрипт на языке JavaScript, который вносит изменения на страницу без ее полной перезагрузки.

При этом сервер возвращает не готовый HTML-код, а только данные необходимые для обновления страницы. Обновленные страницы создаются исходя из этих данных, с использованием методов DOM. Для передачи данных обычно используется XML файл, который формируется динамически.

Запрос к серверу. Класс XMLHttpRequest

Класс XMLHttpRequest впервые был реализован компанией Microsoft в браузере Internet Explorer 5.0 в виде объекта ActiveX, доступного через JScript. Программисты проекта Mozilla разработали совместимую версию класса XMLHttpRequest. В дальнейшем эта возможность также была реализована компаниями Apple, Opera и другими.

Класс XMLHttpRequest входит в набор API (XMLHTTP), используемый в JavaScript, для пересылки данных по HTTP-протоколу между браузером и веб-сервером. Кроме пересылки XML, по XMLHTTP можно обмениваться данными формы или текстовыми строками. Объект-запрос XMLHttpRequest выполняет одну из функций браузера- формирование и передачу запроса Web-серверу.

Запрос надо создать, открыть методом open(), а затем передать его методом send().

if (window.XMLHttpRequest) {

req = new XMLHttpRequest();

req.onreadystatechange = processReqChange;

req.open("GET", url, true);

req.send(null); }

В методе open() третий параметр async – флаг асинхронного выполнения. Если

async= true, метод send() сразу же вернет управление сценарию. В этом случае пользователь сможет продолжить работу с документом, пока запрос будет пересылаться к серверу и обратно. При получении ответа от сервера, управление должно перейти к функции обратного вызова, задаваемую свойством onreadystatechange класса XMLHttpRequest. С помощью свойства readyState проверяется состояние процесса обработки запроса (readyState = 4 окончание), необходимые данные извлекаются из свойств responseText или responseXML.

Методы класса XMLHttpRequest

abort() - отменяет текущий запрос;

getAllResponseHeaders() - возвращает список всех HTTP-заголовков в виде строки;

getResponseHeader(headerName) - возвращает значение указанного заголовка;

open(method, URL, async, userName, password) - определяет метод, URL, имя и пароль запроса; async=true/false определяет, происходит ли работа в асинхронном режиме;

send(content) - отправляет запрос на сервер

setRequestHeader(label, value) - добавляет HTTP-заголовок к запросу;

Свойства класса XMLHttpRequest

onreadystatechange - обработчик события, которое будет происходить при смене состояния объекта.

readyState -возвращает текущее состояние объекта (0 — не инициализирован, 1 — открыт, 2 — отправка, 3 — получение данных, 4 — данные загружены).

responseText - текст ответа на запрос; responseXML - текст ответа на запрос в виде XML, который затем может быть распарсен посредством DOM

status - возвращает HTTP-статус в виде числа (404 — «Not Found», 200 — «OK» )

statusText - возвращает статус в виде строки («Not Found», «OK» и т. д.)

Создание экземпляра объекта XMLHttpRequest

В браузере в IE 5 - IE 6 объект XMLHttpRequest реализован через ActiveXObject, а в остальных браузерах (IE 7, Mozilla, Opera, Safari) — как встроенный объект типа XMLHttpRequest. Поэтому в версиях Internet Explorer до IE7 рекомендуется использовать:

var req = new ActiveXObject("Msxml2.XMLHTTP");

Для остальных браузеров пишем:

var req = new XMLHttpRequest();

В качестве универсального решения предлагается использование функции:

function createRequestObject()

{

if (window.XMLHttpRequest) {

// проверка наличия window.XMLHttpRequest

try {

return new XMLHttpRequest();

} catch (e){}

} else if (window.ActiveXObject)

{ проверка наличия window.ActiveXObject

try {

return new ActiveXObject('Msxml2.XMLHTTP');

}

} catch (e){}

}

}

return null;

}

Установка обработчика событий:

req.onreadystatechange = processReqChange;

открытие соединения

req.open(<"GET"|"POST"|...>, <url>, <asyncFlag>);

Отправка запросов.

После определения всех параметров запроса его остается отправить. Делается это функцией send().

При отправке GET-запроса необходимо указать параметр null или не указывать никаких параметров:

req.send(null);

Если необходимо передать на сервер POST-данные, их надо передать в качестве параметра для этой функции. POST-данные должны быть свернуты в URL-escaped строку в кодировка UTF-8 и добавлен заголовок req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");.

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

function processReqChange()

{

try { // Важно!

// только при состоянии "complete"

if (req.readyState == 4) {

// для статуса "OK"

if (req.status == 200) {

// здесь идут всякие штуки с полученным ответом

} else {

alert("Не удалось получить данные:\n" +

req.statusText);

}

}

}

catch( e ) { }

}

Приведем код всего AJAX-приложения:

//JavaScript’овая часть:

var req;

var reqTimeout;

function loadXMLDoc(url) {

req = null;

if (window.XMLHttpRequest) {

try {

req = new XMLHttpRequest();

} catch (e){}

} else if (window.ActiveXObject) {

try {

req = new ActiveXObject('Msxml2.XMLHTTP');

} catch (e){

try {

req = new ActiveXObject('Microsoft.XMLHTTP');

} catch (e){}

}

}

if (req) {

req.onreadystatechange = processReqChange;

req.open("GET", url, true);

req.send(null);

reqTimeout = setTimeout("req.abort();", 5000);

} else {

alert("Браузер не поддерживает AJAX");

}

}

function processReqChange() {

document.form1.state.value = stat(req.readyState);

if (req.readyState == 4) {

clearTimeout(reqTimeout);

document.form1.statusnum.value = req.status;

document.form1.status.value = req.statusText;

// only if "OK"

if (req.status == 200) {

document.form1.response.value=req.responseText;

} else {

alert("Не удалось получить данные:\n" + req.statusText);

}

}

}

function stat(n)

{

switch (n) {

case 0:

return "не инициализирован";

break;

case 1:

return "загрузка...";

break;

case 2:

return "загружено";

break;

case 3:

return "в процессе...";

break;

case 4:

return "готово";

break;

default:

return "неизвестное состояние";

}

}

function requestdata(params)

{

loadXMLDoc('examples/httpreq.php?'+params);

}

HTML-форма:

<form name=form1>

<table width=100% style="font-size: 100%">

<tr>

<td width=30% valign=top>Состояние запроса</td>

<td width=70%><input size=25 disabled type=text name=state value=""></td>

</tr>

<tr>

<td valign=top>Код статуса</td>

<td><input disabled size=2 type=text name=statusnum value="">

<input disabled size=19 type=text name=status value=""></td>

</tr>

<tr>

<td valign=top>Данные от сервера</td>

<td><textarea rows=6 name=response></textarea></td>

</tr>

<tr>

<td>Строка GET-запроса<td>

<td></td>

</tr>

</table>

<input type=text name=getparams value="?">

<input type=button onclick="requestdata(getparams.value);" value="GET">

</form>

PHP-файл:

<?php

header("Content-type: text/plain; charset=windows-1251");

header("Cache-Control: no-store, no-cache, must-revalidate");

header("Cache-Control: post-check=0, pre-check=0", false);

echo "Hello world!\n\n";

if (isset($a))

{

for ($i=1; $i < 10000; $i++)

{

echo 'Это тестовая строка. ';

if (($i % 1000) == 0) flush();

}

}

if (count($_GET) > 0)

{

echo "\n\nПередано GET'ом\n"; print_r($_GET);

}

?>

Использование DOM

Полученные без прерывания работы пользователя новые данные нужно включить в состав документа, уже отображающегося на экране. Для этого надо воспользоваться структурой объектов DOM. От свойства responseText лучше отказаться, так как его применение потребует дополнительного синтаксического разбора. Гораздо полезнее свойство responseXML, в котором информация изначально представляется в совместимом с DOM виде. В структуре текущего документа необходимо выбрать узел, в состав которого следует включить возвращенные данные, и вызвать метод replaceChild(), заменив старое поддерево новым, прочитанным из responseXML объекта XMLHttpRequest. После этого осталось задать внешний вид полученных данных посредством каскадных таблиц стилей.

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

Информируйте пользователя

Сначала нам нужно добавить сообщения об ошибках, о которых не может сообщить браузер. О каких ошибках мы должны сообщить пользователю? Для начала это ошибки соединения. Если запрос не удался, мы сможем получить код ошибки с помощью XMLHttpRequest и вывести соответствующее сообщение. Здесь приведен отрывок функции, которая обрабатывает событие onreadystatechange, объекта request класса XMLHttpRequest.

if (request.readyState == 4){// 4(complete) запрос выполнен

if (request.status == 200){

// HTTP OK, продолжаем нормальную обработку Ajax

//...

}else{

// что-то пошло не так, сообщаем об ошибке

error("HTTP " + request.status +

". Произошла ошибка: " + request.statusText);

}

}

Очень важно, чтобы цикл связи Ajax не прерывался. Серверный скрипт должен возвращать корректный XML документ. Если серверный скрипт завершится аварийно, сообщение об ошибке будет утеряно и приложение упадет

Если скрипты отключены

При создании клиентских скриптов нельзя забывать о пользователях, у которых скрипты отключены. В случае использования Ajax это сделать довольно просто с помощью использования «захвата» ссылки или формы.

<form action="traditional_action.php" method="post"

onsubmit="perform_ajax_action(); return false;">

Если этот код обрабатываться браузером с включенными скриптами, то выполняется код Ajax, иначе свойство onsubmit игнорируется и форма работает традиционным способом.

Мы можем пойти дальше и проверить поддерживает ли браузер объект XMLHttpRequest. Вместо использования явного вызова return false в обработчике onsubmit, мы можем проверить есть ли необходимые для Ajax объекты, в вызываемой функции, и выполнить код Ajax если он поддерживается или передать управление форме если нет. Проверим, существует ли функция createAjaxRequest создающая соответствующий браузеру объект XMLHttpRequest.

var request; // our request object

function perform_ajax_action(){

if (!request = createAjaxRequest()){

// попытка использовать Ajax не удалась,

//подтверждаем форму

return true;

}

// нормальная обработка с помощью Ajax

//...

return false; // не подтверждать форму

}

В коде формы мы перепишем обработчик, чтобы использовать традиционный способ при первых признаках проблем.

<form action="traditional_action.php" method="post"

onsubmit="return perform_ajax_action();">

Если все пройдет хорошо, будет выполнен код Ajax, а подтверждение формы пропущено. При наличии проблем с поддержкой Ajax, форма будет подтверждена, и пользователь сможет продолжить работу обычным образом.

Рассмотрим пример:

//Создаем новый объект-запрос JavaScript:

var req = new ActiveXObject("Microsoft.XMLHTTP"); //(для IE)

var req = new XMLHttpRequest(); // (Для всего остального)

Часто выбор класса для объекта req оформляется в виде функции

//пишем функцию, использующую этот объект

var req;

function loadXMLDoc(url) {

// branch for native XMLHttpRequest object

if (window.XMLHttpRequest) {

req = new XMLHttpRequest();

req.onreadystatechange = processReqChange;

req.open("GET", url, true);

req.send(null); }

// branch for IE/Windows ActiveX version

else if (window.ActiveXObject) {

req = new ActiveXObject("Microsoft.XMLHTTP");

if (req) {

req.onreadystatechange = processReqChange;

req.open("GET", url, true); //открыть запрос

req.send();//послать запрос

}

}

}

//В теле HTML файла пишем скрипт:

function checkName(input, response)

{

if (response != ''){

// Response mode

message = document.getElementById('nameCheckFailed');

if (response == '1'){

message.className = 'error';

}else{

message.className = 'hidden';

}

}else{

// Input mode

url = 'http://localhost/xml/checkUserName.php?q=' \\

+ input;

loadXMLDoc(url);

}

}

В данном примере в файле localhost/xml/checkUserName.php обрабатываются данные, полученные из командной строки в в переменной q. А результат сохраняется в XML структуре, которая хранится в этом же файле. Так можно получить из БД и обработать данные, которые необходимо обновить.

Объект FormData

One of the enhancements to XMLHttpRequest is the introduction of the FormData object. With the FormData object, you can create and send a set of key/value pairs and, optionally, files using XMLHttpRequest. When using this technique, the data is sent in the same format as if you'd submitted it via the form's submit() method with the encoding type of multipart/form-data.

FormData позволяет создать форму HTML на лету, используя JavaScript, и затем переслать ее, используя XMLHttpRequest.send(). Простой пример:

var formData = new FormData();formData.append("part_num", "123ABC"); formData.append("part_price", 7.95);formData.append("part_image", somefile) var xhr = new XMLHttpRequest();xhr.open("POST", "http://some.url/"); xhr.send(formData);

You can also use FormData to add additional data to an existing form before submitting it.

var formElement = document.getElementById("someFormElement");var formData = new FormData(formElement);formData.append("part_description", "The best part ever!"); var xhr = new XMLHttpRequest();xhr.open("POST", "http://some.url/");xhr.send(formData);

Cookies

Cookie является решением одной из проблем HTTP протокола. Транзакция завершается после того, как браузер сделал запрос, а сервер выдал соответствующий ответ. Сразу после этого сервер "забывает" о пользователе и каждый следующий запрос того же пользователя считает новым пользователем.

Используя cookie, можно эмулировать сессию по HTTP протоколу. Коротко принцип эмуляции сессии таков: на первом запросе выдается соотвествующее значение cookie, а при каждом последующем запросе это значение читается из переменной окружения HTTP_COOKIE и обрабатывается.

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

Cookie - это небольшая порция текстовой информации, которую сервер передает браузеру. Браузер будет хранить эту информацию и передавать ее серверу с каждым запросом как часть HTTP заголовка. Одни значения cookie могут храниться только в течение одной сессии, они удаляются после закрытия броузера. Другие, установленные на некоторый период времени, записываются в файл. Обычно этот файл называется 'cookies.txt' и лежит в рабочей директории установленного на компьютер браузера.

Сами по себе cookies не могут делать ничего, это только лишь некоторая текстовая информация. Однако сервер может считывать содержащуюся в cookies информацию и на основании ее анализа совершать те или иные действия. Например, в случае авторизованного доступа к чему либо через WWW в cookies сохраняется login и password в течение сессии, что позволяет пользователю не вводить их снова при запросах каждого документа, защищенного паролем.

Еще одна распространенная область использования cookies - при настройке индивидуального профиля каждого зарегистрированного пользователя.

И, наконец, самая последняя область - использование механизма cookie в рекламном бизнесе на Интернет. Однако рекламодатели начинают предъявлять более жесткие условия к оценке эффективности своих расходов. Cookie используются для определения целевой аудитории по географическому положению пользователей, отслеживания интересов пользователей, учета количества показов и проходов сквозь баннеры.

Работа с cookie

Теперь, когда с принципами действия и областями применения cookie все более или менее понятно, можно приступить к изучению формата и синтаксиса, а также способов задания значений 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 <= 4000)

document.cookie = curCookie

else

if (confirm("Cookie превышает 4KB и будет вырезан !"))

document.cookie = curCookie

}

Пример 4. Функция чтения значения cookie

Возвращает установленное значение или пустую строку, если cookie не существует.

// name - имя считываемого cookie

function getCookie(name) {

var prefix = name + "="

var cookieStartIndex = document.cookie.indexOf(prefix)

if (cookieStartIndex == -1)

return null

var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length)

if (cookieEndIndex == -1)

cookieEndIndex = document.cookie.length

return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex))

}

Пример 5. Функция удаления значения cookie

Принцип работы этой функции заключается в том, что cookie устанавливается с заведомо устаревшим параметром expires, в данном случае 1 января 1970 года.

// name - имя cookie

// [path] - путь, для которого cookie действительно

// [domain] - домен, для которого cookie действительно

function deleteCookie(name, path, domain) {

if (getCookie(name)) {

document.cookie = name + "=" +

((path) ? "; path=" + path : "") +

((domain) ? "; domain=" + domain : "") +

"; expires=Thu, 01-Jan-70 00:00:01 GMT"

}

Работающий пример персонализации пользователя, построенный на JavaScript и использующий механизм cookie.

3. Задание cookie с помощью CGI-скриптов

Самый мощный и гибкий способ управления документами с использованием механизма cookie - с помощью CGI-скриптов. Задание значения cookie на Perl будет выглядеть следующим образом:

print "Content-type: text/html\n";

print "Set-Cookie: username=aaa13; expires=Friday, 31-Dec-99 23:59:59 GMT; path=/; domain=www.citforum.ru;\n\n";

Скрипт при выдаче результатов работы генерирует HTTP заголовок: Content-type: text/html

Set-Cookie: "username=aaa13; expires=Friday, 31-Dec-99 23:59:59 GMT; path=/; domain=www.citforum.ru;"

Чтобы прочитать в скрипте ранее заданное значение cookie, используется переменная окружения HTTP_COOKIE.

$cookie = $ENV{'HTTP_COOKIE'};

Далее можно анализировать полученную строку и, в зависимости от считанных значений, выполнять соответствующие действия.

Немного о проблемах, связанных с использованием cookie

Главной проблемой является изначальное недоверие пользователей к тому, что удаленные сервера без их (пользователей) ведома и согласия записывают на их собственные локальные диски какую либо информацию. Бытовали также слухи о том, что с помощью механизма cookie можно прочесть любую информацию с любого компьютера. Это неправда, к тому же современные версии браузеров позволяют контролировать прием cookie или вовсе блокировать его. Кроме того, появилось множество специальных утилит для управления приемом cookie, так называемые Cookie Managers.

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

<script type="text/javascript">

//Исходный код скрипта:

var username = GetCookie('username');

if (username == null) {

username = prompt(' Пожалуйста, введите Ваше им\я\n (в противном случае нажмите cancel)',"");

if (username == null) {

alert('Ну хорошо, тогда я буду звать Вас ВебСёрфером');

username = 'ВебСёрфер';

} else {

pathname = location.pathname;

myDomain = pathname.substring(0,pathname.lastIndexOf('/')) +'/';

// Установка параметра expire на год вперед.

var largeExpDate = new Date ();

largeExpDate.setTime(largeExpDate.getTime() + (365 * 24 * 3600 * 1000));

SetCookie('username',username,largeExpDate,myDomain);

}

}

function getCookieVal (offset) {

var endstr = document.cookie.indexOf (";", offset);

if (endstr == -1)

endstr = document.cookie.length;

return unescape(document.cookie.substring(offset, endstr));

}

function GetCookie (name) {

var arg = name + "=";

var alen = arg.length;

var clen = document.cookie.length;

var i = 0;

while (i < clen) {

var j = i + alen;

if (document.cookie.substring(i, j) == arg)

return getCookieVal (j);

i = document.cookie.indexOf(" ", i) + 1;

if (i == 0)

break;

}

return null;

}

function SetCookie (name, value) {

var argv = SetCookie.arguments;

var argc = SetCookie.arguments.length;

var expires = (argc > 2) ? argv[2] : null;

var path = (argc > 3) ? argv[3] : null;

var domain = (argc > 4) ? argv[4] : null;

var secure = (argc > 5) ? argv[5] : false;

document.cookie = name + "=" + escape (value) +

((expires == null) ? "" : ("; expires=" +

expires.toGMTString())) +

((path == null) ? "" : ("; path=" + path)) +

((domain == null) ? "" : ("; domain=" + domain)) +

((secure == true) ? "; secure" : "");

}

document.write('<p align=center>Здравствуйте, ' + username + '</p>');

</script>

<SCRIPT LANGUAGE="JavaScript">

// Alex Alexandrov wrote:

// This scrpt was taken from a book called "Learn Advanced Java Script" Chapter 14.

// The guys who wrote that book wanted us to leave a copyright. So here it goes:

// THIS SCRPIT IS COPYRIGHTED//

// Be AWARE TO PUT IT ON YOUR PAGE//

// Boolean variable specified if alert should be displayed if cookie exceeds 4KB

var caution = false

// name - name of the cookie

// value - value of the cookie

// [expires] - expiration date of the cookie (defaults to end of current session)

// [path] - path for which the cookie is valid (defaults to path of calling document)

// [domain] - domain for which the cookie is valid (defaults to domain of calling document)

// [secure] - Boolean value indicating if the cookie transmission requires a secure transmission

// * an argument defaults when it is assigned null as a placeholder

// * a null placeholder is not required for trailing omitted arguments

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 <= 4000)

document.cookie = curCookie

else

if (confirm("Cookie превышает 4KB и будет вырезан !"))

document.cookie = curCookie

}

// name - name of the desired cookie

// * return string containing value of specified cookie or null if cookie does not exist

function getCookie(name) {

var prefix = name + "="

var cookieStartIndex = document.cookie.indexOf(prefix)

if (cookieStartIndex == -1)

return null

var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length)

if (cookieEndIndex == -1)

cookieEndIndex = document.cookie.length

return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex))

}

// name - name of the cookie

// [path] - path of the cookie (must be same as path used to create cookie)

// [domain] - domain of the cookie (must be same as domain used to create cookie)

// * path and domain default if assigned null or omitted if no explicit argument proceeds

function deleteCookie(name, path, domain) {

if (getCookie(name)) {

document.cookie = name + "=" +

((path) ? "; path=" + path : "") +

((domain) ? "; domain=" + domain : "") +

"; expires=Thu, 01-Jan-70 00:00:01 GMT"

}

}

function fixDate(date) {

var base = new Date(0)

var skew = base.getTime()

if (skew > 0)

date.setTime(date.getTime() - skew)

}

function initCookie(monthName) {

// initializes cookie with the following format:

// ^1^^2^^3^^4^...^30^^31^

// initialize accumulative variable

var text = ""

for (var i = 1; i <= 31; ++i) {

text += "^" + i + "^"

}

var now = new Date()

fixDate(now)

// set time to one month (31 days) in the future

now.setTime(now.getTime() + 1000 * 60 * 60 * 24 * 31)

setCookie(monthName + "Calendar", text, now)

}

function getSpecificReminder(num, monthName) {

var prefix = "^" + num + "^"

var totalCookie = getCookie(monthName + "Calendar")

var startIndex = totalCookie.indexOf(prefix, 0)

var startData = totalCookie.indexOf("^", startIndex + 1) + 1

if (num == 31)

var endData = totalCookie.length

else

var endData = totalCookie.indexOf("^", startData)

return totalCookie.substring(startData, endData)

}

function setSpecificReminder(num, monthName, newValue) {

var prefix = "^" + num + "^"

var totalCookie = getCookie(monthName + "Calendar")

var startIndex = totalCookie.indexOf(prefix, 0)

var startData = totalCookie.indexOf("^", startIndex + 1) + 1

if (num == 31)

var endData = totalCookie.length

else

var endData = totalCookie.indexOf("^", startData)

var now = new Date()

fixDate(now)

// set time to one month (31 days) in the future

now.setTime(now.getTime() + 1000 * 60 * 60 * 24 * 31)

setCookie(monthName + "Calendar", totalCookie.substring(0, startData) + newValue + totalCookie.substring(endData, totalCookie.length), now)

}

function getInput(num, monthName) {

if (!getCookie(monthName + "Calendar"))

initCookie(monthName)

var newValue = prompt("Введите запись соответствующей данной дате:", getSpecificReminder(num, monthName))

if (newValue) // user did not cancel

setSpecificReminder(num, monthName, newValue)

}

function getTime() {

// initialize time-related variables with current time settings

var now = new Date()

var hour = now.getHours()

var minute = now.getMinutes()

now = null

var ampm = ""

// validate hour values and set value of ampm

if (hour >= 12) {

hour -= 12

ampm = "PM"

} else

ampm = "AM"

hour = (hour == 0) ? 12 : hour

// add zero digit to a one digit minute

if (minute < 10)

minute = "0" + minute // do not parse this number!

// return time string

return hour + ":" + minute + " " + ampm

}

function leapYear(year) {

if (year % 4 == 0) // basic rule

return true // is leap year

return false // is not leap year

}

function getDays(month, year) {

// create array to hold number of days in each month

var ar = new Array(12)

ar[0] = 31 // January

ar[1] = (leapYear(year)) ? 29 : 28 // February

ar[2] = 31 // March

ar[3] = 30 // April

ar[4] = 31 // May

ar[5] = 30 // June

ar[6] = 31 // July

ar[7] = 31 // August

ar[8] = 30 // September

ar[9] = 31 // October

ar[10] = 30 // November

ar[11] = 31 // December

// return number of days in the specified month (parameter)

return ar[month]

}

function getMonthName(month) {

// create array to hold name of each month

var ar=["ЯНВАРЬ", "ФЕВРАЛЬ", "МАРТ", "АПРЕЛЬ", "МАЙ","ИЮНЬ", "ИЮЛЬ", "АВГУСТ", "СЕНТЯБРЬ"

, "ОКТЯБРЬ", "НОЯБРЬ","ДЕКАБРЬ"];

/*var ar = new Array(12)

ar[0] = "ЯНВАРЬ"

ar[1] = "ФЕВРАЛЬ"

ar[2] = "МАРТ"

ar[3] = "АПРЕЛЬ"

ar[4] = "МАЙ"

ar[5] = "ИЮНЬ"

ar[6] = "ИЮЛЬ"

ar[7] = "АВГУСТ"

ar[8] = "СЕНТЯБРЬ"

ar[9] = "ОКТЯБРЬ"

ar[10] = "НОЯБРЬ"

ar[11] = "ДЕКАБРЬ"*/

// return name of specified month (parameter)

return ar[month]

}

function setCal() {

// standard time attributes

var now = new Date()

var year = now.getYear()

var month = now.getMonth()

var monthName = getMonthName(month)

var date = now.getDate()

now = null

// create instance of first day of month, and extract the day on which it occurs

var firstDayInstance = new Date(year, month, 1)

var firstDay = firstDayInstance.getDay()

firstDayInstance = null

// number of days in current month

var days = getDays(month, year)

// call function to draw calendar

drawCal(firstDay + 1, days, date, monthName, 1900 + year)

}

function drawCal(firstDay, lastDate, date, monthName, year) {

// constant table settings

var headerHeight = 35 // height of the table's header cell

var border = 0 // 3D height of table's border

var cellspacing = 0 // width of table's border

var headerColor = "00008b" // color of table's header

var headerSize = "+2" // size of tables header font

var colWidth = 45 // width of columns in table

var dayCellHeight = 15 // height of cells containing days of the week

var dayColor = "000000" // color of font representing week days

var cellHeight = 25 // height of cells representing dates in the calendar

var todayColor = "red" // color specifying today's date in the calendar

var timeColor = "purple" // color of font representing current time

var dayCellcolor="87ceda"

var monthColor="6485ed"

// create basic table structure

var text = "" // initialize accumulative variable to empty string

text += '<CENTER>'

text += '<TABLE BORDER=' + border + ' CELLSPACING=' + cellspacing + '>' // table settings

text += '<TH COLSPAN=7 HEIGHT=' + headerHeight + ' BGCOLOR='+ monthColor +'>' // create table header cell

text += '<FONT COLOR="' + headerColor + '" SIZE=' + headerSize + '>' // set font for table header

text += monthName + ' ' + year

text += '</FONT>' // close table header's font settings

text += '</TH>' // close header cell

// variables to hold constant settings

var openCol = '<TD align=right WIDTH=' + colWidth + ' HEIGHT=' + dayCellHeight + ' BGCOLOR='+ dayCellcolor +'>'

openCol += '<FONT SIZE=-1 COLOR="' + dayColor + '">'

var closeCol = '</FONT></TD>'

// create array of abbreviated day names

var weekDay = new Array(7)

weekDay[0] = "Вс"

weekDay[1] = "Пн"

weekDay[2] = "Вт"

weekDay[3] = "Ср"

weekDay[4] = "Чт"

weekDay[5] = "Пт"

weekDay[6] = "Сб"

//create first row to set column width and specify week day

text += '<TR ALIGN="center" VALIGN="center">'

for (var dayNum = 0; dayNum < 7; ++dayNum) {

text += openCol + weekDay[dayNum] + closeCol

}

text += '</TR>'

//declaration of two variables to help with tables

var digit = 1

var curCell = 1

for (var row = 1; row <= Math.ceil((lastDate + firstDay - 1) / 7); ++row) {

text += '<TR ALIGN="right" VALIGN="top">'

for (var col = 1; col <= 7; ++col) {

if (digit > lastDate)

break

if (curCell < firstDay) {

text += '<TD></TD>';

curCell++

} else {

if (digit == date) {

// current cell repesent today's date

text += '<TD HEIGHT=' + cellHeight + ' BGCOLOR="#00FFFF">'

text += '<FONT COLOR="' + todayColor + '">'

text += '<A HREF="javascript:getInput(' + digit + ', \'' + monthName + '\')" onMouseOver="window.status = \'Записать или прочесть запись за ' + monthName + ' ' + digit + '\'; return true"><FONT SIZE=-1 COLOR="' + todayColor + '">' + digit + '</FONT></A>'

text += '<BR>'

text += '<FONT COLOR="' + timeColor + '" SIZE=2>'

text += '<CENTER>' + getTime() + '</CENTER>'

text += '</FONT>'

text += '</TD>'

} else

text += '<TD HEIGHT=' + cellHeight + ' BGCOLOR= "#C0C0C0"><FONT SIZE=-1><A HREF="javascript:getInput(' + digit + ', \'' + monthName + '\')" onMouseOver="window.status = \'Записать или прочесть запись за ' + monthName + ' ' + digit + '\'; return true">' + digit + '</A></FONT></TD>'

digit++

}

}

text += '</TR>'

}

// close all basic table tags

text += '</TABLE>'

text += '</CENTER>'

// print accumulative HTML string

document.write(text)

}

setCal()

</script>

Примеры на JavaScript

Приветствие в зависимости от времени суток

<html>

<head>

<title>Привет</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script language="JavaScript">

day = new Date();

hour = day.getHours();

if (hour>=5 && hour<12) greeting = "Доброе утро";

else

if (hour>=12 && hour<18) greeting = "Добрый день";

else

if (hour>=18 && hour<24) greeting = "Добрый вечер";

else

if (hour>=0 && hour<5) greeting = "Доброй ночи";

document.write(greeting); </script>

</head>

<body>

</body>

</html>

<!-- пример 32: создание динамического меню после загрузки страницы -->

<html><head>

<style>

.menuContainer {

border: 1px solid #123456;

}

.menuContainer .menuItem {

float: left;

margin: 2px;

padding: 10px;

}

.menuContainer .menuOver {

background-color: #808080;

}

.menuContainer .menuOver a {

color: #800000;

font-weight: bold;

}

.menuContainer .clear {

clear: left;

}

</style>

<script type="text/javascript">

function processMenu() {

var allDiv = document.getElementsByTagName("DIV");

for (var i = 0; i < allDiv.length; i++) {

if (allDiv[i].className == "menuContainer")

processMenuItem(allDiv[i]);

}

}

function processMenuItem(_obj) {

var allChilds = _obj.childNodes;

for (var i = 0; i < allChilds.length; i++) {

if (allChilds[i].className == "menuItem") {

allChilds[i].onmouseover = function() {

this.className += " menuOver";

}

allChilds[i].onmouseout = function() {

this.className =

this.className.replace(" menuOver","");

}

}

}

}

</script>

</head>

<body onload="processMenu();">

<div class="menuContainer">

<div class="menuItem"><a href="#">first</a></div>

<div class="menuItem"><a href="#">second</a></div>

<div class="menuItem"><a href="#">third</a></div>

<div class="menuItem"><a href="#">fourth</a></div>

<div class="clear"></div>

</div>

</body></html>

<!-- пример pr33: валидация формы -->

<script type="text/javascript">

function submitForm(_form) {debugger;

markErrorField(false);

var errMess = "";

if (!_form.elements["login"].value) {

errMess += "Your Login is empty.\n";

markErrorField(_form.elements["login"]);

}

if (!_form.elements["mail"].value) {

errMess += "Your Email is empty\n";

markErrorField(_form.elements["mail"]);

}

if (!_form.elements["pass"].value) {

errMess += "Your Password is empty.\n";

markErrorField(_form.elements["pass"]);

} else if (!_form.elements["confpass"].value) {

errMess +=

"Your Password confirmation is empty.\n";

markErrorField(_form.elements["confpass"]);

} else if

(_form.elements["pass"].value !=

_form.elements["confpass"].value) {

errMess +=

"Your Password confirmation does not equal to your Password.\n";

markErrorField(_form.elements["pass"]);

markErrorField(_form.elements["confpass"]);

}

if (errMess) {

alert(errMess + "");

return false;

}

}

function markErrorField(_element) {

var allLabels =

document.getElementsByTagName("LABEL");

if (_element) {

for (var i = 0; i < allLabels.length; i++) {

if (allLabels[i].htmlFor == _element.id)

allLabels[i].style.color = "red"; }

} else {

for (var i = 0; i < allLabels.length; i++) {

allLabels[i].style.color = "black";

}

}

}

</script>

<form onsubmit="return submitForm(this);">

<table>

<tr>

<td><label for="login">Your Login</label></td>

<td><input type="text" name="login" id="login" /></td>

</tr>

<tr>

<td><label for="mail">Your Email</label></td>

<td><input type="text" name="mail" id="mail" /></td>

</tr>

<tr>

<td><label for="pass">Your Password</label></td>

<td><input type="password" name="pass" id="pass" /></td>

</tr>

<tr>

<td><label for="confpass">

Confirm Your Password</label></td>

<td><input type="password" name="confpass"

id="confpass" /></td>

</tr>

<tr>

<td colspan="2"><input type="submit"

name="Register" /></td>

</tr>

</table>

</form>

//pr34-Выделение всех чекбоксов (checkbox) в группе

<html>

<head>

<script type="text/javascript">

function checkAll(oForm, cbName, checked)

{

for (var i=0; i < oForm[cbName].length; i++) oForm[cbName][i].checked = checked;

}

</script>

</head>

<body>

<form name="form1" method="post" action="">

<input type="checkbox" name="total" value="checkbox" onClick="checkAll(this.form,'checkbox[]',this.checked)">Отметить все

<br>

<input type="checkbox" name="checkbox[]" value="checkbox">1

<br>

<input type="checkbox" name="checkbox[]" value="checkbox">2

<br>

<input type="checkbox" name="checkbox[]" value="checkbox">3

</form>

</body>

</html>

//pr35- Проверка информации, введенной в форму

Наши рекомендации