Деловая неделя

При открытии страниц браузер может передавать на сервер данные GET, POST, COOKIE, Authorization (в рамках протокола HTTP). Эти данные позволяют серверу более точно отличать одного пользователя от другого и хранить индивидуальные настройки.

ЕЖЕНЕДЕЛЬНАЯ РЕКЛАМНАЯ ГАЗЕТА ДЛЯ ПРЕДПРИЯТИЙ «Деловая неделя» (Иркутск)

Где хранить настройки неавторизованного пользователя (HTTP, JS)

Чтобы получить из Интернета информацию, пользователь должен отправлять запросы веб-серверу. Чаще всего пользователь не знает, что он «отправляет запрос», – он просто щёлкает по ссылке (например, http://dn.ir2.ru/), набирает адрес в браузере или вводит слова в поля поиска и щёлкает по кнопке отправки HTML-формы.

После заполнения полей HTML-формы всё равно получается точно такой же запрос, как если бы его просто набрали в адресной строке: http://irkutsk.ir2.ru/?q=запчасти. После знака вопроса в запросе передаются параметры – ряд пар "название параметра" = "значение", связанных знаком равенства и разделённых знаком &. Это вы можете увидеть в любой поисковой системе Интернета.

Иногда после отправки формы адресная строк не меняется. Тогда говорят, что пары "название" = "значение" отправляются на сервер методом POST (а если через адресную строку – методом GET). Методом POST обычно отправляют на сервер большие тексты – например, сообщения для форума. Методом GET – более короткие (например слова для поиска).

Время жизни параметра

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

Если вы листаете страницы сайта не как авторизованный пользователь, сервер не может хранить ваши настройки в базе данных. Вернее, он может хранить какие угодно настройки, но не может соотнести их с конкретным неавторизованным пользователем. Для сервера, в соответствии с HTTP-протоколом, пользователи отличаются друг от друга только ip-адресами и браузерами. То есть если в одном предприятии 20 человек выходят в Интернет через один шлюз и каждый пользуется Оперой 9.60, установленной на ОС Убунту, для сайта без авторизации это всё будет выглядеть как один очень активный пользователь.

В этом случае есть три варианта хранения долгоживущих параметров (будем называть их настройками пользователя).

Как хранить настройки

1. Настройки можно передавать каждый раз с каждым запросом (адресная строка может стать при этом очень длинной). Например, на сайте irkutsk.ir2.ru при каждом поисковом запросе передаются настройки "где искать – в объявлениях или в прайс-листах" и "как искать – точно введённую пользователем фразу или отбрасывая окончания". Эти настройки можно изменять в той же поисковой форме, но они меняются значительно реже самих искомых слов. То же самое можно делать и через канал POST (в адресной строке ничего тогда не будет меняться).

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

2. Постоянные в течение открытия нескольких страниц настройки можно хранить на сервере в виде переменных PHP-сессии. Так, например, хранятся левый и правый списки (результатов поиска) на сайте http://vostsibspravka.ru/. Сессия – это время, в течение которого пользователь беспрерывно тусуется на данном сайте. Беспрерывно – чаще всего определяется сервером как "не прерываясь более чем на 30 минут". Если 30 минут не щёлкать по ссылкам – сессия прервётся, и все текущие настройки будут сброшены.

Настройки, отправляемые по каналам GET и POST, могут быть более долговечными, чем переменные сессии. Вы можете надолго отойти от компьютера, сессия на сервере прервётся, но в открытом окне браузера в заполненной вами HTML-форме останутся старые данные (или просто старая адресная строка с параметрами), и при попытке обновить страницу все выбранные настройки опять отправятся на сервер (автоматом).

3. Хранить ваши личные настройки между PHP-сессиями может сам браузер – в виде файлов COOKIE. Все современные браузеры хрнят cookie в системном профиле пользователя (на Windows – что-нибудь вроде "C:\Documents and Settings\[пользователь]\Cookies\"). Чтобы это происходило, надо запрограммировать страницу сайта примерно так:

<script type='text/javascript'>
function setcookie(obj){
 var val
 if ("checkbox"==obj.type) {
  val=obj.checked
  val=Number(val)
 }
 else {
  val=obj.value
  val=(isFinite(val))?val:8
 }
 var expiresDate = new Date(); 
 expiresDate.setTime(expiresDate.getTime() + 36 * 24 * 60 * 60 * 1000)
 var expires = expiresDate.toGMTString()
 document.cookie = obj.id+'=' + val + '; expires=' + expires
 document.location.reload()
}
</script>

Эта функция принимает в виде параметра элемент HTML (который её вызывает), проверяет, не является ли он элементом управления input type="checkbox", если является и "выбран" (галочка поставлена), записывает в куки, названные по имени этого элемента, значение 1 (например, "rufield=1"). Если элемент не чекбокс, функция проверяет, было ли введено в этот элемент число и принимает его, если да (если нет – берёт "по умолчанию" число 8) – записывает в куки "limit=8". Ещё она записывает время жизни куки: 36000 дней. Это, конечно, глупо, столько не живут. Достаточно одного месяца. Потом функция перезагружает страницу, чтобы передались на сервер и вступили в действие новые настройки.

Элементы, которые при изменении в них значений запускают данную функцию, могут выглядеть примерно так:

История запросов sql, показывать 
<input class='num' name='limit' id='limit' onchange='setcookie(this)' value=\"$limit\"> 
<input type='button' value='ok'>

HTML: <input onchange='setcookie(this)' id='h' name='h' $hchck type='checkbox'>

Кнопка ok после инпута limit – чисто декоративная, она нужна, чтобы пользователь, щёлкнув по ней, вызвал бы событие onchange для данного инпута (с таким же успехом пользователь может щёлкнуть в любое другое место).

Во втором примере (чекбокс h) вообще всё просто – щелчок по элементу данного типа всегда вызывает событие onchange, больше никуда щёлкать не надо, куки записываются сразу.

Значение переменных $limit и $hchck определяются PHP-скриптом в зависимости от действий пользователя (код можно посмотреть на стр. mysql4.php, введя в форму нового sql-запроса число 1).

Так устанавливаются настройки пользователя (например, количество sql-запросов в истории) в мини-администраторе БД mysql – скрипте http://soft.infodisk.info/mysql4.php.

HTTP запросы и ответы

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

Серверный скрипт должен анализировать всю информацию, полученную в HTTP-запросе от пользователя (браузера). Если это скрипт PHP, анализировать несложно: информация по всем трём каналам помещается в соответствующие массивы – $_GET, $_POST, $_COOKIE. Эти массивы создаются в PHP всегда; если информации там нет, они пусты. Посмотреть, что там лежит, можно командой print_r($_COOKIE). На практике мы обычно заранее знаем название интересующего нас параметра, в куки их не очень много, поэтому в серверном скрипте для их обработки обычно бывает достаточно одной строчки:

$limit=intval(@$_COOKIE["limit"]);

Ну, если хитрый пользователь додумается подправить куки (или их вообще нет), переменная $limit в данном случае может оказаться равной нулю, и ни одного запроса в истории не будет (или, что ещё хуже, вылезет mysql_error). На этот случай обычно добавляется вторая строчка, задающая параметру значение "по умолчанию":

$limit=(!$limit)?"8":"$limit";

======================================

* Авторизованный пользователь тоже каждый раз при обращении к серверу отправляет туда в запросе определённую информацию, но эта информация намного меньше по объёму. Например, он может передавать только куки с идентификатором сессии (что-то вроде Cookie: PHPSESSID=79e970d05c540b8b86d6700710208dea), а сервер после авторизации уже знает, что эта сессия принадлежит конкретному пользователю, и извлекает из базы данных для него параметры (настройки). Или, при HTTP-авторизации, браузер с каждым запросом к серверу отправляет (кодированную) пару "логин" – "пароль" (Authorization: Basic YX3540b2tplkja4X5M6bmasH4hZlY=). Пользователь всего этого не видит, за него думает заботливый Firefox (или Opera).

© 2009, «Деловая неделя», Михаил Гутентог

Читать все комментарии (2)

124. Следователь

В вашем примере куки будут жить 36 дней. Если б это было на PHP, тогда да, 36000. А на Javascript – всего 36.

23.07.2010 18:48:24

125. Следователь

"Во втором примере (чекбокс h)" – "щелчок по элементу данного типа" НЕ всегда вызывает событие onchange. Например, в МС ИЕ не вызывает ничего (и ничего не будет происходить, Javascript не запустится). Поэтому в этом случае лучше привязывать к элементу событие onclick, а не onchange.

23.07.2010 18:51:54

Добавить комментарий:

*Автор:
E-Mail:
*Текст: