Главная страница статей --> Советы по фотошопу, графике и хитрости в построении php кода

Сверхдинамичные веб-интерфейсы

Источник: realcoding.net

[1 страница]
Одно из главных затруднений, с которым сталкиваются разработчики интерфейсов веб-приложений, состоит в том, что после того, как страница оказалась в браузере клиента, связь браузера с сервером заканчивается. Любое действие с элементом интерфейса требует повторного обращения к серверу с повторной загрузкой новой страницы. Из-за этого веб-приложение теряет свою элегантность и медленно работает. В данной статье я расскажу о том, как данную проблему можно решить с помощью JavaScript и объекта XMLHttpRequest.

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

Возьмем простой пример ввода серийного номера в каком-либо Windows-приложении. Согласно правилам, после того, как вы закончите вводить замысловатый набор цифр и букв в поля, рядом с ними появится зеленая "галочка", означающая, что вы ввели правильный номер. Она появляется моментально, как результат логики "вшитой" в интерфейс. Как только вы закончили набирать номер, программа проверяет его и выдает ответ.

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

Разумеется не часто веб-приложение требует от пользователя ввести серийный номер, но есть бесчисленное множество других примеров, где быстрая реакция интерфейса на действия пользователя очень бы пригодилась. А так как вся программная логика находится на сервере, получить такой результат в традиционном веб-приложении весьма сложно.

На сцене появляется JavaScript


Благодаря JavaScript определенное количество программной логики можно перенести в HTML-страницу, что позволит быстро реагировать на действия пользователя. Однако у этого решения есть один главный недостаток. Первая проблема заключается в том, что как только JavaScript попадает в браузер пользователя вместе со страницей, программная логика доступна для просмотра невооруженным глазом. В случае например с проверкой правильности введенного адреса e-mail это может быть и не страшно, но если проверка связана с серийным номером, алгоритм проверки становится доступным всем, кто скачал страницу, а это неприемлемо.

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

Объект XMLHttpRequest


Решением этой проблемы может стать объект XMLHttpRequest. Этот объект впервые был реализован компанией Microsoft в виде объекта ActiveX, но сейчас он доступен как встроенный объект во всех браузерах Mozilla и Safari. Этот объект позволяет JavaScript-у осуществлять HTTP-запросы к удаленному серверу без необходимости перезагружать страницу. По сути HTTP-запросы отправляются и получаются полностью за "кулисами" страницы, а пользователь их даже не замечает.

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

Начнем с основ


Из-за своей противоречивой истории объект XMLHttpRequest еще не является частью какого-либо стандарта (хотя нечто подобное уже было предложено в спецификации W3C DOM Level 3 Load and Save). Поэтому существует два отличных друг от друга метода вызова этого объекта в коде скрипта. В Internet Explorer объект ActiveX вызывается так:

var req = new ActiveXObject(Microsoft.XMLHTTP);

В Mozilla и Safari это делается проще (так как там это объект, встроенный в JavaScript):

var req = new XMLHttpRequest();

Разумеется из-за таких различий вам необходимо создавать в коде ветки, каждая из которых будет выполняться в зависимости от того, в каком браузере загружен скрипт. Существует несколько способов, как сделать это (включая различные мудрёные хаки и метод "условных комментариев"). Но я считаю, что лучше всего просто проверять в коде, поддерживается ли браузером тот или иной объект. Хорошим примером может служить код, взятый с сайта Apple, где выложена документация по этому объекту. Давайте им и будем пользоваться:

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();
        }
    }
}

В этом коде особенно важно обратить внимание на свойство onreadystatechange. Посмотрите, как ему присваивается значение функции processReqChange. Это свойство - хендлер события, которое запускается всякий раз, когда меняется состояние объекта req. Состояния обозначаются номерами с 0 (объект неинициализирован) по 4 (запрос выполнен). Важно это потому, что наш скрипт не будет ждать ответа от сервера, чтобы продолжить свою работу. HTTP-запрос будет сформирован и отослан на сервер, но скрипт будет выполняться дальше. Из-за того, что мы выбрали такой вариант поведения, нам нельзя просто в конце функции вернуть результат запроса, так как нам неизвестно, получили мы его к этому времени или нет. Для этого мы и предусмотрели функцию processReqChange, которая будет отслеживать состояние объекта req, и сообщит нам в нужное время, что процесс получения документа закончен, и мы можем идти дальше.

Для этого функции processReqChange требуется проверять две вещи. Первая - ждать, когда состояние объекта req изменится на 4 (означающее, что процесс получения документа с сервера закончен). Второе, это проверить HTTP-статус ответа. Вы знаете, что код 404 означает "файл не найден" и 500 - "произошла ошибка на сервере". Но нам нужен старый добрый код 200 ("все ОК"), который означает, что на сервере наш запрос был успешно выполнен. Если мы получили и состояние 4 и код 200, мы можем продолжать выполнение нашего скрипта и обрабатывать результаты, полученные от сервера. Разумеется в противном случае мы должны обработать все ошибки, например, если код ответа отличается от 200.

function processReqChange()
{
   
// only if req shows complete
   
if (req.readyState == 4) {
       
// only if OK
       
if (req.status == 200) {
            
// ...processing statements go here...
       
} else {
            
alert(There was a problem retrieving
               the XML data:n
+ req.statusText);
        }
    }
}

На практике


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

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

Форма


Это самая легкая часть работы - простая форма с полем для ввода "ника". К событию onblur мы привязываем наш скрипт проверки. Для того, чтобы вывести пользователю сообщение о результатах проверки, я вставил его в форму и спрятал с помощью CSS. Это более элегантный и вежливый способ, чем стандартное диалоговое окно функции alert().

<input id=username name=username type=text
 
onblur=checkName(this.value,) />
<
span class=hidden id=nameCheckFailed>
 
This name is in use, please try another.
</
span>

В CSS объявлены свойства класса hidden, а также еще одного класса error, который служит для вывода сообщений об ошибке.

span.hidden{
 
display: none;
}

span.error{
 
display: inline;
 
color: black;
 
background-color: pink
}



Похожие статьи:
- Подпись или аватар на пхп
- Сбор статистики на PHP
- Классы и объекты в РНР со Штирлицом и Мюллером
- Как назвать Web-сайт?
- Дядя Гугл — великан
- Разработка фирменного стиля
- Сверхдинамичные веб-интерфейсы
- Оптимизация для MSN
- RSS генератор
- Шаблоны в PHP для чайников
- Гостевая книга на PHP
- В каких поисковиках надо раскручиваться?
- Использование HTML-таблиц для вывода диаграмм


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |

Контакты
Редакция:
[0.001]