Using XMLHttpRequest

  • Revision slug: DOM/XMLHttpRequest/Using_XMLHttpRequest
  • Revision title: Using XMLHttpRequest
  • Revision id: 2335
  • Created:
  • Creator: XP1
  • Is current revision? No
  • Comment 3 words added, 1 words removed

Revision Content

XMLHttpRequest makes sending HTTP requests very easy.  You simply create an instance of the object, open a URL, and send the request.  The HTTP status of the result, as well as the result's contents, are available in the request object when the transaction is completed.

Synchronous and asynchronous requests

XMLHttpRequest supports both synchronous and asynchronous communications.

Note: You shouldn't use synchronous XMLHttpRequests because, due to the inherently asynchronous nature of networking, there are various ways memory and events can leak when using synchronous requests.

In versions of Firefox prior to Firefox 3, synchronous XMLHttpRequest requests blocked the user interface.  In order to make it possible for the user to terminate frozen requests, Firefox 3 no longer does so.

Synchronous request

In rare cases, the use of a synchronous method is preferable to an asynchronous one.

Example: HTTP synchronous request

This example demonstrates how to make a simple synchronous request.

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

if (request.status === 200) {
  console.log(request.responseText);
}

Line 1 instantiates the XMLHttpRequest object.  Line 2 then opens a new request, specifying that a GET request will be used to fetch the Mozilla.org home page, and that the operation should not be asynchronous.

Line 3 sends the request.  The null parameter indicates that no body content is needed for the GET request.

Line 4 checks the status code after the transaction is completed.  If the result is 200 -- HTTP's "OK" result -- the document's text content is output to the console.

Example: Non-HTTP synchronous request

Despite its name, XMLHttpRequest can be used for non-HTTP requests.  This example shows how to use it to fetch a file from the local file system.

var request = new XMLHttpRequest();
request.open('GET', 'file:///home/user/file.json', false); 
request.send(null);

if (request.status == 0)
  console.log(request.responseText);

The key thing to note here is that the result status is being compared to 0 for success instead of 200.  This is because the file and ftp schemes do not use HTTP result codes.

Example: synchronous HTTP request from a Worker

One of the few cases in which a synchronous request is preferable to the asynchronous one is the use of XMLHttpRequest within a Worker.

example.html:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>MDN Example</title>
<script type="text/javascript">
var oMyWorker = new Worker("myTask.js");  
oMyWorker.onmessage = function(oEvent) {  
  alert(("Worker said: " + oEvent.data));
};

oMyWorker.postMessage("Hello");
</script>
</head>

<body></body>

</html>

myTask.js:

function getFile (sURL) {
  var oXHR = new XMLHttpRequest();
  // synchronous request
  oXHR.open("GET", sURL, false);
  oXHR.send(null);
  return oXHR.responseText;
}

var sFileContent;

self.onmessage = function (oEvent) {
  if (oEvent.data === "Hello") {
    sFileContent = getFile("myFile.txt");
    self.postMessage("File loaded!");
  }
};
Note: The effect, because of the use of the Worker, is however asynchronous.

It could be useful in order to interact in background with the server or to preload some content. See Using web workers for examples and details.

Asynchronous request

If you use XMLHttpRequest from an extension, you should use it asynchronously.  In this case, you receive a callback when the data has been received, which lets the browser continue to work as normal while your request is being handled.

Example: send a file to the console log

This is the simplest usage of asynchronous XMLHttpRequest.

var oXHR = new XMLHttpRequest();
oXHR.open("GET", "http://www.mozilla.org/", true);
oXHR.onreadystatechange = function (oEvent) {
  if (oXHR.readyState === 4) {
    if (oXHR.status === 200) {
      console.log(oXHR.responseText)
    } else {
      console.log("Error", oXHR.statusText);
    }
  }
};
oXHR.send(null); 

Line 2 specifies true for its third parameter to indicate that the request should be handled asynchronously.

Line 3 creates an event handler function object and assigns it to the request's onreadystatechange attribute.  This handler looks at the request's readyState to see if the transaction is complete in line 4, and if it is, and the HTTP status is 200, dumps the received content.  If an error occurred, an error message is displayed.

Line 12 actually initiates the request.  The callback routine is called whenever the state of the request changes.

Example: creating a standard function to read external files

In some cases you must read many external files. This is a standard function which uses the XMLHttpRequest object asynchronously in order to switch the content of the readed file to a specified listener.

function loadFile (sURL, fCallback /*, argumentToPass1, argumentToPass2, etc. */) {
  var aPassArgs = Array.prototype.slice.call(arguments, 2), oXHR = new XMLHttpRequest();
  oXHR.onreadystatechange = function() {
    if (oXHR.readyState === 4) { fCallback.apply(oXHR, aPassArgs); }
  };
  oXHR.open("GET", sURL, true);
  oXHR.send(null);
}

Usage:

function showMessage (sMsg) {
  alert(sMsg + this.responseText);
}

loadFile("message.txt", showMessage, "New message!\n");

Line 1 declares a function which will pass all arguments after the third to the fCallback function when the file has been loaded.

Line 5 creates an event handler function object and assigns it to the request's onreadystatechange attribute.  This handler looks at the request's readyState to see if the transaction is complete in line 4, and if it is, and the HTTP status is 200, dumps the received content.  If an error occurred, an error message is displayed.

Line 6 specifies true for its third parameter to indicate that the request should be handled asynchronously.

Line 7 actually initiates the request.  The callback routine is called whenever the state of the request changes.

Example: using asynchronous request avoiding closures

Manipulating the new XMLHttpRequest instance:

function switchXHRState() {
  switch (this.readyState) {
    case 0: console.log("open() has not been called yet."); break;
    case 1: console.log("send() has not been called yet."); break;
    case 2: console.log("send() has been called, headers and status are available."); break;
    case 3: console.log("Downloading, responseText holds the partial data."); break;
    case 4: console.log("Complete!"); this.callback.apply(this, this.arguments);
  }
};

function loadFile (sURL, fCallback /*, argumentToPass1, argumentToPass2, etc. */) {
  var oXHR = new XMLHttpRequest();
  oXHR.callback = fCallback;
  oXHR.arguments = Array.prototype.slice.call(arguments, 2);
  oXHR.onreadystatechange = switchXHRState;
  oXHR.open("GET", sURL, true);
  oXHR.send(null);
}

Using bind:

function switchXHRState(fCallback, aArguments) {
  switch (this.readyState) {
    case 0: console.log("open() has not been called yet."); break;
    case 1: console.log("send() has not been called yet."); break;
    case 2: console.log("send() has been called, headers and status are available."); break;
    case 3: console.log("Downloading, responseText holds the partial data."); break;
    case 4: console.log("Complete!"); fCallback.apply(this, aArguments);
  }
};

