XMLHttpRequest

  • Revision slug: XMLHttpRequest
  • Revision title: XMLHttpRequest
  • Revision id: 72952
  • Created:
  • Creator: TotalAMD
  • Is current revision? Нет
  • комментировать 1 words added, 1 words removed

Revision Content

 

XMLHttpRequest - это объект JavaScript созданный Microsoft и адаптированный Mozilla. Вы можете использовать его для простой передачи данных через HTTP. Несмотря на свое название он может быть использован не только для XML документов, например для JSON.

Оставшаяся часть статьи может содержать информацию специфичную для Gecko или привилегированному коду, такому как дополнения.

В Gecko, этот объект реализует интерфейсы nsIJSXMLHttpRequest и nsIXMLHttpRequest. Недавние версии Gecko содержат некторые изменения для этого объекта, см. XMLHttpRequest changes for Gecko1.8.

Основы использования

Использование XMLHttpRequest очень простое. Вы создаете экземпляр объекта, открываете URL и отправляете запрос. статус HTTP-ответа также как и возвращаемый документ доступны в свойствах объекта запроса.

Замечание: Версии Firefox до версии 3 постоянно отправляют запрос используя кодировку UTF-8. Отправляя документ, Firefox 3 использует кодировку определенную в data.inputEncoding (где data ненулевой объект переданный в send()). Если не определенно, то используется UTF-8.

Пример

var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false); 
req.send(null);
if(req.status == 200)
  dump(req.responseText);
Замечание: Этот пример работает синхронно, то есть он заблокирует интерфейс пользователя, если вы вызовете его из своего кода. Не рекомендуется использовать это на практике.

Пример без http протокола

var req = new XMLHttpRequest();
req.open('GET', 'file:///home/user/file.json', false); 
req.send(null);
if(req.status == 0)
  dump(req.responseText);
Замечание: file:/// и ftp:// не возвращают HTTP статуса, вот почему они возвращают ноль в status и пустую строчку в statusText. См. {{ Bug("331610") }} для подробной информации.

Асинхронное использование

Если вы собираетесь использовать XMLHttpRequest из дополнения, вы должны позволить ему загружаться асинхронно. Во время асинхронного использования вы получаете отзыв после загрузки данных, что позволяет браузеру продолжать работу пока ваш запрос обрабатывается.

Пример

var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true); /* Третий аргумент true означает асинхронность */
req.onreadystatechange = function (aEvt) {
  if (req.readyState == 4) {
     if(req.status == 200)
      dump(req.responseText);
     else
      dump("Error loading page\n");
  }
};
req.send(null); 

Наблюдение за прогрессом

XMLHttpRequest предоставляет возможность отлавливать некоторые события которые могут возникнуть во время обработки запроса. Включая периодические уведомления о прогрессе, сообщения об ошибках и так далее.

Если к примеру вы желаете предоставить информацию пользователю о прогрессе получения документа вы можете использовать код вроде этого:

function onProgress(e) {
  var percentComplete = (e.position / e.totalSize)*100;
  ...
}

function onError(e) {
  alert("Error " + e.target.status + " occurred while receiving the document.");
}

function onLoad(e) {
  // ...
}
// ...
var req = new XMLHttpRequest();
req.onprogress = onProgress;
req.open("GET", url, true);
req.onload = onLoad;
req.onerror = onError;
req.send(null);

Атрибуты события onprogress: position и totalSize, отображают соотвественно текущие количество принятых байтов и количество ожидаемых байтов.

Все эти события имеют свои target атрибуты установленные в соответствии с XMLHttpRequest.

Замечание: Firefox 3 по сути обеспечивает установку значений-ссылок полей target, currentTarget и this у объекта события на правильные объекты во время вызова обработчика событий для XML документов представленных в XMLDocument. См. {{ Bug("198595") }} для деталей.

Другие Свойства и Методы

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

responseXML

