JavaScript. Подробное руководство, 6-е издание, стр. 278

******************************************

18.1.2. Получение ответа

Полный HTTP-ответ содержит код состояния, набор заголовков ответа и тело ответа. Все это доступно в виде свойств и методов объекта

<b>XMLHttpRequest</b>
:

• Свойства

<b>status</b>
и
<b>statusText</b>
возвращают код состояния HTTP в числовом и текстовом виде. Эти свойства хранят стандартные HTTP-значения, такие как 200 и «ОК» в случае успешного выполнения запроса или 404 и «Not Found» при попытке обратиться к ресурсу, отсутствующему на сервере.

• Заголовки ответа можно получить с помощью методов

<b>getResponseHeader()</b>
и
<b>getAllResponseHeaders().</b>
Обработка cookies выполняется объектом
<b>XMLHttpRequest</b>
автоматически: он исключает заголовки «Cookie» из множества, возвращаeмого методом
<b>getAllResponseHeaders(),</b>
и возвращает null, если передать аргумент «Set-Cookie» или «Set-Cookie2» методу
<b>getResponseHeader().</b>

• Тело ответа в текстовом виде доступно через свойство

<b>responseText</b>
или в виде объекта
<b>Document</b>
через свойство
<b>responseXML</b>
. (Выбор такого имени свойства объясняется историческими причинами: фактически оно предназначено для работы с XHTML- и XML-документами, но спецификация «ХНН2» определяет, что оно также должно работать с обычными HTML-документами.) Более подробно о свойстве
<b>responseXML</b>
рассказывается в разделе 18.1.2.2.

Обычно объект

<b>XMLHttpRequest</b>
используется в асинхронном режиме (но загляните в раздел 18.1.2.1): метод
<b>send()</b>
возвращает управление сразу же после отправки запроса, поэтому методы и свойства, перечисленные выше, не могут использоваться до фактического получения ответа. Чтобы определить момент получения ответа, необходимо обрабатывать событие «readystatechange» (или событие «progress», определяемое новой спецификацией «ХНН2» и описываемое в разделе 18.1.4), возбуждаемое в объекте
<b>XMLHttpRequest</b>
. Но, чтобы понять, как обрабатывать это событие, необходимо сначала разобраться со свойством
<b>readyState</b>
.

Свойство

<b>readyState</b>
- это целочисленное значение, определяющее код состояния HTTP-запроса; его возможные значения перечислены в табл. 18.1. Идентификаторы, указанные в первой колонке, - это константы, определяемые конструктором
<b>XMLHttpRequest</b>
. Эти константы являются частью спецификации
<b>XMLHttpRequest</b>
, но старые версии броузеров и ІE8 не определяют их, поэтому часто можно увидеть программный код, в котором вместо константы
<b>XMLHttpRequest.DONE</b>
используется числовое значение 4.

Теоретически событие «readystatechange» генерируется всякий раз, когда изменяется значение свойства

<b>readyState</b>
. На практике же событие может не возбуждаться, когда свойство
<b>readyState</b>
получает значение 0 или 1. Оно часто возбуждается при вызове метода
<b>send(),</b>
даже при том, что свойство
<b>readyState</b>
по-прежнему содержит значение
<b>OPENED</b>
. Некоторые броузеры возбуждают событие множество раз для состояния
<b>LOADING</b>
, чтобы обеспечить обратную связь. Все броузеры возбуждают событие «readystatechange», когда завершается прием ответа сервера и свойство
<b>readyState</b>
получает значение 4. Так как это событие может возбуждаться еще до завершения приема ответа, обработчики события «readystatechange» всегда должны проверять значение свойства
<b>readyState</b>
.

Чтобы обрабатывать события «readystatechange», нужно присвоить функцию обработчика события свойству

<b>onreadystatechange</b>
объекта
<b>XMLHttpRequest</b>
. Можно также воспользоваться методом
<b>addEventListener()</b>
(или
<b>attachEvent()</b>
в IE версии 8 и ниже), но обычно для обработки запроса бывает вполне достаточно одного обработчика, поэтому проще установить свойство
<b>onreadystatechange</b>
.

JavaScript. Подробное руководство, 6-е издание - i_032.jpg

Пример 18.2 определяет функцию

<b>getText(),</b>
которая демонстрирует особенности обработки событий «ready statechange». Обработчик события сначала проверяет завершение запроса. После этого он проверяет код состояния ответа и убеждается в успешном выполнении. Затем он извлекает заголовок «Content-Type», чтобы убедиться, что получен ответ ожидаемого типа. Если выполняются все три условия, он передает тело ответа (в виде текста) указанной функции обратного вызова.

Пример 18.2. Получение HTTP-ответа в обработчике

<b>onreadystatechange</b>

<b>// Выполняет запрос HTTP GET содержимого указанного URL-адреса.</b>

<b>// После успешного получения ответа проверяет, содержит ли он простой текст,</b>

<b>// и передает его указанной функции обратного вызова </b>

<b>function getText(url, callback) {</b>

<b>  var request = new XMLHttpRequest(); // Создать новый запрос</b>

<b>  request.open(&quot;GET&quot;, url); // Указать URL-адрес ресурса</b>

<b>  request.onreadystatechange = function() {</b>

<b>    // Определить обработчик события</b>

<b>    // Если запрос был выполнен успешно</b>

<b>    if (request.readyState === 4 &amp;&amp; request.status === 200) {</b>

<b>      var type = request.getResponseHeader(&quot;Content-Type&quot;);</b>

<b>      if (type.fnatch(/~text/)) // Убедиться, что это текст</b>

<b>        callback(request.responseText); // Передать функции</b>