function loadFile (sURL, fCallback /*, argumentToPass1, argumentToPass2, etc. */) {
  var oXHR = new XMLHttpRequest();
  oXHR.onreadystatechange = switchXHRState.bind(oXHR, fCallback, Array.prototype.slice.call(arguments, 2));
  oXHR.open("GET", sURL, true);
  oXHR.send(null);
}

Analyzing and manipulating the responseXML property

If you use XMLHttpRequest to get the content of a remote XML document, the responseXML property will be a DOM Object containing a parsed XML document, which can be hard to manipulate and analyze. There are four primary ways of analyzing this XML document:

  1. Using XPath.
  2. Manually Parsing and serializing XML to strings or Javascript objects.
  3. Using XMLSerializer to serialize DOM trees to strings or to files.
  4. RegExp can be used if you always know the content of the XML document beforehand. You might want to remove line breaks, if you use RegExp to scan with regard to linebreaks. However, this method is a "last resort" since if the XML code changes slightly, the method will likely fail.

Analyzing and manipulating a responseText property containing a HTML document

If you use XMLHttpRequest to get the content of a remote HTML webpage, the responseText property will be a string containing a "soup" of all the HTML tags, which can be hard to manipulate and analyze. There are three primary ways of analyzing this HTML soup string:

  1. Safely parsing with nsIScriptableUnescapeHTML will quickly convert the HTML string into DOM, while stripping out JavaScript and other advanced elements, including the <head> of the webpage.
  2. RegExp can be used if you always know the content of the HTML responseText beforehand. You might want to remove line breaks, if you use RegExp to scan with regard to linebreaks. However, this method is a "last resort" since if the HTML code changes slightly, the method will likely fail.
  3. Using a hidden chrome or content-level iframe to load up the webpage can also be done to then manipulate it as DOM, however there are security risks to giving remote code this level of privileged access, which can cause issues for the review of your addon. For example, if a webpage executes the common "document.location = redirecttothispage.html" command on load, this will get interpreted as changing the browser chrome location (document.location in an extension) as opposed to the webpage location (content.document.location in an extension), thus destroying all browser components. Alternatively, and somewhat safer, a responseText string attained through a XMLHttpRequest can be analyzed using RegExp to remove potential JavaScript problems, then loaded into the hidden iframe that you have set up:
document.getElementById("hiddenXULiframe").contentWindow.document.body.innerHTML = req.responseText

Using FormData objects

The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest. Its primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data. The transmitted data is in the same format that the form's submit() method would use to send the data if the form's encoding type were set to "multipart/form-data".

Creating a FormData object from scratch

You can build a FormData object yourself, instantiating it then appending fields to it by calling its append() method, like this:

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456);
formData.append("afile", fileInputElement.files[0]);

var oXHR = new XMLHttpRequest();
oXHR.open("POST", "http://foo.com/submitform.php");
oXHR.send(formData);

This example builds a FormData object containing values for fields named "username" and "accountnum", then uses the XMLHttpRequest method send() to send the form's data.

Retrieving a FormData object from an HTML form

To construct a FormData object that contains the data from an existing {{ HTMLElement("form") }}, specify that form element when creating the FormData object:

var newFormData = new FormData(someFormElement);

For example:

var formElement = document.getElementById("myFormElement");
var oXHR = new XMLHttpRequest();
oXHR.open("POST", "submitform.php");
oXHR.send(new FormData(formElement));

You can also append additional data to the FormData object between retrieving it from a form and sending it, like this:

var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
oXHR.send(formData);

This lets you augment the form's data before sending it along, to include additional information that's not necessarily user editable on the form.

Sending files using a FormData object

You can also send files using FormData. Simply include an {{ HTMLElement("input") }} element of type "file":

<form enctype="multipart/form-data" method="post" name="fileinfo">
  <label>Your email address:</label>
  <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
  <label>Custom file label:</label>
  <input type="text" name="filelabel" size="12" maxlength="32" /><br />
  <label>File to stash:</label>
  <input type="file" name="file" required />
</form>
<div id="output"></div>
<a href="javascript:sendForm()">Stash the file!</a>

Then you can send it using code like the following:

function sendForm() {
  var oOutput = document.getElementById("output");
  var oData = new FormData(document.forms.namedItem("fileinfo"));

  oData.append("CustomField", "This is some extra data");

  var oXHR = new XMLHttpRequest();
  oXHR.open("POST", "stash.php", true);
  oXHR.onload = function(oEvent) {
    if (oXHR.status == 200) {
      oOutput.innerHTML = "Uploaded!";
    } else {
      oOutput.innerHTML = "Error " + oXHR.status + " occurred uploading your file.<br \/>";
    }
  };

  oXHR.send(oData);
}

Note that this example is directing the output to a Perl CGI script running on the server, and handles HTTP errors, although not prettily.

You can also append a {{ domxref("File") }} or {{ domxref("Blob") }} directly to the {{ domxref("XMLHttpRequest/FormData", "FormData") }} object, like this:

data.append("myfile", myBlob);

When using a {{ domxref("Blob") }}, the filename reported to the server in the HTTP "Content-Disposition" header is browser-specific; Firefox uses simply "blob," while Chrome uses a random string, for example.

You can also use FormData with jQuery if you set the right options:

var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // tell jQuery not to process the data
  contentType: false   // tell jQuery not to set contentType
});

Handling binary data

Although XMLHttpRequest is most commonly used to send and receive textual data, it can be used to send and receive binary content.

Receiving binary data using JavaScript typed arrays

The responseType property of the XMLHttpRequest object can be set to change the expected response type from the server. Possible values are the empty string (default), "arraybuffer", "blob", "document", and "text". The response property will contain the entity body according to responseType, as an ArrayBuffer, Blob, Document, or string. This is NULL if the request is not complete or was not successful.

This example reads an image as a binary file and creates an 8-bit unsigned integer array from the raw bytes.

var oXHR = new XMLHttpRequest();
oXHR.open("GET", "/myfile.png", true);
oXHR.responseType = "arraybuffer";

oXHR.onload = function (oEvent) {
  var arrayBuffer = oXHR.response; // Note: not oXHR.responseText
  if (arrayBuffer) {
    var byteArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteArray.byteLength; i++) {
      // do something with each byte in the array
    }
  }
};

oXHR.send(null);

{{ obsolete_header("6") }}

Gecko 2.0 {{ geckoRelease("2.0") }} added a vendor-specific mozResponseArrayBuffer property to the XMLHttpRequest object that should no longer be used as of Gecko 6 {{ geckoRelease("6") }}.

var oXHR = new XMLHttpRequest();
oXHR.open("GET", "binary_file", false);
oXHR.send(null);

buffer = oXHR.mozResponseArrayBuffer;
if (buffer) {
  var byteArray = new Uint8Array(buffer);
  for (var i = 0; i < byteArray.byteLength; i++) {
    // do something with each byte in the array
  }
}

Receiving binary data in older browsers

The load_binary_resource() function shown below loads binary data from the specified URL, returning it to the caller.

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