Если вы загрузили XML документ свойство responseXML будет содержать документ в виде XmlDocument объекта которым вы можете манипулировать используя DOM методы. Если сервер отправляет правильно сформированные XML документы но не устанавливает Content-Type заголовок для него, вы можете использовать overrideMimeType() для того чтобы документ был обработан как XML. Если сервер не отправляет правильно сформированного документа XML, responseXML вернет null независимо от любых перезаписей Content-Type заголовка.

overrideMimeType()

Этот метод может быть использован для обработки документа особенным образом. Обычно вы будите использовать его когда вы запросите responseXML и сервер отправит вам XML, но не отправит вам правильного Content-Type заголовка.

Замечание: Этот метод должен вызываться до вызова send().
var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.overrideMimeType('text/xml');
req.send(null);

setRequestHeader()

Этот метод может быть использован чтобы установить HTTP заголовок в запросе до его отправки.

Замечание: Вы должны вызвать вначале open().
var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.setRequestHeader("X-Foo", "Bar");
req.send(null);

getResponseHeader()

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

var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false);
req.send(null);
dump("Content-Type: " + req.getResponseHeader("Content-Type") + "\n");

abort()

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

var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false);
req.send(null);
req.abort();

mozBackgroundRequest

Это свойство может быть использовано чтобы уберечь от всплытия аутентификации и неправильных диалогов сертификации в ответ на запрос. Также запрос не будет отменен при закрытие его окна которому он принадлежит. Это свойство работает только для кода chrome. {{ Fx_minversion_inline("3") }}

var req = new XMLHttpRequest();
req.mozBackgroundRequest = true;
req.open('GET', 'http://www.mozilla.org/', true);
req.send(null);

Using from XPCOM components

Note: Changes are required if you use XMLHttpRequest from a JavaScript XPCOM component.

XMLHttpRequest cannot be instantiated using the XMLHttpRequest() constructor from a JavaScript XPCOM component. The constructor is not defined inside components and the code results in an error. You'll need to create and use it using a different syntax.

Instead of this:

var req = new XMLHttpRequest();
req.onprogress = onProgress;
req.onload = onLoad;
req.onerror = onError;
req.open("GET", url, true);
req.send(null);

Do this:

var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
req.onprogress = onProgress;
req.onload = onLoad;
req.onerror = onError;
req.open("GET", url, true);
req.send(null);

For C++ code you would need to QueryInterface the component to an nsIEventTarget in order to add event listeners, but chances are in C++ using a channel directly would be better.

Limited number of simultaneous XMLHttpRequest connections

The about:config preference: network.http.max-persistent-connections-per-server limits the number of connections. In Firefox 3 this value is 6 by default, previous versions use 2 as the default. Some interactive web pages using xmlHttpRequest may keep a connection open. Opening two or three of these pages in different tabs or on different windows may cause the browser to hang in such a way that the window no longer repaints and browser controls don't respond.

Binary Content

Although less typical than sending/receiving character-oriented content, XMLHttpRequest can be used to send and receive binary content.

Retrieving binary content

// Fetches BINARY FILES synchronously using XMLHttpRequest
function load_binary_resource(url) {
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType('text/plain; charset=x-user-defined');
  req.send(null);
  if (req.status != 200) return '';
  return req.responseText;
}

var filestream = load_binary_resource(url);
// x is the offset (i.e. position) of the byte in the returned binary file stream. The valid range for x is from 0 up to filestream.length-1.
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)

See downloading binary streams with XMLHttpRequest for a detailed explanation. See also downloading files.

Sending binary content

This example POSTs binary content asynchronously. aBody is some data to send.

 var req = new XMLHttpRequest();
 req.open("POST", url, true);
 // set headers and mime-type appropriately
 req.setRequestHeader("Content-Length", 741);
 req.sendAsBinary(aBody);

You can also send binary content by passing an instance of interface nsIFileInputStream to req.send(). In that case, there is not need to set the Content-Length request header:

// Make a stream from a file. The file variable holds an nsIFile
var stream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                       .createInstance(Components.interfaces.nsIFileInputStream);
stream.init(file, 0x04 | 0x08, 0644, 0x04); // file is an nsIFile instance   

// Try to determine the MIME type of the file
var mimeType = "text/plain";
try {
  var mimeService = Components.classes["@mozilla.org/mime;1"].getService(Components.interfaces.nsIMIMEService);
  mimeType = mimeService.getTypeFromFile(file); // file is an nsIFile instance
}
catch(e) { /* eat it; just use text/plain */ }

// Send    
var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
req.open('PUT', url, false); /* synchronous! */
req.setRequestHeader('Content-Type', mimeType);
req.send(stream);

Bypassing cache

Normally, XMLHttpRequest attempts to retrieve content from local cache. To bypass this attempt, do the following:

 var req = new XMLHttpRequest();
 req.open('GET', url, false);
 req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
 req.send(null);

An alternative approach to bypassing cache, as described here:

 var req = new XMLHttpRequest();
 req.open("GET", url += (url.match(/\?/) == null ? "?" : "&") + (new Date()).getTime(), false);
 req.send(null);

This appends a timestamp URL parameter to the URL, taking care to insert a ? or & as appropriate. For example, http://foo.com/bar.html becomes http://foo.com/bar.html?12345 and http://foo.com/bar.html?foobar=baz becomes http://foo.com/bar.html?foobar=baz&12345. Since local cache is indexed by URL, the idea is that every URL used by XMLHttpRequest is unique, bypassing the cache.

Downloading JSON and JavaScript in extensions

Extensions shouldn't use eval() on JSON or JavaScript downloaded from the web. See Downloading JSON and JavaScript in extensions for details.

References

  1. MDC AJAX introduction
  2. XMLHttpRequest - REST and the Rich User Experience
  3. XULPlanet documentation
  4. Microsoft documentation
  5. Apple developers' reference
  6. "Using the XMLHttpRequest Object" (jibbering.com)
  7. The XMLHttpRequest Object: W3C Working Draft

{{ languages( { "es": "es/XMLHttpRequest", "fr": "fr/XMLHttpRequest", "it": "it/XMLHttpRequest", "ja": "ja/XMLHttpRequest", "ko": "ko/XMLHttpRequest", "pl": "pl/XMLHttpRequest", "zh-cn": "cn/XMLHttpRequest" } ) }}

Revision Source

<p> </p>
<p><code>XMLHttpRequest</code> - это объект <a href="/ru/JavaScript" title="ru/JavaScript">JavaScript</a> созданный Microsoft и адаптированный Mozilla. Вы можете использовать его для простой передачи данных через HTTP. Несмотря на свое название он может быть использован не только для XML документов, например для <a href="/ru/JSON" title="ru/JSON">JSON</a>.</p>
<p>Оставшаяся часть статьи может содержать информацию специфичную для <a href="/ru/Gecko" title="ru/Gecko">Gecko</a> или привилегированному коду, такому как дополнения.</p>
<p>В Gecko, этот объект реализует интерфейсы <code><a href="/ru/NsIJSXMLHttpRequest" title="ru/NsIJSXMLHttpRequest">nsIJSXMLHttpRequest</a></code> и <code><a href="/ru/NsIXMLHttpRequest" title="ru/NsIXMLHttpRequest">nsIXMLHttpRequest</a></code>. Недавние версии Gecko содержат некторые изменения для этого объекта, см. <a href="/ru/XMLHttpRequest_changes_for_Gecko1.8" title="ru/XMLHttpRequest_changes_for_Gecko1.8">XMLHttpRequest changes for Gecko1.8</a>.</p>
<h3 id=".D0.9E.D1.81.D0.BD.D0.BE.D0.B2.D1.8B_.D0.B8.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D1.8F" name=".D0.9E.D1.81.D0.BD.D0.BE.D0.B2.D1.8B_.D0.B8.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D1.8F">Основы использования</h3>
<p>Использование <code>XMLHttpRequest</code> очень простое. Вы создаете экземпляр объекта, открываете URL и отправляете запрос. статус HTTP-ответа также как и возвращаемый документ доступны в свойствах объекта запроса.</p>
<div class="note"><strong>Замечание: </strong>Версии Firefox до версии 3 постоянно отправляют запрос используя кодировку UTF-8. Отправляя документ, Firefox 3 использует кодировку определенную в <code>data.inputEncoding</code> (где <code>data </code>ненулевой объект переданный в <code>send()</code>). Если не определенно, то используется UTF-8.</div>
<h4 id=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80" name=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80">Пример</h4>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false); 
req.send(null);
if(req.status == 200)
  dump(req.responseText);
</pre>
<div class="note"><strong>Замечание:</strong> Этот пример работает синхронно, то есть он заблокирует интерфейс пользователя, если вы вызовете его из своего кода. Не рекомендуется использовать это на практике.</div>
<h4 id=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_.D0.B1.D0.B5.D0.B7_http_.D0.BF.D1.80.D0.BE.D1.82.D0.BE.D0.BA.D0.BE.D0.BB.D0.B0" name=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_.D0.B1.D0.B5.D0.B7_http_.D0.BF.D1.80.D0.BE.D1.82.D0.BE.D0.BA.D0.BE.D0.BB.D0.B0">Пример без http протокола</h4>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'file:///home/user/file.json', false); 
req.send(null);
if(req.status == 0)
  dump(req.responseText);
</pre>
<div class="note"><strong>Замечание:</strong> file:/// и ftp:// не возвращают HTTP статуса, вот почему они возвращают ноль в <code>status</code> и пустую строчку в <code>statusText</code>. См. {{ Bug("331610") }} для подробной информации.</div><h3 id=".D0.90.D1.81.D0.B8.D0.BD.D1.85.D1.80.D0.BE.D0.BD.D0.BD.D0.BE.D0.B5_.D0.B8.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5" name=".D0.90.D1.81.D0.B8.D0.BD.D1.85.D1.80.D0.BE.D0.BD.D0.BD.D0.BE.D0.B5_.D0.B8.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5">Асинхронное использование</h3>
<p>Если вы собираетесь использовать <code>XMLHttpRequest</code> из дополнения, вы должны позволить ему загружаться асинхронно. Во время асинхронного использования вы получаете отзыв после загрузки данных, что позволяет браузеру продолжать работу пока ваш запрос обрабатывается.</p>
<h4 id=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_2" name=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_2">Пример</h4>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true); /* Третий аргумент true означает асинхронность */
req.onreadystatechange = function (aEvt) {
  if (req.readyState == 4) {
     if(req.status == 200)
      dump(req.responseText);
     else
      dump("Error loading page\n");
  }
};
req.send(null); 
</pre>
<h4 id=".D0.9D.D0.B0.D0.B1.D0.BB.D1.8E.D0.B4.D0.B5.D0.BD.D0.B8.D0.B5_.D0.B7.D0.B0_.D0.BF.D1.80.D0.BE.D0.B3.D1.80.D0.B5.D1.81.D1.81.D0.BE.D0.BC" name=".D0.9D.D0.B0.D0.B1.D0.BB.D1.8E.D0.B4.D0.B5.D0.BD.D0.B8.D0.B5_.D0.B7.D0.B0_.D0.BF.D1.80.D0.BE.D0.B3.D1.80.D0.B5.D1.81.D1.81.D0.BE.D0.BC">Наблюдение за прогрессом</h4>
<p><code>XMLHttpRequest</code> предоставляет возможность отлавливать некоторые события которые могут возникнуть во время обработки запроса. Включая периодические уведомления о прогрессе, сообщения об ошибках и так далее.</p>
<p>Если к примеру вы желаете предоставить информацию пользователю о прогрессе получения документа вы можете использовать код вроде этого:</p>
<pre>function onProgress(e) {
  var percentComplete = (e.position / e.totalSize)*100;
  ...
}

function onError(e) {
  alert("Error " + e.target.status + " occurred while receiving the document.");
}

