Флаг асинхронности немного отличается почти от всего остального в JavaScript. Если этот флаг задан как false, то код продолжает выполняться, как и любой другой фрагмент кода, то есть он ожидает, пока объект XMLHttp завершит свою работу, прежде чем двигаться дальше. Однако, если этот флаг задан как true, то код продолжает делать то, что следует в коде после запроса. Когда состояние запроса изменяется, вызывается функция, которая определена в onreadystatechange.
В чем различие? Если флаг асинхронности задан как false, то браузер будет полностью заблокирован, пока обрабатывается запрос. Если запрошенные данные нужны в обязательном порядке для продолжения работы, то используйте это значение флага. Если флаг задан как true, то пользователь может продолжать использовать Web-страницу, но ничего не известно о том, когда вернется ответ на запрос. Может потребоваться 1/2 секунды или 1 минута. Все зависит от нагрузки на сервер и соединения конечного пользователя.
Когда все готово, посылается запрос. Затем мы ожидаем. Если запрос выполняется синхронно с функцией обработки, определенной с помощью onreadystatechange, то она будет вызываться несколько раз. На самом деле она вызывается всякий раз при изменении состояния запроса. Существуют различные состояния, такие, как отправка и загрузка данных, но нас интересует только завершение загрузки данных. Если readyState == 4, то запрос выполнен, поэтому в любом другом случае мы просто выходим из функции.
Теперь мы получили данные, но что это за данные?
Существует три возможных варианта получения данных: XML, JSON или обычный текст. При извлечении данных из базы данных, скорее всего, будет использоваться XML или JSON. Ни один из этих вариантов не имеет явных преимуществ. XML - широко распространенный стандарт, и поэтому существует много приложений, которые работают с файлами XML. JSON является более новой идеей, но быстро становится популярным. Его обычно легче прочитать (для человека), и он требует немного меньшую полосу пропускания для пересылки.
Предположим, что создается приложение для управления контактами. Cервер может возвращать информацию о людях. Одни и те же данные можно выразить в форме XML или JSON:
XML:
JSON:
{contacts:[
{"firstname":"Joe", "lastname":"Smith", "phone":"555-1212"},
{"firstname":"Sam", "lastname":"Stevens", "phone":"123-4567"}
]}
Можно видеть, что нотация XML выглядит очень похоже на HTML. По большей части это так и есть. HTML и XML оба являются основанными на тегах языками и могут даже анализироваться одинаковым образом (см. Лекция 6).
Нотация JSON выглядит очень похоже на простой JavaScript. JSON означает JavaScript Object Notation и поэтому действительно является обычным JavaScript.
Данные в любой нотации можно посылать с Web-сервера просто как обычный текст. Никакие пробелы, имеющиеся в этих примерах, не нужны, за исключением одиночных пробелов между именами атрибутов в тегах person (в версии XML).
Формат XML является совокупностью тегов, очень похожих на HTML. Можно иметь любое количество тегов, вложенных друг в друга, и каждый тег может иметь любое количество атрибутов: например, firstname, lastname и phone в примере выше. Однако имеется несколько вещей, за которыми необходимо следить.
[x].
Каждый тег должен иметь закрывающий тег. Например, закрывается с помощью расположенного ниже . Теги person являются замкнутыми. /> в конце действует по сути как дополнительный закрывающий тег. Можно было так же легко написать один из них как ... >.
[x].
XML имеет ограниченный набор символов, которые можно использовать. В частности следующие символы являются недопустимыми в узлах и атрибутах и должны заменяться специальными комбинациями:
& | --> | & |
< | --> | < |
> | --> | > |
" | --> | " |
' | --> | ' |
Например, узел является недопустимым и должен быть заменен на .
[x].
Приходящие с сервера данные должны посылаться с content-type, заданным как text/xml. Если извлекается файл с расширением .xml, то это должно происходить автоматически. Если данные извлекаются из сценария, необходимо задавать это вручную.
Для PHP добавьте следующее:
Для ASP добавьте:
<% response.contentType = "text/xml" %>
[x].
Для всех других языков добавьте эквивалентный заголовок content-type.
Если этот заголовок не задан, свойство responseXML объекта XMLHttp будет пустым (это свойство будет описано далее).