С чего начать

  • Revision slug: AJAX/С_чего_начать
  • Revision title: С чего начать
  • Revision id: 273303
  • Created:
  • Creator: Megapotz
  • Is current revision? Нет
  • комментировать

Revision Content

В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.

Что такое AJAX?

Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest(), необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовых файлах. Самое привлекательное в Ajax — это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя

Две особенности, которые мы рассмотрим:

  • Отправление запросов серверу без перезагрузки страницы
  • Работа с XML документами

Шаг 1 — скажите «Пожалуйста!» или как послать HTTP запрос

Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый XMLHTTP. Позже в Mozilla, Safari и другие броузеры был введен класс XMLHttpRequest, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.

В результате, чтобы создать кросс-броузерный объект требуемого класса, вы можете сделать:

if (window.XMLHttpRequest) { // Mozilla, Safari, ...
    http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
    http_request = new ActiveXObject("Microsoft.XMLHTTP");
}

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

Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML mime-type. Чтобы решить эту проблему вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от text/xml.

http_request = new XMLHttpRequest();
http_request.overrideMimeType('text/xml');

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

http_request.onreadystatechange = nameOfTheFunction;

Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:

http_request.onreadystatechange = function(){
    // do the thing
};

Далее, после того как вы объявили что будет происходить после получения ответа, вам необходимо сделать запрос. Вы должны вызвать методы класса open() и send():

http_request.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null);
  • Первый параметр вызова функции open() — метод запроса HTTP (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами; иначе некоторые броузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу W3C specs
  • Второй параметр — URL запрашиваемой страницы. Из соображений безопасности вы не можете запрашивать страницы сторонних доменов. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку 'доступ запрещен' при вызове функции open(). Типичной ошибкой при доступе к сайту через <tt>site.ru</tt> является подача запросов на <tt>www.site.ru</tt>.
  • Третий параметр указывает, является ли запрос асинхронным. Если он TRUE, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом заключается асинхронный принцип работы.

Параметром метода send() могут быть любые данные, которые вы хотите послать на сервер методом POST. Данные должны быть сформированы в строку запроса:

name=value&anothername=othervalue&so=on

Заметьте, что если вы хотите отправить данные методом POST, вы должны изменить MIME-тип запроса с помощью следующей строки:

http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

Иначе сервер проигнорирует данные отправленные методом POST.

Шаг 2 — «Ничего страшного!» или обрабатываем HTTP ответ

Запомните, что отправляя запрос вы указали имя функции JavaScript, обрабатывающую ответ.

http_request.onreadystatechange = nameOfTheFunction;

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

if (http_request.readyState == 4) {
    // everything is good, the response is received
} else {
    // still not ready
}

Полный список значений кодов readyState такой:

  • 0 (uninitialized)
  • 1 (loading)
  • 2 (loaded)
  • 3 (interactive)
  • 4 (complete)

(Source)

Следующее, что нужно проверить — это статус HTTP-ответа. Все возможные коды можно посмотреть на W3C site. Для наших целей нам интересен только код ответа 200 OK.

if (http_request.status == 200) {
    // perfect!
} else {
    // there was a problem with the request,
    // for example the response may be a 404 (Not Found)
    // or 500 (Internal Server Error) response codes
}

Теперь, после того как мы проверили состояние запроса и статус HTTP-ответа вы можете делать с данными, полученными от сервера, все что вам угодно. Есть два способа получить доступ к данным:

  • http_request.responseText – возвращает ответ сервера в виде строки текста.
  • http_request.responseXML – возвращает ответ сервера в виде объекта XMLDocument, который вы можете обходить используя функции JavaScript DOM

Шаг 3 — «А теперь все вместе!» — простой пример

Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ test.html, который содержит текст "I'm a test." и выведет содержимое файла в диалоговом окне.

<script type="text/javascript" language="javascript">
    function makeRequest(url) {
        var http_request = false;

        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/xml');
                // Читайте ниже об этой строке
            }
        } else if (window.ActiveXObject) { // IE
            try {
                http_request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    http_request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
            }
        }

        if (!http_request) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
        }
        http_request.onreadystatechange = function() { alertContents(http_request); };
        http_request.open('GET', url, true);
        http_request.send(null);

    }

    function alertContents(http_request) {

        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                alert(http_request.responseText);
            } else {
                alert('There was a problem with the request.');
            }
        }

    }