function onLoad(e) {
  // ...
}
// ...
var req = new XMLHttpRequest();
req.onprogress = onProgress;
req.open("GET", url, true);
req.onload = onLoad;
req.onerror = onError;
req.send(null);
</pre>
<p>Атрибуты события <code>onprogress</code>: <code>position</code> и <code>totalSize</code>, отображают соотвественно текущие количество принятых байтов и количество ожидаемых байтов.</p>
<p>Все эти события имеют свои <code>target</code> атрибуты установленные в соответствии с <code>XMLHttpRequest</code>.</p>
<div class="note"><strong>Замечание:</strong> <a href="/ru/Firefox_3" title="ru/Firefox_3">Firefox 3</a> по сути обеспечивает установку значений-ссылок полей <code>target</code>, <code>currentTarget</code> и <code>this</code> у объекта события на правильные объекты во время вызова обработчика событий для XML документов представленных в <code>XMLDocument</code>. См. {{ Bug("198595") }} для деталей.</div>
<h3 id=".D0.94.D1.80.D1.83.D0.B3.D0.B8.D0.B5_.D0.A1.D0.B2.D0.BE.D0.B9.D1.81.D1.82.D0.B2.D0.B0_.D0.B8_.D0.9C.D0.B5.D1.82.D0.BE.D0.B4.D1.8B" name=".D0.94.D1.80.D1.83.D0.B3.D0.B8.D0.B5_.D0.A1.D0.B2.D0.BE.D0.B9.D1.81.D1.82.D0.B2.D0.B0_.D0.B8_.D0.9C.D0.B5.D1.82.D0.BE.D0.B4.D1.8B">Другие Свойства и Методы</h3>
<p>В дополнение к свойствам и методам описанным выше, ниже следуют другие полезные свойства и методы для объекта запроса.</p>
<h4 id="responseXML" name="responseXML">responseXML</h4>
<p>Если вы загрузили <a href="/ru/XML" title="ru/XML">XML</a> документ свойство <code>responseXML</code> будет содержать документ в виде <code>XmlDocument</code> объекта которым вы можете манипулировать используя DOM методы. Если сервер отправляет правильно сформированные XML документы но не устанавливает Content-Type заголовок для него, вы можете использовать <code><a href="/ru/XMLHttpRequest#overrideMimeType.28.29" title="ru/XMLHttpRequest#overrideMimeType.28.29">overrideMimeType()</a></code> для того чтобы документ был обработан как XML. Если сервер не отправляет правильно сформированного документа XML, <code>responseXML</code> вернет null независимо от любых перезаписей Content-Type заголовка.</p>
<h4 id="overrideMimeType.28.29" name="overrideMimeType.28.29">overrideMimeType()</h4>
<p>Этот метод может быть использован для обработки документа особенным образом. Обычно вы будите использовать его когда вы запросите <code>responseXML</code> и сервер отправит вам <a href="/ru/XML" title="ru/XML">XML</a>, но не отправит вам правильного Content-Type заголовка.</p>
<div class="note"><strong>Замечание:</strong> Этот метод должен вызываться до вызова <code>send()</code>.</div>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.overrideMimeType('text/xml');
req.send(null);
</pre>
<h4 id="setRequestHeader.28.29" name="setRequestHeader.28.29">setRequestHeader()</h4>
<p>Этот метод может быть использован чтобы установить HTTP заголовок в запросе до его отправки.</p>
<div class="note"><strong>Замечание:</strong> Вы должны вызвать вначале <code>open()</code>.</div>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.setRequestHeader("X-Foo", "Bar");
req.send(null);
</pre>
<h4 id="getResponseHeader.28.29" name="getResponseHeader.28.29">getResponseHeader()</h4>
<p>Этот метод может быть использован для получения HTTP заголовка из ответа сервера.</p>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false);
req.send(null);
dump("Content-Type: " + req.getResponseHeader("Content-Type") + "\n");
</pre>
<h4 id="abort.28.29" name="abort.28.29">abort()</h4>
<p>Этот метод может быть использован чтобы отменить обрабатываемый запрос.</p>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false);
req.send(null);
req.abort();
</pre>
<h4 id="mozBackgroundRequest" name="mozBackgroundRequest">mozBackgroundRequest</h4>
<p>Это свойство может быть использовано чтобы уберечь от всплытия аутентификации и неправильных диалогов сертификации в ответ на запрос. Также запрос не будет отменен при закрытие его окна которому он принадлежит. Это свойство работает только для кода chrome. {{ Fx_minversion_inline("3") }}</p>
<pre>var req = new XMLHttpRequest();
req.mozBackgroundRequest = true;
req.open('GET', 'http://www.mozilla.org/', true);
req.send(null);
</pre>
<h3 id="Using_from_XPCOM_components" name="Using_from_XPCOM_components">Using from XPCOM components</h3>
<div class="note"><strong>Note:</strong> Changes are required if you use XMLHttpRequest from a JavaScript XPCOM component.</div>
<p>XMLHttpRequest cannot be instantiated using the <code>XMLHttpRequest()</code> constructor from a JavaScript XPCOM component. The constructor is not defined inside components and the code results in an error. You'll need to create and use it using a different syntax.</p>
<p>Instead of this:</p>
<pre>var req = new XMLHttpRequest();
req.onprogress = onProgress;
req.onload = onLoad;
req.onerror = onError;
req.open("GET", url, true);
req.send(null);
</pre>
<p>Do this:</p>
<pre>var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
req.onprogress = onProgress;
req.onload = onLoad;
req.onerror = onError;
req.open("GET", url, true);
req.send(null);
</pre>
<p>For C++ code you would need to QueryInterface the component to an <code>nsIEventTarget</code> in order to add event listeners, but chances are in C++ using a channel directly would be better.</p>
<h3 id="Limited_number_of_simultaneous_XMLHttpRequest_connections" name="Limited_number_of_simultaneous_XMLHttpRequest_connections">Limited number of simultaneous XMLHttpRequest connections</h3>
<p>The about:config preference: network.http.max-persistent-connections-per-server limits the number of connections. In Firefox 3 this value is 6 by default, previous versions use 2 as the default. Some interactive web pages using xmlHttpRequest may keep a connection open. Opening two or three of these pages in different tabs or on different windows may cause the browser to hang in such a way that the window no longer repaints and browser controls don't respond.</p>
<h3 id="Binary_Content" name="Binary_Content">Binary Content</h3>
<p>Although less typical than sending/receiving character-oriented content, <code>XMLHttpRequest</code> can be used to send and receive binary content.</p>
<h4 id="Retrieving_binary_content" name="Retrieving_binary_content">Retrieving binary content</h4>
<pre>// Fetches BINARY FILES synchronously using XMLHttpRequest
function load_binary_resource(url) {
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType('text/plain; charset=x-user-defined');
  req.send(null);
  if (req.status != 200) return '';
  return req.responseText;
}

