mozilla

Сравнить версии

С чего начать

Change Revisions

Ревизия 273309:

Версия 273309 пользователя Megapotz, сделанная

Ревизия 212664:

Версия 212664 пользователя Megapotz, сделанная

Заголовок:
С чего начать
С чего начать
Slug:
AJAX/С_чего_начать
AJAX/С_чего_начать
Метки:
AJAX
Содержимое:

Ревизия 273309
Ревизия 212664
t7    <p>t
8      &nbsp;
9    </p>
10    <p>
11      В этой статье рассмотрены основные принципы работы AJAX и д
>аны два простых примера, использующих эту технологию. 
12    </p>
13    <h3 id=".D0.A7.D1.82.D0.BE_.D1.82.D0.B0.D0.BA.D0.BE.D0.B5_AJA
>X.3F" name=".D0.A7.D1.82.D0.BE_.D1.82.D0.B0.D0.BA.D0.BE.D0.B5_AJA 
>X.3F"> 
14      Что такое AJAX?
15    </h3>
16    <p>
17      Ajax означает Асинхронный JavaScript и XML. В основе технол
>огии лежит использование нестандартного объекта <code><a href="/r 
>u/XMLHttpRequest" title="ru/XMLHttpRequest">XMLHttpRequest</a></c 
>ode>, необходимого для взаимодействия со скриптами на стороне сер 
>вера. Объект может как отправлять, так и получать информацию в ра 
>зличных форматах включая XML, HTML и даже текстовые файлы. Самое  
>привлекательное в Ajax&nbsp;— это его асинхронный принцип работы. 
> С помощью этой технологии можно осуществлять взаимодействие с се 
>рвером без необходимости перезагрузки страницы. Это позволяет обн 
>овлять содержимое страницы частично, в зависимости от действий по 
>льзователя. 
18    </p>
19    <p>
20      Две особенности, которые мы рассмотрим:
21    </p>
22    <ul>
23      <li>Отправление запросов серверу без перезагрузки страницы
24      </li>
25      <li>Работа с XML документами
26      </li>
27    </ul>
28    <h3 id=".D0.A8.D0.B0.D0.B3_1.C2.A0.E2.80.94_.D0.9A.D0.B0.D0.B
>A_.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" name=".D0.A8.D0.B0.D0.B3_1.C2.A0.E2.80.94_ 
>.D0.9A.D0.B0.D0.BA_.D0.BF.D0.BE.D1.81.D0.BB.D0.B0.D1.82.D1.8C_HTT 
>P_.D0.B7.D0.B0.D0.BF.D1.80.D0.BE.D1.81"> 
29      Шаг 1&nbsp;— Как послать HTTP запрос
30    </h3>
31    <p>
32      Для того, чтобы послать HTTP запрос на сервер используя Jav
>aScript, вам необходим экземпляр класса, который позволит это сде 
>лать. Такой класс впервые был введен в Internet Explorer как объе 
>кт ActiveX, называемый <code>XMLHTTP</code>. Позже в Mozilla, Saf 
>ari и другие броузеры был введен класс <code>XMLHttpRequest</code 
>>, который поддерживал методы и свойства изначального объекта Act 
>iveX от Microsoft. 
33    </p>
34    <p>
35      В результате, чтобы создать кросс-броузерный объект требуем
>ого класса, вы можете сделать следующее: 
36    </p>
37    <pre>
38var httpRequest;
39if (window.XMLHttpRequest) { // Mozilla, Safari, ...
40    httpRequest = new XMLHttpRequest();
41} else if (window.ActiveXObject) { // IE
42    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
43}
44</pre>
45    <p>
46      (В целях наглядности код выше является немного упрощенным. 
>Более жизненный пример будет рассмотрен в шаге 3 этой статьи) 
47    </p>
48    <p>
49      Некоторые версии некоторых броузеров Mozilla не будут корре
>ктно работать, если ответ сервера не содержит заголовка XML <code 
>>mime-type</code>. Чтобы решить эту проблему вы можете использова 
>ть вызовы дополнительных методов для переопределения заголовка по 
>лученного от сервера, если он отличен от <code>text/xml</code>. 
50    </p>
51    <pre>
52httpRequest = new XMLHttpRequest();
53httpRequest.overrideMimeType('text/xml');
54</pre>
55    <p>
56      Далее вам необходимо решить, что вы будете делать после пол
>учения ответа сервера. На этом этапе вам необходимо указать объек 
>ту, какая JavaScript функция будет обрабатывать ответ. Это делает 
>ся путем присваивания свойству <code>onreadystatechange</code> им 
>ени JavaScript функции, которую вы собираетесь использовать: 
57    </p>
58    <p>
59      <code>httpRequest.onreadystatechange = nameOfTheFunction;</
>code> 
60    </p>
61    <p>
62      Заметьте, что после названия функции нет скобок и не указан
>о параметров, потому что вы просто присваиваете ссылку на функцию 
>, а не вызываете ее. К тому же, вместо указания имени функции, вы 
> можете использовать возможность JavaScript объявлять функции на  
>лету (так называемые «анонимные функции») и указывать действия, к 
>оторые тотчас же будут обрабатывать ответ: 
63    </p>
64    <pre>
65httpRequest.onreadystatechange = function(){
66    // какой-нибудь код
67};
68</pre>
69    <p>
70      Далее, после того как вы объявили что будет происходить пос
>ле получения ответа, вам необходимо сделать запрос. Вы должны выз 
>вать методы класса <code>open()</code> и <code>send()</code>: 
71    </p>
72    <pre>
73httpRequest.open('GET', 'http://www.example.org/some.file', true)
>; 
74httpRequest.send(null);
75</pre>
76    <ul>
77      <li>Первый параметр вызова функции <code>open()</code>&nbsp
>;— метод HTTP запроса (GET, POST, HEAD или любой другой метод, ко 
>торый вы хотите использовать). Используйте методы в соответствии  
>с HTTP стандартами, иначе некоторые браузеры (такие как Firefox)  
>могут не обработать запрос. Информация о допустимых HTTP запросах 
> доступна по адресу <a class="external" href="http://www.w3.org/P 
>rotocols/rfc2616/rfc2616-sec9.html">спецификации W3C</a> 
78      </li>
79      <li>Второй параметр&nbsp;— URL запрашиваемой страницы. Из с
>оображений безопасности возможность запрашивать страницы сторонни 
>х доменов недоступна. Убедитесь, что вы используете одинаковое до 
>менное имя на всех страницах, иначе вы получите ошибку 'доступ за 
>прещен' при вызове функции <code>open()</code>. Типичной ошибкой  
>при доступе к сайту через <code>site.ru</code> является отправка  
>запроса на <code>www.site.ru</code>. 
80      </li>
81      <li>Третий параметр указывает, является ли запрос асинхронн
>ым. Если он <code>TRUE</code>, то выполнение JavaScript продолжит 
>ся во время ожидания ответа сервера. В этом и заключается асинхро 
>нность технологии. 
82      </li>
83    </ul>
84    <p>
85      Параметром метода <code>send()</code> могут быть любые данн
>ые, которые вы хотите послать на сервер. Данные должны быть сформ 
>ированы в строку запроса: 
86    </p>
87    <p>
88      <code>name=value&amp;anothername=othervalue&amp;so=on</code
>> 
89    </p>
90    <p>
91      Заметьте, что если вы хотите отправить данные методом <code
>>POST</code>, вы должны изменить MIME-тип запроса с помощью следу 
>ющей строки: 
92    </p>
93    <pre>
94httpRequest.setRequestHeader('Content-Type', 'application/x-www-f
>orm-urlencoded'); 
95</pre>
96    <p>
97      Иначе сервер проигнорирует данные отправленные методом POST
>. 
98    </p>
99    <h3 id=".D0.A8.D0.B0.D0.B3_2.C2.A0.E2.80.94_.D0.9E.D0.B1.D1.8
>0.D0.B0.D0.B1.D0.B0.D1.82.D1.8B.D0.B2.D0.B0.D0.B5.D0.BC_.D0.BE.D1 
>.82.D0.B2.D0.B5.D1.82_.D1.81.D0.B5.D1.80.D0.B2.D0.B5.D1.80.D0.B0" 
> name=".D0.A8.D0.B0.D0.B3_2.C2.A0.E2.80.94_.D0.9E.D0.B1.D1.80.D0. 
>B0.D0.B1.D0.B0.D1.82.D1.8B.D0.B2.D0.B0.D0.B5.D0.BC_.D0.BE.D1.82.D 
>0.B2.D0.B5.D1.82_.D1.81.D0.B5.D1.80.D0.B2.D0.B5.D1.80.D0.B0"> 
100      Шаг 2&nbsp;— Обрабатываем ответ сервера
101    </h3>
102    <p>
103      Отправляя запрос, вы указали имя функции JavaScript, обраба
>тывающей ответ. 
104    </p>
105    <p>
106      <code>httpRequest.onreadystatechange = nameOfTheFunction;</
>code> 
107    </p>
108    <p>
109      Давайте посмотрим, что эта функция должна делать. Во-первых
>, функция должна проверять статус запроса. Если значение переменн 
>ой статуса 4, то это означает, что ответ от сервера получен и его 
> можно обрабатывать. 
110    </p>
111    <pre>
112if (httpRequest.readyState == 4) {
113    // все в порядке, ответ получен
114} else {
115    // все еще не готово
116}
117</pre>
118    <p>
119      Полный список значений кодов <code>readyState</code> такой:
120    </p>
121    <ul>
122      <li>0 (uninitialized)
123      </li>
124      <li>1 (loading)
125      </li>
126      <li>2 (loaded)
127      </li>
128      <li>3 (interactive)
129      </li>
130      <li>4 (complete)
131      </li>
132    </ul>
133    <p>
134      (<a class="external" href="http://msdn.microsoft.com/worksh
>op/author/dhtml/reference/properties/readystate_1.asp">Источник</ 
>a>) 
135    </p>
136    <p>
137      Следующее, что нужно проверить&nbsp;— это статус HTTP-ответ
>а. Все возможные коды можно посмотреть на <a class="external" hre 
>f="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">сайте  
>W3C</a>. Для наших целей нам интересен только код ответа <code>20 
>0 OK</code>. 
138    </p>
139    <pre>
140if (httpRequest.status == 200) {
141    // великолепно!
142} else {
143    // с запросом возникли проблемы,
144    // например, ответ может быть 404 (Не найдено)
145    // или 500 (Внутренняя ошибка сервера)
146}
147</pre>
148    <p>
149      Теперь, после проверки состояния запроса и статуса HTTP-отв
>ета, вы можете делать с данными, полученными от сервера, все что  
>угодно. Есть два способа получить доступ к данным: 
150    </p>
151    <ul>
152      <li>
153        <code>httpRequest.responseText</code> – возвращает ответ 
>сервера в виде строки текста. 
154      </li>
155      <li>
156        <code>httpRequest.responseXML</code> – возвращает ответ с
>ервера в виде объекта <code>XMLDocument</code>, который вы можете 
> обходить используя функции JavaScript DOM 
157      </li>
158    </ul>
159    <h3 id=".D0.A8.D0.B0.D0.B3_3.C2.A0.E2.80.94_.D0.9F.D1.80.D0.B
>E.D1.81.D1.82.D0.BE.D0.B9_.D0.BF.D1.80.D0.B8.D0.BC.D0.B5.D1.80" n 
>ame=".D0.A8.D0.B0.D0.B3_3.C2.A0.E2.80.94_.D0.9F.D1.80.D0.BE.D1.81 
>.D1.82.D0.BE.D0.B9_.D0.BF.D1.80.D0.B8.D0.BC.D0.B5.D1.80"> 
160      Шаг 3&nbsp;— Простой пример
161    </h3>
162    <p>
163      Давайте соберем все вместе и сделаем простой пример HTTP-за
>проса. Наш JavaScript запросит HTML документ <code>test.html</cod 
>e>, который содержит текст "I'm a test." и выведет содержимое фай 
>ла в диалоговом окне. 
164    </p>
165    <pre>
166&lt;script type="text/javascript" language="javascript"&gt;
167    function makeRequest(url) {
168        var httpRequest = false;
169 
170        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
171            httpRequest = new XMLHttpRequest();
172            if (httpRequest.overrideMimeType) {
173                httpRequest.overrideMimeType('text/xml');
174                // Читайте ниже об этой строке
175            }
176        } else if (window.ActiveXObject) { // IE
177            try {
178                httpRequest = new ActiveXObject("Msxml2.XMLHTTP")
>; 
179            } catch (e) {
180                try {
181                    httpRequest = new ActiveXObject("Microsoft.XM
>LHTTP"); 
182                } catch (e) {}
183            }
184        }
185 
186        if (!httpRequest) {
187            alert('Не вышло :( Невозможно создать экземпляр класс
>а XMLHTTP '); 
188            return false;
189        }
190        httpRequest.onreadystatechange = function() { alertConten
>ts(httpRequest); }; 
191        httpRequest.open('GET', url, true);
192        httpRequest.send(null);
193 
194    }
195 
196    function alertContents(httpRequest) {
197 
198        if (httpRequest.readyState == 4) {
199            if (httpRequest.status == 200) {
200                alert(httpRequest.responseText);
201            } else {
202                alert('С запросом возникла проблема.');
203            }
204        }
205 
206    }
207&lt;/script&gt;
208&lt;span
209    style="cursor: pointer; text-decoration: underline"
210    onclick="makeRequest('test.html')"&gt;
211        Сделать запрос
212&lt;/span&gt;
213</pre>
214    <p>
215      <br>
216      В этом примере:
217    </p>
218    <ul>
219      <li>Пользователь нажимает на ссылку "Сделать запрос" в броу
>зере; 
220      </li>
221      <li>Это вызывает функцию <code>makeRequest()</code> с парам
>етром <code>test.html</code>&nbsp;— именем HTML файла; 
222      </li>
223      <li>Посылается запрос, после чего (<code>onreadystatechange
></code>) выполнение передается <code>alertContents()</code>; 
224      </li>
225      <li>
226        <code>alertContents()</code> проверяет получен ли ответ и
> все ли с ним в порядке, после чего содержимое файла <code>test.h 
>tml</code> выводится в диалоговом окне. 
227      </li>
228    </ul>
229    <p>
230      Вы можете попробовать пример в действии <a class="external"
> href="http://www.akvi.ru/mozdev/httprequest_test.html" rel="foll 
>ow">здесь</a>, а сам тестовый файл можно посмотреть <a class="ext 
>ernal" href="http://www.akvi.ru/mozdev/test.html" rel="follow">зд 
>есь</a>. 
231    </p>
232    <p>
233      <strong>Замечание</strong>: Строка <code>httpRequest.overri
>deMimeType('text/xml');</code> вызовет ошибки в консоли JavaScrip 
>t в Firefox 1.5 или более позднем, как описано в <a class=" link- 
>https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=311724" 
> rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=3117 
>24</a>, если страница вызванная с помощью XMLHttpRequest не являе 
>тся правильным XML (например, если это обычный текст). На самом д 
>еле это корректное поведение. 
234    </p>
235    <p>
236      <strong>Замечание 2</strong>: Если вы посылаете запрос не н
>а статический XML-файл, а на серверный скрипт, возвращающий XML,  
>то нужно установить некоторые заголовки ответа, если вы планирует 
>е сделать вашу страницу работоспособной в Internet Explorer помим 
>о Mozilla. Если вы не установите заголовок <code>Content-Type: ap 
>plication/xml</code>, IE будет сообщать об ошибке JavaScript, 'Ob 
>ject Expected', после строки, где вы пытаетесь получить доступ к  
>XML элементу. Если вы не установите заголовок <code>Cache-Control 
>: no-cache</code> броузер будет кэшировать ответ и никогда не буд 
>ет повторно отправлять запрос, что сделает отладку весьма «забавн 
>ой». 
237    </p>
238    <p>
239      <strong>Замечание 3</strong>: Если переменная <code>httpReq
>uest</code> используется глобально, то конкурирующие функции, выз 
>ывающие <code>makeRequest()</code> могут конкурировать друг с дру 
>гом, вызывая состязания. Объявление переменной <code>httpRequest< 
>/code> локально в функции и передача ее в <code>alertContent()</c 
>ode> предотвращает состязания. 
240    </p>
241    <p>
242      <strong>Замечание 4</strong>: При привязывании функции обра
>тного вызова к <code>onreadystatechange</code> нельзя указывать а 
>ргументов. По этой причине не работает следующий код: 
243    </p>
244    <pre>
245httpRequest.onreadystatechange = alertContents(httpRequest); // (
>не работает) 
246</pre>
247    <p>
248      Таким образом, для успешной регистрации функции, вы должны 
>передать ей аргументы косвенно через анонимную функцию или исполь 
>зуя <code>httpRequest</code> как глобальную переменную. Вот приме 
>р: 
249    </p>
250    <pre>
251httpRequest.onreadystatechange = function() { alertContents(httpR
>equest); };  //1 (одновременный запрос) 
252httpRequest.onreadystatechange = alertContents;  //2 (глобальная 
>переменная) 
253</pre>
254    <p>
255      Первый способ позволяет делать несколько запросов одновреме
>нно, а второй используется, когда переменная <code>httpRequest</c 
>ode> является глобальной. 
256    </p>
257    <p>
258      <strong>Замечание 5</strong>: В случае ошибки взаимодействи
>я (например, если сервер упал), при попытке доступа к переменной  
>.status метода onreadystatechange будет сгенерировано исключение. 
> Убедитесь, что if...then заключено в try...catch. (См. <a class= 
>" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id= 
>238559" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi? 
>id=238559</a>). 
259    </p>
260    <pre>
261function alertContents(httpRequest) {
262 
263        try {
264            if (httpRequest.readyState == 4) {
265                if (httpRequest.status == 200) {
266                    alert(httpRequest.responseText);
267                } else {
268                    alert('С запросом возникла проблема.');
269                }
270            }
271        }
272        catch( e ) {
273            alert('Произошло исключение: ' + e.description);
274        }
275 
276    }
277</pre>
278    <h3 id=".D0.A8.D0.B0.D0.B3_4.C2.A0.E2.80.94_.D0.A0.D0.B0.D0.B
>1.D0.BE.D1.82.D0.B0_.D1.81_XML_.D0.BE.D1.82.D0.B2.D0.B5.D1.82.D0. 
>BE.D0.BC" name=".D0.A8.D0.B0.D0.B3_4.C2.A0.E2.80.94_.D0.A0.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"> 
279      Шаг 4&nbsp;— Работа с XML ответом
280    </h3>
281    <p>
282      В предыдущем примере, после того как был получен ответ на H
>TTP-запрос мы использовали <code>responseText</code> запрашиваемо 
>го объекта, который содержал данные файла <code>test.html</code>. 
> Теперь давайте попробуем использовать свойство <code>responseXML 
></code>. 
283    </p>
284    <p>
285      Прежде всего, давайте создадим правильный XML документ, кот
>орый мы будем запрашивать. Документ (<code>test.xml</code>) содер 
>жит следующее: 
286    </p>
287    <pre>
288&lt;?xml version="1.0" ?&gt;
289&lt;root&gt;
290    I'm a test.
291&lt;/root&gt;
292</pre>
293    <p>
294      В скрипте нам всего лишь необходимо заменить строку запроса
> на: 
295    </p>
296    <pre>
297...
298onclick="makeRequest('test.xml')"&gt;
299...
300</pre>
301    <p>
302      Далее в <code>alertContents()</code> нам нужно заменить стр
>оку <code>alert(httpRequest.responseText);</code> на: 
303    </p>
304    <pre>
305var xmldoc = httpRequest.responseXML;
306var root_node = xmldoc.getElementsByTagName('root').item(0);
307alert(root_node.firstChild.data);
308</pre>
309    <p>
310      Этот код берет объект <code>XMLDocument</code>, возвращаемы
>й <code>responseXML</code> и использует методы DOM для доступа к  
>данным, содержащимся в документе XML. Посмотреть <code>test.xml</ 
>code> можно <a class="external" href="http://www.akvi.ru/mozdev/t 
>est.xml" rel="follow">здесь</a>, а обновленный скрипт <a class="e 
>xternal" href="http://www.akvi.ru/mozdev/httprequest_test_xml.htm 
>l" rel="follow">здесь</a>. 
311    </p>
312    <p>
313      Чтобы узнать больше о методах DOM, посмотрите <a class="ext
>ernal" href="http://www.mozilla.org/docs/dom/">реализация DOM в M 
>ozilla</a>. 
314    </p>
315    <p>
316      {{ languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/A
>JAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/ 
>AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJA 
>X/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Gett 
>ing_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Co 
>mo_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }} 
317    </p>

Вернуться в Историю