The magic happens in line 5, which overrides the MIME type, forcing the browser to treat it as plain text, using a user-defined character set.  This tells the browser not to parse it, and to let the bytes pass through unprocessed.

var filestream = load_binary_resource(url);
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)

The example above fetches the byte at offset x within the loaded binary data.  The valid range for x is from 0 to filestream.length-1.

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

Sending binary data

The send method of the XMLHttpRequest has been extended to enable easy transmission of binary data by accepting an ArrayBuffer, {{ domxref("Blob") }}, or {{ domxref("File") }} object.

The following example sends creates a text file on-the-fly and uses the POST method to send the "file" to the server. This example uses plain text, but you can imagine the data being a binary file instead.

var oXHR = new XMLHttpRequest();
oXHR.open("POST", url, true);
oXHR.onload = function (oEvent) {
  // Uploaded.
};

var bb = new BlobBuilder(); // prefixed: window.MozBlobBuilder or window.WebKitBlobBuilder
bb.append('abc123');

oXHR.send(bb.getBlob('text\/plain'));

Sending typed arrays as binary data

You can send JavaScript typed arrays as binary data as well.

var myArray = new ArrayBuffer(512);
var longInt8View = new Uint8Array(myArray);

for (var i=0; i< longInt8View.length; i++) {
  longInt8View[i] = i % 255;
}

var xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.send(myArray);

This is building a 512-byte array of 8-bit integers and sending it; you can use any binary data you'd like, of course.

Note: Support for sending ArrayBuffer objects using XMLHttpRequest was added to Gecko 9.0 {{ geckoRelease("9.0") }}. Add information about other browsers' support here.

Firefox-specific examples

This example transmits binary content asynchronously, using the POST method, and Firefox's non-stand sendAsBinary().

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

Line 4 sets the Content-Length header to 741, indicating that the data is 741 bytes long.  Obviously you need to change this value based on the actual size of the data being sent.

Line 5 uses the sendAsBinary() method to initiate the request.

You can also send binary content by passing an instance of the {{ interface("nsIFileInputStream") }} to send().  In that case, you don't have to set the Content-Length header yourself, as the information is fetched from the stream automatically:

