Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Введение в Веб программирование.doc
Скачиваний:
81
Добавлен:
07.11.2018
Размер:
4.42 Mб
Скачать

Способы задания значений 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>