</script>
<span
    style="cursor: pointer; text-decoration: underline"
    onclick="makeRequest('test.html')">
        Make a request
</span>


В этом примере:

  • Пользователь нажимает на ссылку "Make a request" в броузере;
  • Это вызывает функцию makeRequest() с параметром test.html — именем HTML файла;
  • Посылается запрос, после чего (onreadystatechange) выполнение передается alertContents();
  • alertContents() проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла test.html выводится в диалоговом окне.

Вы можете попробовать пример в действии здесь, а сам тестовый файл можно посмотреть здесь.

Замечание: Строка http_request.overrideMimeType('text/xml'); вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано на https://bugzilla.mozilla.org/show_bug.cgi?id=311724, если страница вызванная с помощью XMLHttpRequest не является валидным XML (например, если это обычный текст). На самом деле это корректное поведение.

Замечание 2: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок Content-Type: application/xml, IE будет сообщать об ошибке JavaScript, 'Object Expected', после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок Cache-Control: no-cache броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что делает отладку весьма «забавной».

Замечание 3: Если переменная http_request используется глобально, то конкурирующие функции, вызывающие makeRequest() могут перезаписывать друг друга, вызывая состязания. Объявление переменной http_request локально в функции и передача ее в alertContent() предотвращает состязания.

Замечание 4: При привязывании функции обратного вызова к onreadystatechange нельзя указывать аргументов. По этой причине не работает следующий код:

http_request.onreadystatechange = alertContents(http_request); // (does not work)

Таким образом, для успешной регистрации функции, вы должны передать ей аргументы косвенно через анонимную функцию или используя http_request как глобальную переменную. Вот пример:

http_request.onreadystatechange = function() { alertContents(http_request); };  //1 (simultaneous request)
http_request.onreadystatechange = alertContents;  //2 (global variable)

Первый способ позволяет делать несколько запросов одновременно, а второй метод используется, когда переменная http_request является глобальной.


Замечание 5: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной .status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (Смотри: https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

function alertContents(http_request) {

        try {
            if (http_request.readyState == 4) {
                if (http_request.status == 200) {
                    alert(http_request.responseText);
                } else {
                    alert('There was a problem with the request.');
                }
            }
        }
        catch( e ) {
            alert('Caught Exception: ' + e.description);
        }

    }

Шаг 4 — «X-Файлы» или работа с XML ответом

В предыдущем примере, после того как был получен ответ HTTP-запрос мы использовали responseText запрашиваемого объекта, который содержал данные файла <tt>test.html</tt>. Теперь давайте попробуем использовать свойство responseXML.

Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (<tt>test.xml</tt>) содержит следующее:

<?xml version="1.0" ?>
<root>
    I'm a test.
</root>

В скрипте нам всего лишь необходимо заменить строку запроса на:

...
onclick="makeRequest('test.xml')">
...

Then in alertContents(), we need to replace the line alert(http_request.responseText); with:

var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);

Этот код берет объект XMLDocument, возвращаемый responseXML и использует методы DOM для доступа к некоторым данным, содержащимся в документе XML. Посмотреть test.xml This code takes the XMLDocument object given by responseXML and uses DOM methods to access some of the data contained in the XML document. You can see the test.xml можно здесь, а обновленный скрипт здесь.

Чтобы узнать больше о методах DOM, посмотрите Mozilla's DOM implementation.

{{ wiki.languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }}

Revision Source

<p>
</p><p>В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.
</p>
<h3 name=".D0.A7.D1.82.D0.BE_.D1.82.D0.B0.D0.BA.D0.BE.D0.B5_AJAX.3F"> Что такое AJAX? </h3>
<p>Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest(), необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовых файлах. Самое привлекательное в Ajax — это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя
</p><p>Две особенности, которые мы рассмотрим:
</p>
<ul><li> Отправление запросов серверу без перезагрузки страницы
</li><li> Работа с XML документами
</li></ul>
<h3 name=".D0.A8.D0.B0.D0.B3_1_.E2.80.94_.D1.81.D0.BA.D0.B0.D0.B6.D0.B8.D1.82.D0.B5_.C2.AB.D0.9F.D0.BE.D0.B6.D0.B0.D0.BB.D1.83.D0.B9.D1.81.D1.82.D0.B0.21.C2.BB_.D0.B8.D0.BB.D0.B8_.D0.BA.D0.B0.D0.BA_.D0.BF.D0.BE.D1.81.D0.BB.D0.B0.D1.82.D1.8C_HTTP_.D0.B7.D0.B0.D0.BF.D1.80.D0.BE.D1.81"> Шаг 1 — скажите «Пожалуйста!» или как послать HTTP запрос </h3>
<p>Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый <code>XMLHTTP</code>. Позже в Mozilla, Safari и другие броузеры был введен класс <code>XMLHttpRequest</code>, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.
</p><p>В результате, чтобы создать кросс-броузерный объект требуемого класса, вы можете сделать:
</p>
<pre>if (window.XMLHttpRequest) { // Mozilla, Safari, ...
    http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
    http_request = new ActiveXObject("Microsoft.XMLHTTP");
}
</pre>
<p>(В целях наглядности код выше является немного упрощенным. Более жизненный пример будет рассмотрен в шаге 3 этой статьи)
</p><p>Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML <code>mime-type</code>. Чтобы решить эту проблему вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от <code>text/xml</code>.
</p>
<pre>http_request = new XMLHttpRequest();
http_request.overrideMimeType('text/xml');
</pre>
<p>Далее вам необходимо решить, что вы будете делать после получения ответа от сервера. На этом этапе вам необходимо указать объекту, какая JavaScript функция будет обрабатывать ответ. Это делается путем присваивания свойству <code>onreadystatechange</code> имени JavaScript функции, которую вы собираетесь использовать:
</p><p><code>http_request.onreadystatechange = nameOfTheFunction;</code>
</p><p>Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:
</p>
<pre>http_request.onreadystatechange = function(){
    // do the thing
};
</pre>
<p>Далее, после того как вы объявили что будет происходить после получения ответа, вам необходимо сделать запрос. Вы должны вызвать методы класса <code>open()</code> и <code>send()</code>:
</p>
<pre>http_request.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null);
</pre>
<ul><li> Первый параметр вызова функции <code>open()</code> — метод запроса HTTP (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами; иначе некоторые броузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу <a class="external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">W3C specs</a> 
</li><li> Второй параметр — URL запрашиваемой страницы. Из соображений безопасности вы не можете запрашивать страницы сторонних доменов. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку 'доступ запрещен' при вызове функции <code>open()</code>. Типичной ошибкой при доступе к сайту через <tt>site.ru</tt> является подача запросов на <tt>www.site.ru</tt>.
</li><li> Третий параметр указывает, является ли запрос асинхронным. Если он <code>TRUE</code>, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом заключается асинхронный принцип работы.
</li></ul>
<p>Параметром метода <code>send()</code> могут быть любые данные, которые вы хотите послать на сервер методом <code>POST</code>. Данные должны быть сформированы в строку запроса:
</p><p><code>name=value&amp;anothername=othervalue&amp;so=on</code>
</p><p>Заметьте, что если вы хотите отправить данные методом <code>POST</code>, вы должны изменить MIME-тип запроса с помощью следующей строки: 
</p>
<pre>http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
</pre>
<p>Иначе сервер проигнорирует данные отправленные методом POST.
</p>
<h3 name=".D0.A8.D0.B0.D0.B3_2_.E2.80.94_.C2.AB.D0.9D.D0.B8.D1.87.D0.B5.D0.B3.D0.BE_.D1.81.D1.82.D1.80.D0.B0.D1.88.D0.BD.D0.BE.D0.B3.D0.BE.21.C2.BB_.D0.B8.D0.BB.D0.B8_.D0.BE.D0.B1.D1.80.D0.B0.D0.B1.D0.B0.D1.82.D1.8B.D0.B2.D0.B0.D0.B5.D0.BC_HTTP_.D0.BE.D1.82.D0.B2.D0.B5.D1.82"> Шаг 2 — «Ничего страшного!» или обрабатываем HTTP ответ </h3>
<p>Запомните, что отправляя запрос вы указали имя функции JavaScript, обрабатывающую ответ.
</p><p><code>http_request.onreadystatechange = nameOfTheFunction;</code>
</p><p>Давайте посмотрим, что эта функция должна делать. Во-первых, функция должна проверять статус запроса. Если значения переменной статуса 4, то это означает, что ответ от сервера получен и его можно обрабатывать. 
</p>
<pre>if (http_request.readyState == 4) {
    // everything is good, the response is received
} else {
    // still not ready
}
</pre>
<p>Полный список значений кодов <code>readyState</code> такой:
</p>
<ul><li> 0 (uninitialized)
</li><li> 1 (loading)
</li><li> 2 (loaded)
</li><li> 3 (interactive)
</li><li> 4 (complete)
</li></ul>
<p>(<a class="external" href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp">Source</a>)
</p><p>Следующее, что нужно проверить — это статус HTTP-ответа. Все возможные коды можно посмотреть на <a class="external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">W3C site</a>. Для наших целей нам интересен только код ответа <code>200 OK</code>.
</p>
<pre>if (http_request.status == 200) {
    // perfect!
} else {
    // there was a problem with the request,
    // for example the response may be a 404 (Not Found)
    // or 500 (Internal Server Error) response codes
}
</pre>
<p>Теперь, после того как мы проверили состояние запроса и статус HTTP-ответа вы можете делать с данными, полученными от сервера, все что вам угодно. Есть два способа получить доступ к данным:
</p>
<ul><li> <code>http_request.responseText</code> – возвращает ответ сервера в виде строки текста.
</li><li> <code>http_request.responseXML</code> – возвращает ответ сервера в виде объекта <code>XMLDocument</code>, который вы можете обходить используя функции JavaScript DOM
</li></ul>
<h3 name=".D0.A8.D0.B0.D0.B3_3_.E2.80.94_.C2.AB.D0.90_.D1.82.D0.B5.D0.BF.D0.B5.D1.80.D1.8C_.D0.B2.D1.81.D0.B5_.D0.B2.D0.BC.D0.B5.D1.81.D1.82.D0.B5.21.C2.BB.C2.A0.E2.80.94_.D0.BF.D1.80.D0.BE.D1.81.D1.82.D0.BE.D0.B9_.D0.BF.D1.80.D0.B8.D0.BC.D0.B5.D1.80"> Шаг 3 — «А теперь все вместе!» — простой пример </h3>
<p>Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ <code>test.html</code>, который содержит текст "I'm a test." и выведет содержимое файла в диалоговом окне.
</p>
<pre>&lt;script type="text/javascript" language="javascript"&gt;
    function makeRequest(url) {
        var http_request = false;

        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/xml');
                // Читайте ниже об этой строке
            }
        } else if (window.ActiveXObject) { // IE
            try {
                http_request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    http_request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
            }
        }

        if (!http_request) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
        }
        http_request.onreadystatechange = function() { alertContents(http_request); };
        http_request.open('GET', url, true);
        http_request.send(null);

    }

    function alertContents(http_request) {

        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                alert(http_request.responseText);
            } else {
                alert('There was a problem with the request.');
            }
        }

    }