// Make a stream from a file.
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 (oEvent) { /* 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);

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.

{{ h1_gecko_minversion("In Firefox 3.5 and later", "1.9.1") }}

Gecko 1.9.1 {{ geckoRelease("1.9.1") }} adds support for DOM progress event monitoring of XMLHttpRequest transfers; this follows the Web API specification for progress events.

var req = new XMLHttpRequest();

req.addEventListener("progress", updateProgress, false);
req.addEventListener("load", transferComplete, false);
req.addEventListener("error", transferFailed, false);
req.addEventListener("abort", transferCanceled, false);

req.open();

...

// progress on transfers from the server to the client (downloads)
function updateProgress(evt) {
  if (evt.lengthComputable) {
    var percentComplete = evt.loaded / evt.total;
    ...
  } else {
    // Unable to compute progress information since the total size is unknown
  }
}

function transferComplete(evt) {
  alert("The transfer is complete.");
}

function transferFailed(evt) {
  alert("An error occurred while transferring the file.");
}

function transferCanceled(evt) {
  alert("The transfer has been canceled by the user.");
}

Lines 3-6 add event listeners for the various events that are sent while performing a data transfer using XMLHttpRequest.  See {{ interface("nsIDOMProgressEvent") }} and {{ interface("nsIXMLHttpRequestEventTarget") }} for details on these events.

Note: You need to add the event listeners before calling open() on the request.  Otherwise the progress events will not fire.

The progress event handler, specified by the updateProgress() function in this example, receives the total number of bytes to transfer as well as the number of bytes transferred so far in the event's total and loaded fields.  However, if the lengthComputable field is false, the total length is not known and will be zero.

Progress events exist for both download and upload transfers. The download events are fired on the XMLHttpRequest object itself, as shown in the above sample. The upload events are fired on the XMLHttpRequest.upload object, as shown below:

var req = new XMLHttpRequest();

req.upload.addEventListener("progress", updateProgress, false);
req.upload.addEventListener("load", transferComplete, false);
req.upload.addEventListener("error", transferFailed, false);
req.upload.addEventListener("abort", transferCanceled, false);

req.open();
Note: Progress events are not available for the file: protocol.

{{ gecko_callout_heading("9.0") }}

Starting in Gecko 9.0 {{ geckoRelease("9.0") }}, progress events can now be relied upon to come in for every chunk of data received, including the last chunk in cases in which the last packet is received and the connection closed before the progress event is fired. In this case, the progress event is automatically fired when the load event occurs for that packet. This lets you now reliably monitor progress by only watching the "progress" event.

In Firefox 3 and earlier

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 (oEvent) {
  var percentComplete = oEvent.position * 100 / oEvent.totalSize;
  // ...
}

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

function onLoad(oEvent) {
  // ...
}
// ...
var req = new XMLHttpRequest();
req.onprogress = onProgress; // or req.addEventListener("progress", onProgress, false);
req.open("GET", url, true);
req.onload = onLoad; // or req.addEventListener("load", onLoad, false);
req.onerror = onError; // or req.addEventListener("error", onError, false);
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 {{ Bug("198595") }} for details.

{{ h2_gecko_minversion("Detecting any load end condition", "5.0") }}

Starting in Gecko 5.0 {{ geckoRelease("5.0") }}, you can detect all three load-ending conditions (abort, load, or error) using the loadend event:

req.addEventListener("loadend", loadEnd, false);

function loadEnd(evt) {
  alert("The transfer finished (although we don't know if it succeeded or not).");
} 

Note that there's no way to be certain from the information received by the loadend event as to which condition caused the operation to terminate; however, you can use this to handle tasks that need to be performed in all end-of-transfer scenarios.

Cross-site XMLHttpRequest

{{ fx_minversion_section("3") }}

Firefox 3.5 supports cross-site requests by implementing the web applications working group's Access Control for Cross-Site Requests standard.  As long as the server is configured to allow requests from your web application's origin, XMLHttpRequest will work.  Otherwise, an INVALID_ACCESS_ERR exception is thrown.

Bypassing the cache

Normally, XMLHttpRequest tries to retrieve content from the cache, if it's available.  To bypass this, do the following:

var req = new XMLHttpRequest();
req.open('GET', url, false);
req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
req.send(null);
Note: This approach will only work in Gecko-based software, as the channel attribute is Gecko-specific.

An alternate, cross-browser compatible approach is to append a timestamp to the URL, being sure to include 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 the local cache is indexed by URL, this causes every request to be unique, thereby bypassing the cache.

You can automatically adjust URLs using the following code:

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

Security

{{ fx_minversion_note("3") }}

{{ fx_minversion_note("5") }}

The recommended way to enable cross-site scripting is to use the Access-Control-Allow-Origin HTTP header in the response to the XMLHttpRequest.

XMLHttpRequests being stopped

If you end up with an XMLHttpRequest having status=0 and statusText=null, it means that the request was not allowed to be performed. It was UNSENT. A likely cause for this is when the XMLHttpRequest origin (at the creation of the XMLHttpRequest) has changed when the XMLHttpRequest is then open(). This case can happen for example when one has an XMLHttpRequest that gets fired on an onunload event for a window: the XMLHttpRequest gets in fact created when the window to be closed is still there, and then the request is sent (ie open()) when this window has lost its focus and potentially different window has gained focus. The way to avoid this problem is to set a listener on the new window "activate" event that gets set when the old window has its "unload" event fired.

Downloading JSON and JavaScript from extensions

For security reasons, extensions should never use eval() to parse JSON or JavaScript code downloaded from the web.  See Downloading JSON and JavaScript in extensions for details.

Using XMLHttpRequest from JavaScript modules / XPCOM components

Instantiating XMLHttpRequest from a JavaScript module or an XPCOM component works a little differently; it can't be instantiated using the XMLHttpRequest() constructor. 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 that in C++, using a channel directly would be better.

See also

  1. MDC AJAX introduction
  2. HTTP access control
  3. How to check the security state of an XMLHTTPRequest over SSL
  4. XMLHttpRequest - REST and the Rich User Experience
  5. Microsoft documentation
  6. Apple developers' reference
  7. "Using the XMLHttpRequest Object" (jibbering.com)
  8. The XMLHttpRequest Object: W3C Specification
  9. Web Progress Events specification
  10. Reading Ogg files with JavaScript (Chris Double)

{{ languages( { "ja": "Ja/Using_XMLHttpRequest"} ) }}

Revision Source

<p><a href="/en/DOM/XMLHttpRequest" title="en/XMLHttpRequest"><code>XMLHttpRequest</code></a> makes sending HTTP requests very easy.  You simply create an instance of the object, open a URL, and send the request.  The HTTP status of the result, as well as the result's contents, are available in the request object when the transaction is completed.</p>
<h2>Synchronous and asynchronous requests</h2>
<p><code>XMLHttpRequest</code> supports both synchronous and asynchronous communications.</p>
<div class="note"><strong>Note:</strong> You shouldn't use synchronous <code>XMLHttpRequests</code> because, due to the inherently asynchronous nature of networking, there are various ways memory and events can leak when using synchronous requests.</div>
<p>In versions of Firefox prior to Firefox 3, synchronous <code>XMLHttpRequest</code> requests blocked the user interface.  In order to make it possible for the user to terminate frozen requests, Firefox 3 no longer does so.</p>
<h3>Synchronous request</h3>
<p>In rare cases, the use of a synchronous method is preferable to an asynchronous one.</p>
<h4>Example: HTTP synchronous request</h4>
<p>This example demonstrates how to make a simple synchronous request.</p>
<pre class="brush: js">var request = new XMLHttpRequest();
request.open('GET', '<a class=" external" href="http://www.mozilla.org/" rel="freelink">http://www.mozilla.org/</a>', false); 
request.send(null);

if (request.status === 200) {
  console.log(request.responseText);
}
</pre>
<p>Line 1 instantiates the <code>XMLHttpRequest</code> object.  Line 2 then opens a new request, specifying that a <code>GET</code> request will be used to fetch the Mozilla.org home page, and that the operation should not be asynchronous.</p>
<p>Line 3 sends the request.  The <code>null</code> parameter indicates that no body content is needed for the <code>GET</code> request.</p>
<p>Line 4 checks the status code after the transaction is completed.  If the result is 200 -- HTTP's "OK" result -- the document's text content is output to the console.</p>
<h4>Example: Non-HTTP synchronous request</h4>
<p>Despite its name, <code>XMLHttpRequest</code> can be used for non-HTTP requests.  This example shows how to use it to fetch a file from the local file system.</p>
<pre class="brush: js">var request = new XMLHttpRequest();
request.open('GET', '<a class=" external" href="file:///home/user/file.json" rel="freelink">file:///home/user/file.json</a>', false); 
request.send(null);

if (request.status == 0)
  console.log(request.responseText);
</pre>
<p>The key thing to note here is that the result status is being compared to 0 for success instead of 200.  This is because the <code>file</code> and <code>ftp</code> schemes do not use HTTP result codes.</p>
<h4>Example: synchronous HTTP request from a Worker</h4>
<p>One of the few cases in which a synchronous request is preferable to the asynchronous one is the use of <code>XMLHttpRequest</code> within a <code><a href="/En/DOM/Worker" title="/en/DOM/Worker">Worker</a></code>.</p>
<p>example.html:</p>
<pre class="brush: html">&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
&lt;title&gt;MDN Example&lt;/title&gt;
&lt;script type="text/javascript"&gt;
var oMyWorker = new Worker("myTask.js");  
oMyWorker.onmessage = function(oEvent) {  
  alert(("Worker said: " + oEvent.data));
};

oMyWorker.postMessage("Hello");
&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;&lt;/body&gt;

&lt;/html&gt;</pre>
<p>myTask.js:</p>
<pre class="brush: js">function getFile (sURL) {
  var oXHR = new XMLHttpRequest();
  // synchronous request
  oXHR.open("GET", sURL, false);
  oXHR.send(null);
  return oXHR.responseText;
}

var sFileContent;

self.onmessage = function (oEvent) {
  if (oEvent.data === "Hello") {
    sFileContent = getFile("myFile.txt");
    self.postMessage("File loaded!");
  }
};
</pre>
<div class="note"><strong>Note:</strong> The effect, because of the use of the <code>Worker</code>, is however asynchronous.</div>
<p>It could be useful in order to interact in background with the server or to preload some content. See <a class="internal" href="/En/Using_web_workers" title="en/Using DOM workers">Using web workers</a> for examples and details.</p><h3>Asynchronous request</h3>
<p>If you use <code>XMLHttpRequest</code> from an extension, you should use it asynchronously.  In this case, you receive a callback when the data has been received, which lets the browser continue to work as normal while your request is being handled.</p>
<h4>Example: send a file to the console log</h4>
<p>This is the simplest usage of asynchronous <code>XMLHttpRequest</code>.</p>
<pre class="brush: js">var oXHR = new XMLHttpRequest();
oXHR.open("GET", "<a class=" external" href="http://www.mozilla.org/" rel="freelink">http://www.mozilla.org/</a>", true);
oXHR.onreadystatechange = function (oEvent) {
  if (oXHR.readyState === 4) {
    if (oXHR.status === 200) {
      console.log(oXHR.responseText)
    } else {
      console.log("Error", oXHR.statusText);
    }
  }
};
oXHR.send(null); </pre>
<p>Line 2 specifies <code>true</code> for its third parameter to indicate that the request should be handled asynchronously.</p>
<p>Line 3 creates an event handler function object and assigns it to the request's <code>onreadystatechange</code> attribute.  This handler looks at the request's <code>readyState</code> to see if the transaction is complete in line 4, and if it is, and the HTTP status is 200, dumps the received content.  If an error occurred, an error message is displayed.</p>
<p>Line 12 actually initiates the request.  The callback routine is called whenever the state of the request changes.</p>
<h4>Example: creating a standard function to read external files</h4>
<p>In some cases you must read many external files. This is a standard function which uses the <code>XMLHttpRequest</code> object asynchronously in order to switch the content of the readed file to a specified listener.</p>
<pre class="brush: js">function loadFile (sURL, fCallback /*, argumentToPass1, argumentToPass2, etc. */) {
  var aPassArgs = Array.prototype.slice.call(arguments, 2), oXHR = new XMLHttpRequest();
  oXHR.onreadystatechange = function() {
    if (oXHR.readyState === 4) { fCallback.apply(oXHR, aPassArgs); }
  };
  oXHR.open("GET", sURL, true);
  oXHR.send(null);
}
</pre>
<p>Usage:</p>
<pre class="brush: js">function showMessage (sMsg) {
  alert(sMsg + this.responseText);
}

loadFile("message.txt", showMessage, "New message!\n");
</pre>
<p>Line 1 declares a function which will pass all arguments after the third to the <code>fCallback</code> function when the file has been loaded.</p>
<p>Line 5 creates an event handler function object and assigns it to the request's <code>onreadystatechange</code> attribute.  This handler looks at the request's <code>readyState</code> to see if the transaction is complete in line 4, and if it is, and the HTTP status is 200, dumps the received content.  If an error occurred, an error message is displayed.</p>
<p>Line 6 specifies <code>true</code> for its third parameter to indicate that the request should be handled asynchronously.</p>
<p>Line 7 actually initiates the request.  The callback routine is called whenever the state of the request changes.</p>
<h4>Example: using asynchronous request avoiding closures</h4>
<p>Manipulating the new XMLHttpRequest instance:</p>
<pre class="brush: js">function switchXHRState() {
  switch (this.readyState) {
    case 0: console.log("open() has not been called yet."); break;
    case 1: console.log("send() has not been called yet."); break;
    case 2: console.log("send() has been called, headers and status are available."); break;
    case 3: console.log("Downloading, responseText holds the partial data."); break;
    case 4: console.log("Complete!"); this.callback.apply(this, this.arguments);
  }
};

function loadFile (sURL, fCallback /*, argumentToPass1, argumentToPass2, etc. */) {
  var oXHR = new XMLHttpRequest();
  oXHR.callback = fCallback;
  oXHR.arguments = Array.prototype.slice.call(arguments, 2);
  oXHR.onreadystatechange = switchXHRState;
  oXHR.open("GET", sURL, true);
  oXHR.send(null);
}
</pre>
<p>Using <code><a href="/en/JavaScript/Reference/Global_Objects/Function/bind" title="/en/JavaScript/Reference/Global_Objects/Function/bind">bind</a></code>:</p>
<pre class="brush: js">function switchXHRState(fCallback, aArguments) {
  switch (this.readyState) {
    case 0: console.log("open() has not been called yet."); break;
    case 1: console.log("send() has not been called yet."); break;
    case 2: console.log("send() has been called, headers and status are available."); break;
    case 3: console.log("Downloading, responseText holds the partial data."); break;
    case 4: console.log("Complete!"); fCallback.apply(this, aArguments);
  }
};

function loadFile (sURL, fCallback /*, argumentToPass1, argumentToPass2, etc. */) {
  var oXHR = new XMLHttpRequest();
  oXHR.onreadystatechange = switchXHRState.bind(oXHR, fCallback, Array.prototype.slice.call(arguments, 2));
  oXHR.open("GET", sURL, true);
  oXHR.send(null);
}
</pre>
<h2>Analyzing and manipulating the <code>responseXML</code> property</h2>
<p>If you use <code>XMLHttpRequest </code>to get the content of a remote XML document, the <code>responseXML </code>property will be a DOM Object containing a parsed XML document, which can be hard to manipulate and analyze. There are four primary ways of analyzing this XML document:</p>
<ol> <li>Using <a href="/en/XPath" title="/en/XPath">XPath</a>.</li> <li>Manually <a href="/en/Parsing_and_serializing_XML" title="/en/Parsing_and_serializing_XML">Parsing and serializing XML</a> to strings or Javascript objects.</li> <li>Using <a href="/en/XMLSerializer" title="en/XMLSerializer">XMLSerializer</a> to serialize <strong>DOM trees to strings or to files</strong>.</li> <li><a href="/en/JavaScript/Reference/Global_Objects/RegExp" title="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp">RegExp </a>can be used if you always know the content of the XML document beforehand. You might want to remove line breaks, if you use RegExp to scan with regard to linebreaks. However, this method is a "last resort" since if the XML code changes slightly, the method will likely fail.</li>
</ol>
<h2>Analyzing and manipulating a <code>responseText</code> property containing a HTML document</h2>
<p>If you use <code>XMLHttpRequest </code>to get the content of a remote HTML webpage, the <code>responseText</code> property will be a string containing a "soup" of all the HTML tags, which can be hard to manipulate and analyze. There are three primary ways of analyzing this HTML soup string:</p>
<ol> <li><a href="/en/Code_snippets/HTML_to_DOM#Safely_parsing_simple_HTML.c2.a0to_DOM" title="https://developer.mozilla.org/en/Code_snippets/HTML_to_DOM#Safely_parsing_simple_HTML.c2.a0to_DOM">Safely parsing with nsIScriptableUnescapeHTML </a> will quickly convert the HTML string into DOM, while stripping out JavaScript and other advanced elements, including the <code>&lt;head&gt;</code> of the webpage.</li> <li><a href="/en/JavaScript/Reference/Global_Objects/RegExp" title="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp">RegExp </a>can be used if you always know the content of the HTML <code>responseText </code>beforehand. You might want to remove line breaks, if you use RegExp to scan with regard to linebreaks. However, this method is a "last resort" since if the HTML code changes slightly, the method will likely fail.</li> <li><a href="/en/Code_snippets/HTML_to_DOM#Using_a_hidden_iframe_element_to_parse_HTML_to_a_window%27s_DOM" title="https://developer.mozilla.org/en/Code_snippets/HTML_to_DOM#Using_a_hidden_iframe_element_to_parse_HTML_to_a_window's_DOM">Using a hidden chrome or content-level iframe</a> to load up the webpage can also be done to then manipulate it as DOM, however there are <a href="/En/Displaying_web_content_in_an_extension_without_security_issues" title="En/Displaying_web_content_in_an_extension_without_security_issues">security risks to giving remote code this level of privileged access</a>, which can cause <a class="link-https" href="https://addons.mozilla.org/en-US/developers/docs/policies/reviews" title="https://addons.mozilla.org/en-US/developers/docs/policies/reviews">issues </a>for the review of your addon. For example, if a webpage executes the common "<code>document.location = redirecttothispage.html</code>" command on load, this will get interpreted as changing the browser chrome location (<code>document.location</code> in an extension) as opposed to the webpage location (<code>content.document.location</code> in an extension), thus destroying all browser components. Alternatively, and somewhat safer, a <code>responseText </code>string attained through a <code>XMLHttpRequest </code>can be analyzed using RegExp to remove potential JavaScript problems, then loaded into the hidden iframe that you have set up:</li>
</ol>
<pre>document.getElementById("hiddenXULiframe").contentWindow.document.body.innerHTML = req.responseText
</pre>
<h2>Using FormData objects</h2>
<p>The <a href="/en/DOM/XMLHttpRequest/FormData" title="en/DOM/XMLHttpRequest/FormData"><code>FormData</code></a> object lets you compile a set of key/value pairs to send using <code>XMLHttpRequest</code>. Its primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data. The transmitted data is in the same format that the form's <code>submit()</code> method would use to send the data if the form's encoding type were set to "multipart/form-data".</p>
<h3>Creating a FormData object from scratch</h3>
<p>You can build a <code>FormData</code> object yourself, instantiating it then appending fields to it by calling its <a href="/en/DOM/XMLHttpRequest/FormData#append()" title="en/XMLHttpRequest/FormData#append()"><code>append()</code></a> method, like this:</p>
<pre class="brush: js">var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456);
formData.append("afile", fileInputElement.files[0]);

var oXHR = new XMLHttpRequest();
oXHR.open("POST", "http://foo.com/submitform.php");
oXHR.send(formData);</pre>
<p>This example builds a <code>FormData</code> object containing values for fields named "username" and "accountnum", then uses the <code>XMLHttpRequest</code> method <a href="/en/DOM/XMLHttpRequest#send()" title="en/XMLHttpRequest#send()"><code>send()</code></a> to send the form's data.</p>
<h3>Retrieving a FormData object from an HTML form</h3>
<p>To construct a <code>FormData</code> object that contains the data from an existing {{ HTMLElement("form") }}, specify that form element when creating the <code>FormData</code> object:</p>
<pre>var newFormData = new FormData(someFormElement);
</pre>
<p>For example:</p>
<pre class="brush: js">var formElement = document.getElementById("myFormElement");
var oXHR = new XMLHttpRequest();
oXHR.open("POST", "submitform.php");
oXHR.send(new FormData(formElement));</pre>
<p>You can also append additional data to the <code>FormData</code> object between retrieving it from a form and sending it, like this:</p>
<pre class="brush: js">var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
oXHR.send(formData);</pre>
<p>This lets you augment the form's data before sending it along, to include additional information that's not necessarily user editable on the form.</p>
<h3>Sending files using a FormData object</h3>
<p>You can also send files using <code>FormData</code>. Simply include an {{ HTMLElement("input") }} element of type "file":</p>
<pre class="brush: html">&lt;form enctype="multipart/form-data" method="post" name="fileinfo"&gt;
  &lt;label&gt;Your email address:&lt;/label&gt;
  &lt;input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /&gt;&lt;br /&gt;
  &lt;label&gt;Custom file label:&lt;/label&gt;
  &lt;input type="text" name="filelabel" size="12" maxlength="32" /&gt;&lt;br /&gt;
  &lt;label&gt;File to stash:&lt;/label&gt;
  &lt;input type="file" name="file" required /&gt;
&lt;/form&gt;
&lt;div id="output"&gt;&lt;/div&gt;
&lt;a href="javascript:sendForm()"&gt;Stash the file!&lt;/a&gt;
</pre>
<p>Then you can send it using code like the following:</p>
<pre class="brush: js">function sendForm() {
  var oOutput = document.getElementById("output");
  var oData = new FormData(document.forms.namedItem("fileinfo"));

  oData.append("CustomField", "This is some extra data");

  var oXHR = new XMLHttpRequest();
  oXHR.open("POST", "stash.php", true);
  oXHR.onload = function(oEvent) {
    if (oXHR.status == 200) {
      oOutput.innerHTML = "Uploaded!";
    } else {
      oOutput.innerHTML = "Error " + oXHR.status + " occurred uploading your file.&lt;br \/&gt;";
    }
  };

  oXHR.send(oData);
}
</pre>
<p>Note that this example is directing the output to a Perl CGI script running on the server, and handles HTTP errors, although not prettily.</p>
<p>You can also append a {{ domxref("File") }} or {{ domxref("Blob") }} directly to the {{ domxref("XMLHttpRequest/FormData", "FormData") }} object, like this:</p>
<pre>data.append("myfile", myBlob);
</pre>
<p>When using a {{ domxref("Blob") }}, the filename reported to the server in the HTTP "Content-Disposition" header is browser-specific; Firefox uses simply "blob," while Chrome uses a random string, for example.</p>
<p>You can also use <code>FormData</code> with jQuery if you set the right options:</p>
<pre class="brush: js">var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // tell jQuery not to process the data
  contentType: false   // tell jQuery not to set contentType
});
</pre>
<h2>Handling binary data</h2>
<p>Although <code>XMLHttpRequest</code> is most commonly used to send and receive textual data, it can be used to send and receive binary content.</p>
<h3>Receiving binary data using JavaScript typed arrays</h3>
<p>The <code>r</code><code>esponseType</code> property of the XMLHttpRequest object can be set to change the expected response type from the server. Possible values are the empty string (default), "arraybuffer", "blob", "document", and "text". The <code>r</code><code>esponse </code>property will contain the entity body according to <code>r</code><code>esponseType</code>, as an <code>ArrayBuffer</code>, <code>Blob</code>, <code>Document</code>, or string. This is <code>NULL</code> if the request is not complete or was not successful.</p>
<p>This example reads an image as a binary file and creates an 8-bit unsigned integer array from the raw bytes.</p>
<pre class="brush: js">var oXHR = new XMLHttpRequest();
oXHR.open("GET", "/myfile.png", true);
oXHR.responseType = "arraybuffer";

oXHR.onload = function (oEvent) {
  var arrayBuffer = oXHR.response; // Note: not oXHR.responseText
  if (arrayBuffer) {
    var byteArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i &lt; byteArray.byteLength; i++) {
      // do something with each byte in the array
    }
  }
};

oXHR.send(null);
</pre>
<p>{{ obsolete_header("6") }}</p>
<p>Gecko 2.0 {{ geckoRelease("2.0") }} added a vendor-specific <code>mozResponseArrayBuffer</code> property to the XMLHttpRequest object that should no longer be used as of Gecko 6 {{ geckoRelease("6") }}.</p>
<pre class="brush: js">var oXHR = new XMLHttpRequest();
oXHR.open("GET", "binary_file", false);
oXHR.send(null);

