XMLHttpRequest

  • Revision slug: DOM/XMLHttpRequest
  • Revision title: XMLHttpRequest
  • Revision id: 14292
  • Created:
  • Creator: Bzbarsky
  • Is current revision? No
  • Comment /* Basic Usage */

Revision Content

XMLHttpRequest is a JavaScript object that was created by Microsoft and adopted by Mozilla. You can use it to easily retrieve data via HTTP. Despite its name, it can be used for more than just XML documents. In Gecko, this object implements the nsIJSXMLHttpRequest and nsIXMLHttpRequest interfaces. Recent versions of Gecko have some changes to this object, see XMLHttpRequest changes for Gecko1.8.

Basic Usage

Using XMLHttpRequest is very simple. You create an instance of the object, open a URL, and send the request. The HTTP status code of the result, as well as the result document are available in the request object afterwards.

{{template.Note("Versions of Firefox prior to version 3 always send the request using UTF-8 encoding. When sending a Document, <a href=\"en/Firefox_3\">Firefox 3</a> sends it using the encoding specified by <code>data.inputEncoding</code>.")}}

Example

var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true); 
req.send(null);
if(req.status == 200)
  dump(req.responseText);
Note: This example works synchronously, so it will block the user interface if you call this from your JavaScript. You should not use this in practice.

Example with non http protocol

var req = new XMLHttpRequest();
req.open('GET', 'file:///home/user/file.json', false); 
req.send(null);
if(req.status == 0)
  dump(req.responseText);
Note: file:/// and ftp:// do not return HTTP status, which is why they return zero for status and an empty string for statusText. Refer to {{template.Bug(331610)}} for more insight.

Asynchronous Usage

If you intend to use XMLHttpRequest from an extension, you should let it load asynchronously. In asynchronous usage, you get a callback when the data has been received, which lets the browser continue to work as normal while your request is happening.

Example

var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', 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); 

Monitoring progress

XMLHttpRequest provides the ability to listen to various events that can occur while the request is being processed. This includes periodic progress notifications, error notifications, and so forth.

If, for example, you wish to provide progress information to the user while the document is being received, you can use code like this:

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);

The onprogress event's attributes, position and totalSize, indicate the current number of bytes received and the total number of bytes expected, respectively.

All of these events have their target attribute set to the XMLHttpRequest they correspond to.

Note: Firefox 3 properly ensures that the values of the target, currentTarget, and this fields of the event object are set to reference the correct objects when calling event handlers for XML documents represented by XMLDocument. See {{template.Bug(198595)}} for details.

Other Properties and Methods

In addition to the properties and methods shown above, there are other useful properties and methods on the request object.

responseXML

If you load an XML document, the responseXML property will contain the document as an XmlDocument object that you can manipulate using DOM methods. If the server sends well-formed XML but does not specify an XML Content-Type header, you can use overrideMimeType() to force the document to be parsed as XML. If the server does not send well-formed XML, responseXML will be null regardless of any content type override.

overrideMimeType()

This method can be used to force a document to be handled as a particular content type. You will generally want to use when you want to use responseXML and the server sends you XML, but does not send the correct Content-Type header.
Note: This method must be called before calling send().
var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.overrideMimeType('text/xml');
req.send(null);

setRequestHeader()

This method can be used to set an HTTP header on the request before you send it.

Note: You must call open() before calling this method.
var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.setRequestHeader("X-Foo", "Bar");
req.send(null);

getResponseHeader()

This method can be used to get an HTTP header from the server response.

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

mozBackgroundRequest

This property can be used to prevent authentication and bad certificate dialogs from popping up for the request. Also the request will not be canceled if the window it belongs to is closed. This property works for chrome code only. {{template.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 request = Components.
              classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
              createInstance();

// QI the object to nsIDOMEventTarget to set event handlers on it:

request.QueryInterface(Components.interfaces.nsIDOMEventTarget);
request.addEventListener("progress", function(evt) { ... }, false);
request.addEventListener("load", function(evt) { ... }, false);
request.addEventListener("error", function(evt) { ... }, false);

// QI it to nsIXMLHttpRequest to open and send the request:

request.QueryInterface(Components.interfaces.nsIXMLHttpRequest);
request.open("GET", "http://www.example.com/", true);
request.send(null);

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.

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.

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
{{ wiki.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> is a <a href="en/JavaScript">JavaScript</a> object that was created by Microsoft and adopted by Mozilla.  You can use it to easily retrieve data via HTTP.  Despite its name, it can be used for more than just XML documents.  In Gecko, this object implements the <code><a href="en/NsIJSXMLHttpRequest">nsIJSXMLHttpRequest</a></code> and <code><a href="en/NsIXMLHttpRequest">nsIXMLHttpRequest</a></code> interfaces.  Recent versions of Gecko have some changes to this object, see <a href="en/XMLHttpRequest_changes_for_Gecko1.8">XMLHttpRequest changes for Gecko1.8</a>.
</p>
<h3 name="Basic_Usage">Basic Usage</h3>
<p>Using <code>XMLHttpRequest</code> is very simple.  You create an instance of the object, open a URL, and send the request.  The HTTP status code of the result, as well as the result document are available in the request object afterwards.
</p><p>{{template.Note("Versions of Firefox prior to version 3 always send the request using UTF-8 encoding.  When sending a Document, &lt;a href=\"en/Firefox_3\"&gt;Firefox 3&lt;/a&gt; sends it using the encoding specified by &lt;code&gt;data.inputEncoding&lt;/code&gt;.")}}
</p>
<h4 name="Example">Example</h4>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true); 
req.send(null);
if(req.status == 200)
  dump(req.responseText);
</pre>
<div class="note"><b>Note:</b> This example works synchronously, so it will block the user interface if you call this from your JavaScript.  You should not use this in practice.</div>
<h4 name="Example_with_non_http_protocol">Example with non http protocol</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"><b>Note:</b> file:/// and ftp:// do not return HTTP status, which is why they return zero for <code>status</code> and an empty string for <code>statusText</code>. Refer to {{template.Bug(331610)}} for more insight.</div>
<h3 name="Asynchronous_Usage">Asynchronous Usage</h3>
<p>If you intend to use <code>XMLHttpRequest</code> from an extension, you should let it load asynchronously.  In asynchronous usage, you get a callback when the data has been received, which lets the browser continue to work as normal while your request is happening.
</p>
<h4 name="Example_2">Example</h4>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', 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 name="Monitoring_progress">Monitoring progress</h4>
<p><code>XMLHttpRequest</code> provides the ability to listen to various events that can occur while the request is being processed.  This includes periodic progress notifications, error notifications, and so forth.
</p><p>If, for example, you wish to provide progress information to the user while the document is being received, you can use code like this:
</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>The <code>onprogress</code> event's attributes, <code>position</code> and <code>totalSize</code>, indicate the current number of bytes received and the total number of bytes expected, respectively.
</p><p>All of these events have their <code>target</code> attribute set to the <code>XMLHttpRequest</code> they correspond to.
</p>
<div class="note"><b>Note:</b> <a href="en/Firefox_3">Firefox 3</a> properly ensures that the values of the <code>target</code>, <code>currentTarget</code>, and <code>this</code> fields of the event object are set to reference the correct objects when calling event handlers for XML documents represented by <code>XMLDocument</code>.  See {{template.Bug(198595)}} for details.</div>
<h3 name="Other_Properties_and_Methods">Other Properties and Methods</h3>
<p>In addition to the properties and methods shown above, there are other useful properties and methods on the request object.
</p>
<h4 name="responseXML">responseXML</h4>
<p>If you load an <a href="en/XML">XML</a> document, the <code>responseXML</code> property will contain the document as an <code>XmlDocument</code> object that you can manipulate using DOM methods.  If the server sends well-formed XML but does not specify an XML Content-Type header, you can use <code><a href="en/XMLHttpRequest#overrideMimeType.28.29">overrideMimeType()</a></code> to force the document to be parsed as XML. If the server does not send well-formed XML, <code>responseXML</code> will be null regardless of any content type override.
</p>
<h4 name="overrideMimeType.28.29">overrideMimeType()</h4>
This method can be used to force a document to be handled as a particular content type.  You will generally want to use when you want to use <code>responseXML</code> and the server sends you <a href="en/XML">XML</a>, but does not send the correct Content-Type header.  <div class="note"><b>Note:</b> This method must be called before calling <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 name="setRequestHeader.28.29">setRequestHeader()</h4>
<p>This method can be used to set an HTTP header on the request before you send it.
</p>
<div class="note"><b>Note:</b> You must call <code>open()</code> before calling this method.</div>
<pre>var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', true);
req.setRequestHeader("X-Foo", "Bar");
req.send(null);
</pre>
<h4 name="getResponseHeader.28.29">getResponseHeader()</h4>
<p>This method can be used to get an HTTP header from the server response.
</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 name="mozBackgroundRequest">mozBackgroundRequest</h4>
<p>This property can be used to prevent authentication and bad certificate dialogs from popping up for the request. Also the request will not be canceled if the window it belongs to is closed. This property works for chrome code only. {{template.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 name="Using_from_XPCOM_components"> Using from XPCOM components </h3>
<div class="note"><b>Note:</b> 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 request = Components.
              classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
              createInstance();

// QI the object to nsIDOMEventTarget to set event handlers on it:

request.QueryInterface(Components.interfaces.nsIDOMEventTarget);
request.addEventListener("progress", function(evt) { ... }, false);
request.addEventListener("load", function(evt) { ... }, false);
request.addEventListener("error", function(evt) { ... }, false);

// QI it to nsIXMLHttpRequest to open and send the request:

request.QueryInterface(Components.interfaces.nsIXMLHttpRequest);
request.open("GET", "http://www.example.com/", true);
request.send(null);
</pre>
<h3 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 name="Retrieving_Binary_Content">Retrieving Binary Content</h3>
<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.
</p>
<h3 name="References">References</h3>
<ol><li> <a href="en/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>
{{ wiki.languages( { "es": "es/XMLHttpRequest", "fr": "fr/XMLHttpRequest", "it": "it/XMLHttpRequest", "ja": "ja/XMLHttpRequest", "ko": "ko/XMLHttpRequest", "pl": "pl/XMLHttpRequest", "zh-cn": "cn/XMLHttpRequest" } ) }}
Revert to this revision