&lt;/script&gt;
&lt;span
    style="cursor: pointer; text-decoration: underline"
    onclick="makeRequest('test.html')"&gt;
        Make a request
&lt;/span&gt;
</pre>
<p><br>
В этом примере:
</p>
<ul><li> Пользователь нажимает на ссылку "Make a request" в броузере;
</li><li> Это вызывает функцию <code>makeRequest()</code> с параметром <code>test.html</code> — именем HTML файла;
</li><li> Посылается запрос, после чего (<code>onreadystatechange</code>) выполнение передается <code>alertContents()</code>;
</li><li> <code>alertContents()</code> проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла <code>test.html</code> выводится в диалоговом окне.
</li></ul>
<p>Вы можете попробовать пример в действии <a class="external" href="http://www.w3clubs.com/mozdev/httprequest_test.html">здесь</a>, а сам тестовый файл можно посмотреть <a class="external" href="http://www.w3clubs.com/mozdev/test.html">здесь</a>.
</p><p><b>Замечание</b>: Строка <code>http_request.overrideMimeType('text/xml');</code> вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано на https://bugzilla.mozilla.org/show_bug.cgi?id=311724, если страница вызванная с помощью XMLHttpRequest не является валидным XML (например, если это обычный текст). На самом деле это корректное поведение.
</p><p><b>Замечание 2</b>: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок <code>Content-Type: application/xml</code>, IE будет сообщать об ошибке JavaScript, 'Object Expected', после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок <code>Cache-Control: no-cache</code> броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что делает отладку весьма «забавной».
</p><p><b>Замечание 3</b>: Если переменная <code>http_request</code> используется глобально, то конкурирующие функции, вызывающие <code>makeRequest()</code> могут перезаписывать друг друга, вызывая состязания.  Объявление переменной <code>http_request</code> локально в функции и передача ее в <code>alertContent()</code> предотвращает состязания.
</p><p><b>Замечание 4</b>: При привязывании функции обратного вызова к <code>onreadystatechange</code> нельзя указывать аргументов. По этой причине не работает следующий код:
</p>
<pre>http_request.onreadystatechange = alertContents(http_request); // (does not work)
</pre>
<p>Таким образом, для успешной регистрации функции, вы должны передать ей аргументы косвенно через анонимную функцию или используя <code>http_request</code> как глобальную переменную. Вот пример:
</p>
<pre>http_request.onreadystatechange = function() { alertContents(http_request); };  //1 (simultaneous request)
http_request.onreadystatechange = alertContents;  //2 (global variable)
</pre>
<p>Первый способ позволяет делать несколько запросов одновременно, а второй метод используется, когда переменная <code>http_request</code> является глобальной.
</p><p><br>
<b>Замечание 5</b>: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной .status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (Смотри: https://bugzilla.mozilla.org/show_bug.cgi?id=238559).
</p>
<pre>function alertContents(http_request) {

        try {
            if (http_request.readyState == 4) {
                if (http_request.status == 200) {
                    alert(http_request.responseText);
                } else {
                    alert('There was a problem with the request.');
                }
            }
        }
        catch( e ) {
            alert('Caught Exception: ' + e.description);
        }

    }
</pre>
<h3 name=".D0.A8.D0.B0.D0.B3_4.C2.A0.E2.80.94_.C2.ABX-.D0.A4.D0.B0.D0.B9.D0.BB.D1.8B.C2.BB_.D0.B8.D0.BB.D0.B8_.D1.80.D0.B0.D0.B1.D0.BE.D1.82.D0.B0_.D1.81_XML_.D0.BE.D1.82.D0.B2.D0.B5.D1.82.D0.BE.D0.BC"> Шаг 4 — «X-Файлы» или работа с XML ответом </h3>
<p>В предыдущем примере, после того как был получен ответ HTTP-запрос мы использовали <code>responseText</code> запрашиваемого объекта, который содержал данные файла <tt>test.html</tt>. Теперь давайте попробуем использовать свойство <code>responseXML</code>.
</p><p>Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (<tt>test.xml</tt>) содержит следующее:
</p>
<pre>&lt;?xml version="1.0" ?&gt;
&lt;root&gt;
    I'm a test.
&lt;/root&gt;
</pre>
<p>В скрипте нам всего лишь необходимо заменить строку запроса на:
</p>
<pre>...
onclick="makeRequest('test.xml')"&gt;
...
</pre>
<p>Then in <code>alertContents()</code>, we need to replace the line <code>alert(http_request.responseText);</code> with:
</p>
<pre>var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);
</pre>
<p>Этот код берет объект <code>XMLDocument</code>, возвращаемый <code>responseXML</code> и использует методы DOM для доступа к некоторым данным, содержащимся в документе XML. Посмотреть <code>test.xml</code> 
This code takes the <code>XMLDocument</code> object given by <code>responseXML</code> and uses DOM methods to access some of the data contained in the XML document. You can see the <code>test.xml</code> можно <a class="external" href="http://www.w3clubs.com/mozdev/test.xml">здесь</a>, а обновленный скрипт <a class="external" href="http://www.w3clubs.com/mozdev/httprequest_test_xml.html">здесь</a>.
</p><p>Чтобы узнать больше о методах DOM, посмотрите <a class="external" href="http://www.mozilla.org/docs/dom/">Mozilla's DOM implementation</a>.
</p>{{ wiki.languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }}
Revert to this revision