buffer = oXHR.mozResponseArrayBuffer;
if (buffer) {
  var byteArray = new Uint8Array(buffer);
  for (var i = 0; i &lt; byteArray.byteLength; i++) {
    // do something with each byte in the array
  }
}</pre>
<h3>Receiving binary data in older browsers</h3>
<p>The <code>load_binary_resource()</code> function shown below loads binary data from the specified URL, returning it to the caller.</p>
<pre class="brush: js">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;
}
</pre>
<p>The magic happens in line 5, which overrides the MIME type, forcing the browser to treat it as plain text, using a user-defined character set.  This tells the browser not to parse it, and to let the bytes pass through unprocessed.</p>
<pre class="brush: js">var filestream = load_binary_resource(url);
var abyte = filestream.charCodeAt(x) &amp; 0xff; // throw away high-order byte (f7)
</pre>
<p>The example above fetches the byte at offset <code>x</code> within the loaded binary data.  The valid range for <code>x</code> is from 0 to <code>filestream.length-1</code>.</p>
<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="/en/Code_snippets/Downloading_Files" title="en/Code_snippets/Downloading_Files">downloading files</a>.</p>
<h3>Sending binary data</h3>
<p>The <code>send</code> method of the XMLHttpRequest has been extended to enable easy transmission of binary data by accepting an <a href="/en/JavaScript_typed_arrays/ArrayBuffer" title="ArrayBuffer"><code>ArrayBuffer</code></a>, {{ domxref("Blob") }}, or {{ domxref("File") }} object.</p>
<p>The following example sends creates a text file on-the-fly and uses the <code>POST</code> method to send the "file" to the server. This example uses plain text, but you can imagine the data being a binary file instead.</p>
<pre class="brush: js">var oXHR = new XMLHttpRequest();
oXHR.open("POST", url, true);
oXHR.onload = function (oEvent) {
  // Uploaded.
};

var bb = new BlobBuilder(); // prefixed: window.MozBlobBuilder or window.WebKitBlobBuilder
bb.append('abc123');

oXHR.send(bb.getBlob('text\/plain'));
</pre>
<h3>Sending typed arrays as binary data</h3>
<p>You can send JavaScript typed arrays as binary data as well.</p>
<pre class="brush: js">var myArray = new ArrayBuffer(512);
var longInt8View = new Uint8Array(myArray);

for (var i=0; i&lt; longInt8View.length; i++) {
  longInt8View[i] = i % 255;
}

var xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.send(myArray);
</pre>
<p>This is building a 512-byte array of 8-bit integers and sending it; you can use any binary data you'd like, of course.</p>
<div class="note"><strong>Note:</strong> Support for sending <a href="/en/JavaScript_typed_arrays/ArrayBuffer" title="ArrayBuffer"><code>ArrayBuffer</code></a> objects using XMLHttpRequest was added to Gecko 9.0 {{ geckoRelease("9.0") }}. <strong>Add information about other browsers' support here.</strong></div>
<h3>Firefox-specific examples</h3>
<p>This example transmits binary content asynchronously, using the <code>POST</code> method, and Firefox's non-stand <code>sendAsBinary()</code>.</p>
<pre class="brush: js">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>Line 4 sets the Content-Length header to 741, indicating that the data is 741 bytes long.  Obviously you need to change this value based on the actual size of the data being sent.</p>
<p>Line 5 uses the <code>sendAsBinary()</code> method to initiate the request.</p>
<p>You can also send binary content by passing an instance of the {{ interface("nsIFileInputStream") }} to <a class="internal" href="/en/DOM/XMLHttpRequest#send()" title="/En/XMLHttpRequest#send()"><code>send()</code></a>.  In that case, you don't have to set the <code>Content-Length</code> header yourself, as the information is fetched from the stream automatically:</p>
<pre class="brush: js">// Make a stream from a file.
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 (oEvent) { /* 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>
<h2>Monitoring progress</h2>
<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>{{ h1_gecko_minversion("In Firefox 3.5 and later", "1.9.1") }}</p>
<p>Gecko 1.9.1 {{ geckoRelease("1.9.1") }} adds support for DOM progress event monitoring of <code>XMLHttpRequest</code> transfers; this follows the Web API <a class="external" href="http://dev.w3.org/2006/webapi/progress/Progress.html" title="http://dev.w3.org/2006/webapi/progress/Progress.html">specification for progress events</a>.</p>
<pre class="brush: js">var req = new XMLHttpRequest();

req.addEventListener("progress", updateProgress, false);
req.addEventListener("load", transferComplete, false);
req.addEventListener("error", transferFailed, false);
req.addEventListener("abort", transferCanceled, false);

req.open();

...

// progress on transfers from the server to the client (downloads)
function updateProgress(evt) {
  if (evt.lengthComputable) {
    var percentComplete = evt.loaded / evt.total;
    ...
  } else {
    // Unable to compute progress information since the total size is unknown
  }
}

function transferComplete(evt) {
  alert("The transfer is complete.");
}

function transferFailed(evt) {
  alert("An error occurred while transferring the file.");
}

function transferCanceled(evt) {
  alert("The transfer has been canceled by the user.");
}
</pre>
<p>Lines 3-6 add event listeners for the various events that are sent while performing a data transfer using <code>XMLHttpRequest</code>.  See {{ interface("nsIDOMProgressEvent") }} and {{ interface("nsIXMLHttpRequestEventTarget") }} for details on these events.</p>
<div class="note"><strong>Note:</strong> You need to add the event listeners before calling <code>open()</code> on the request.  Otherwise the progress events will not fire.</div>
<p>The progress event handler, specified by the <code>updateProgress()</code> function in this example, receives the total number of bytes to transfer as well as the number of bytes transferred so far in the event's <code>total</code> and <code>loaded</code> fields.  However, if the <code>lengthComputable</code> field is false, the total length is not known and will be zero.</p>
<p>Progress events exist for both download and upload transfers. The download events are fired on the <code>XMLHttpRequest</code> object itself, as shown in the above sample. The upload events are fired on the <code>XMLHttpRequest.upload</code> object, as shown below:</p>
<pre class="brush: js">var req = new XMLHttpRequest();

req.upload.addEventListener("progress", updateProgress, false);
req.upload.addEventListener("load", transferComplete, false);
req.upload.addEventListener("error", transferFailed, false);
req.upload.addEventListener("abort", transferCanceled, false);

req.open();
</pre>
<div class="note"><strong>Note:</strong> Progress events are not available for the <code>file:</code> protocol.</div>
<div class="geckoVersionNote" style="undefined"> <p>{{ gecko_callout_heading("9.0") }}</p> <p>Starting in Gecko 9.0 {{ geckoRelease("9.0") }}, progress events can now be relied upon to come in for every chunk of data received, including the last chunk in cases in which the last packet is received and the connection closed before the progress event is fired. In this case, the progress event is automatically fired when the load event occurs for that packet. This lets you now reliably monitor progress by only watching the "progress" event.</p>
</div>
<h3>In Firefox 3 and earlier</h3>
<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 class="brush: js">function onProgress (oEvent) {
  var percentComplete = oEvent.position * 100 / oEvent.totalSize;
  // ...
}

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

function onLoad(oEvent) {
  // ...
}
// ...
var req = new XMLHttpRequest();
req.onprogress = onProgress; // or req.addEventListener("progress", onProgress, false);
req.open("GET", url, true);
req.onload = onLoad; // or req.addEventListener("load", onLoad, false);
req.onerror = onError; // or req.addEventListener("error", onError, false);
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"><strong>Note:</strong> <a href="/en/Firefox_3_for_developers" title="en/Firefox_3_for_developers">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 {{ Bug("198595") }} for details.</div>
<p>{{ h2_gecko_minversion("Detecting any load end condition", "5.0") }}</p>
<p>Starting in Gecko 5.0 {{ geckoRelease("5.0") }}, you can detect all three load-ending conditions (<code>abort</code>, <code>load</code>, or <code>error</code>) using the <code>loadend</code> event:</p>
<pre class="brush: js">req.addEventListener("loadend", loadEnd, false);

function loadEnd(evt) {
  alert("The transfer finished (although we don't know if it succeeded or not).");
} 
</pre>
<p>Note that there's no way to be certain from the information received by the <code>loadend</code> event as to which condition caused the operation to terminate; however, you can use this to handle tasks that need to be performed in all end-of-transfer scenarios.</p>
<h2>Cross-site XMLHttpRequest</h2>
<p>{{ fx_minversion_section("3") }}</p>
<p>Firefox 3.5 supports cross-site requests by implementing the web applications working group's <a class="internal" href="/En/HTTP_access_control" title="en/HTTP access control">Access Control for Cross-Site Requests</a> standard.  As long as the server is configured to allow requests from your web application's origin, <code>XMLHttpRequest</code> will work.  Otherwise, an <code>INVALID_ACCESS_ERR</code> exception is thrown.</p>
<h2>Bypassing the cache</h2>
<p>Normally, <code>XMLHttpRequest</code> tries to retrieve content from the cache, if it's available.  To bypass this, do the following:</p>
<pre class="brush: js">var req = new XMLHttpRequest();
req.open('GET', url, false);
<strong>req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;</strong>
req.send(null);</pre>
<div class="note"><strong>Note:</strong> This approach will only work in Gecko-based software, as the <code>channel</code> attribute is Gecko-specific.</div>
<p>An alternate, cross-browser compatible approach is to append a timestamp to the URL, being sure to include a "?" or "&amp;" as appropriate.  For example:</p>
<pre>http://foo.com/bar.html</pre>
<p>becomes</p>
<pre>http://foo.com/bar.html?12345</pre>
<p>and</p>
<pre>http://foo.com/bar.html?foobar=baz</pre>
<p>becomes</p>
<pre>http://foo.com/bar.html?foobar=baz&amp;12345</pre>
<p>Since the local cache is indexed by URL, this causes every request to be unique, thereby bypassing the cache.</p>
<p>You can automatically adjust URLs using the following code:</p>
<pre class="brush: js">var req = new XMLHttpRequest();
req.open("GET", url += ((/\?/).test(url) ? "&amp;" : "?") + (new Date()).getTime(), false);
req.send(null); </pre>
<h2>Security</h2>
<p>{{ fx_minversion_note("3") }}</p>
<p>{{ fx_minversion_note("5") }}</p>
<p>The recommended way to enable cross-site scripting is to use the <code>Access-Control-Allow-Origin </code> HTTP header in the response to the XMLHttpRequest.</p>
<h3>XMLHttpRequests being stopped</h3>
<p>If you end up with an XMLHttpRequest having <code>status=0</code> and <code>statusText=null</code>, it means that the request was not allowed to be performed. It was <code><a class="external" href="http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-unsent" title="http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-unsent">UNSENT</a></code>. A likely cause for this is when the <a class="external" href="http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest-origin" style="outline: 1px dotted; outline-offset: 0pt;"><code>XMLHttpRequest</code> origin</a> (at the creation of the XMLHttpRequest) has changed when the XMLHttpRequest is then <code>open()</code>. This case can happen for example when one has an XMLHttpRequest that gets fired on an onunload event for a window: the XMLHttpRequest gets in fact created when the window to be closed is still there, and then the request is sent (ie <code>open()</code>) when this window has lost its focus and potentially different window has gained focus. The way to avoid this problem is to set a listener on the new window "activate" event that gets set when the old window has its "unload" event fired.</p>
<h2>Downloading JSON and JavaScript from extensions</h2>
<p>For security reasons, extensions should never use <code><a href="/en/JavaScript/Reference/Global_Objects/eval" title="en/Core_JavaScript_1.5_Reference/Global_Functions/eval">eval()</a></code> to parse JSON or JavaScript code downloaded from the web.  See <a href="/en/Downloading_JSON_and_JavaScript_in_extensions" title="en/Downloading_JSON_and_JavaScript_in_extensions">Downloading JSON and JavaScript in extensions</a> for details.</p>
<h2>Using XMLHttpRequest from JavaScript modules / XPCOM components</h2>
<p>Instantiating <code>XMLHttpRequest</code> from a <a href="/en/JavaScript_code_modules/Using" title="https://developer.mozilla.org/en/JavaScript_code_modules/Using_JavaScript_code_modules">JavaScript module</a> or an XPCOM component works a little differently; it can't be instantiated using the <code>XMLHttpRequest()</code> constructor. 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 class="brush: js">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 class="brush: js">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 <code>QueryInterface</code> the component to an <code>nsIEventTarget</code> in order to add event listeners, but chances are that in C++, using a channel directly would be better.</p><h2>See also</h2>
<ol> <li><a href="/en/AJAX/Getting_Started" title="en/AJAX/Getting_Started">MDC AJAX introduction</a></li> <li><a class="internal" href="/En/HTTP_access_control" title="En/HTTP access control">HTTP access control</a></li> <li><a class="internal" href="/En/How_to_check_the_security_state_of_an_XMLHTTPRequest_over_SSL" title="En/How to check the security state of an XMLHTTPRequest over SSL">How to check the security state of an XMLHTTPRequest over SSL</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://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 Specification</a></li> <li><a class="external" href="http://dev.w3.org/2006/webapi/progress/Progress.html" title="http://dev.w3.org/2006/webapi/progress/Progress.html">Web Progress Events specification</a></li> <li><a class="external" href="http://www.bluishcoder.co.nz/2009/06/05/reading-ogg-files-with-javascript.html" title="http://www.bluishcoder.co.nz/2009/06/05/reading-ogg-files-with-javascript.html">Reading Ogg files with JavaScript (Chris Double)</a></li>
</ol>
<p>{{ languages( { "ja": "Ja/Using_XMLHttpRequest"} ) }}</p>
Revert to this revision