var filestream = load_binary_resource(url);
// x is the offset (i.e. position) of the byte in the returned binary file stream. The valid range for x is from 0 up to filestream.length-1.
var abyte = filestream.charCodeAt(x) &amp; 0xff; // throw away high-order byte (f7)
</pre>
<p>See <a class="external" href="http://mgran.blogspot.com/2006/08/downloading-binary-streams-with.html">downloading binary streams with XMLHttpRequest</a> for a detailed explanation. See also <a href="/ru/Code_snippets/Downloading_Files" title="ru/Code_snippets/Downloading_Files">downloading files</a>.</p>
<h4 id="Sending_binary_content" name="Sending_binary_content">Sending binary content</h4>
<p>This example POSTs binary content asynchronously. aBody is some data to send.</p>
<pre class="eval"> var req = new XMLHttpRequest();
 req.open("POST", url, true);
 // set headers and mime-type appropriately
 req.setRequestHeader("Content-Length", 741);
 req.sendAsBinary(aBody);
</pre>
<p>You can also send binary content by passing an instance of interface <a href="/ru/NsIFileInputStream" title="ru/NsIFileInputStream">nsIFileInputStream</a> to <code>req.send()</code>. In that case, there is not need to set the Content-Length request header:</p>
<pre>// Make a stream from a file. The file variable holds an nsIFile
var stream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                       .createInstance(Components.interfaces.nsIFileInputStream);
stream.init(file, 0x04 | 0x08, 0644, 0x04); // file is an nsIFile instance   

