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

Далее описывается, как генерируются эти новые события в броузерах, поддерживающих их. Когда вызывается метод

<b>send(),</b>
один раз возбуждается событие «load-start». В ходе загрузки ответа сервера объект
<b>XMLHttpRequest</b>
возбуждает серию событий «progress», обычно каждые 50 миллисекунд или около того, которые можно использовать для обратной связи с пользователем, чтобы информировать его о ходе выполнения запроса. Если запрос завершается очень быстро, событие «progress» может и не возбуждаться. По завершении запроса возбуждается событие «load».

Завершение запроса не всегда означает успешное его выполнение, поэтому обработчик события «load» должен проверять код состояния в объекте

<b>XMLHttpRequest</b>
, чтобы убедиться, что был принят НТТР-код «200 ОК», а не «404 Not Found», например.

Существуют три разные ситуации, когда HTTP-запрос оканчивается неудачей, которым соответствуют три события. Если предельное время ожидания ответа истекло, генерируется событие «timeout». Если выполнение запроса было прервано, генерируется событие «abort». (О предельном времени ожидания и о методе

<b>abort()</b>
подробнее рассказывается в 18.1.5.) Наконец, выполнению запроса могут препятствовРть другие ошибки в сети, такие как слишком большое количество переадресаций, и в этих случаях генерируется событие «error».

Для каждого запроса броузер может возбуждать только по одному событию «load», «abort», «timeout» и «error». Проект спецификации «ХНН2» требует, чтобы броузеры возбуждали событие «loadend» после одного из этих событий. Однако на момент написания этих строк событие «loadend» не было реализовано ни в одном из броузеров.

Для регистрации обработчиков всех этих событий, возникающих в ходе выполнения запроса, можно использовать метод

<b>addEventListener()</b>
объекта
<b>XMLHttpRequest</b>
. Если каждое из этих событий обрабатывается единственным обработчиком, эти обработчики обычно проще установить, присвоив их соответствующим свойствам объекта, таким как
<b>onprogress</b>
и
<b>onload</b>
. Определяя наличие этих свойств, можно даже проверить поддержку соответствующих событий в броузере:

<b>if (&quot;onprogress&quot; in (new XMLHttpRequest())) {</b>

<b>  // События, возникающие в ходе выполнения запроса, поддерживаются</b>

<b>}</b>

Объект события, связанный с этими событиями, возникающими в ходе выполнения запроса, в дополнение к свойствам обычного объекта

<b>Event</b>
, таким как
<b>type</b>
и
<b>timestamp</b>
, добавляет три полезных свойства. Свойство
<b>loaded</b>
определяет количество байтов, переданных к моменту возбуждения события. Свойство
<b>total</b>
содержит общий объем (в байтах) загружаемых данных, определяемый из заголовка «Content-Length», или 0, если объем содержимого не известен. Наконец, свойство
<b>lengthComputable</b>
содержит значение true, если общий объем содержимого известен, и false - в противном случае. Очевидно, что свойства
<b>total</b>
и
<b>loaded</b>
особенно полезны в обработчиках событий, возникающих в ходе выполнения запроса:

<b>request.onprogress = function(e) { </b>

<b>  if (e.lengthComputable)</b>

<b>    progress.innerHTML = Math.round(100*e.loaded/e.total) + ”% Выполнено&quot;;</b>

<b>}</b>

18.1.4.1. События, возникающие в ходе выгрузки

Кроме событий, которые удобно использовать для мониторинга загрузки НТТР-ответа, спецификация «ХНН2» также определяет события для мониторинга выгрузки HTTP-запроса. В броузерах, реализующих эту возможность, объект

<b>XMLHttpRequest</b>
имеет свойство
<b>upload</b>
. Значением свойства
<b>upload</b>
является объект, определяющий метод
<b>addEventListener()</b>
и полный набор свойств-событий хода выполнения операции выгрузки, таких как
<b>onprogress</b>
и
<b>onload</b>
. (Однако этот объект не определяет свойство
<b>onreadystatechange</b>
: в процессе выгрузки генерируются только эти новые события.)

Обработчики событий хода выполнения операции выгрузки можно использовать точно так же, как используются обычные обработчики событий хода выполнения загрузки. Для объекта х типа

<b>XMLHttpRequest</b>
обработчик
<b>х.onprogress</b>
позволяет вести мониторинг хода выполнения загрузки ответа. А свойство
<b>х.upload.onprogress</b>
- мониторинг хода выполнения выгрузки запроса.

Пример 18.11 демонстрирует, как использовать событие «progress», генерируемое в ходе выгрузки запроса, для организации обратной связи с пользователем. Этот пример также демонстрирует, как получать объекты

<b>File</b>
с применением механизма буксировки (drag-and-drop) и как с помощью объекта
<b>FormData</b>
выгружать сразу несколько файлов в одном запросе
<b>XMLHttpRequest</b>
. На момент написания этих строк спецификации, определяющие эти особенности, находились в состоянии проектирования и этот пример работал не во всех броузерах.

Пример 18.11. Мониторинг хода выполнения операции выгрузки

<b>// Отыскивает все элементы с классом &quot;fileDropTarget&quot; и регистрирует </b>

<b>// обработчики событий механизма DnD, чтобы они могли откликаться </b>

<b>// на операции буксировки файлов. При сбросе файлов на эти элементы </b>

<b>// они выгружают их на URL-адрес, указанный в атрибуте data-uploadto. </b>

<b>whenReady(function() {</b>

<b>  var elts = document.getElementsByClassName(&quot;fileDropTarget&quot;);</b>

<b>  for(var і = 0; і &lt; elts.length; i++) {</b>

<b>    var target = elts[i];</b>