// Try to determine the MIME type of the file
var mimeType = "text/plain";
try {
  var mimeService = Components.classes["@mozilla.org/mime;1"].getService(Components.interfaces.nsIMIMEService);
  mimeType = mimeService.getTypeFromFile(file); // file is an nsIFile instance
}
catch(e) { /* eat it; just use text/plain */ }

// Send    
var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
req.open('PUT', url, false); /* synchronous! */
req.setRequestHeader('Content-Type', mimeType);
req.send(stream);
</pre>
<h3 id="Bypassing_cache" name="Bypassing_cache">Bypassing cache</h3>
<p>Normally, <code>XMLHttpRequest</code> attempts to retrieve content from local cache. To bypass this attempt, do the following:</p>
<pre class="eval"> var req = new XMLHttpRequest();
 req.open('GET', url, false);
 <strong>req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;</strong>
 req.send(null);
</pre>
<p>An alternative approach to bypassing cache, as described <a class="external" href="http://mozdev.org/pipermail/project_owners/2006-August/008353.html">here</a>:</p>
<pre class="eval"> var req = new XMLHttpRequest();
 req.open("GET", url += (url.match(/\?/) == null ? "?" : "&amp;") + (new Date()).getTime(), false);
 req.send(null);
</pre>
<p>This appends a timestamp URL parameter to the URL, taking care to insert a ? or &amp; as appropriate. For example, <a class=" external" href="http://foo.com/bar.html" rel="freelink">http://foo.com/bar.html</a> becomes <a class=" external" href="http://foo.com/bar.html?12345" rel="freelink">http://foo.com/bar.html?12345</a> and <a class=" external" href="http://foo.com/bar.html?foobar=baz" rel="freelink">http://foo.com/bar.html?foobar=baz</a> becomes <a class=" external" href="http://foo.com/bar.html?foobar=baz&amp;12345" rel="freelink">http://foo.com/bar.html?foobar=baz&amp;12345</a>. Since local cache is indexed by URL, the idea is that every URL used by XMLHttpRequest is unique, bypassing the cache.</p>
<h3 id="Downloading_JSON_and_JavaScript_in_extensions" name="Downloading_JSON_and_JavaScript_in_extensions">Downloading JSON and JavaScript in extensions</h3>
<p>Extensions shouldn't use <a href="/ru/Core_JavaScript_1.5_Reference/Functions/eval" title="ru/Core_JavaScript_1.5_Reference/Functions/eval">eval()</a> on JSON or JavaScript downloaded from the web. See <a href="/ru/Downloading_JSON_and_JavaScript_in_extensions" title="ru/Downloading_JSON_and_JavaScript_in_extensions">Downloading JSON and JavaScript in extensions</a> for details.</p>
<h3 id="References" name="References">References</h3>
<ol> <li><a href="/ru/AJAX/Getting_Started" title="ru/AJAX/Getting_Started">MDC AJAX introduction</a></li> <li><a class="external" href="http://www.peej.co.uk/articles/rich-user-experience.html">XMLHttpRequest - REST and the Rich User Experience</a></li> <li><a class="external" href="http://www.xulplanet.com/references/objref/XMLHttpRequest.html">XULPlanet documentation</a></li> <li><a class="external" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/xmobjxmlhttprequest.asp">Microsoft documentation</a></li> <li><a class="external" href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html">Apple developers' reference</a></li> <li><a class="external" href="http://jibbering.com/2002/4/httprequest.html">"Using the XMLHttpRequest Object" (jibbering.com)</a></li> <li><a class="external" href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object: W3C Working Draft</a></li>
</ol>
<p>{{ languages( { "es": "es/XMLHttpRequest", "fr": "fr/XMLHttpRequest", "it": "it/XMLHttpRequest", "ja": "ja/XMLHttpRequest", "ko": "ko/XMLHttpRequest", "pl": "pl/XMLHttpRequest", "zh-cn": "cn/XMLHttpRequest" } ) }}</p>
Revert to this revision