Safari Reference Library Apple Developer
Search

Using XMLHttpRequest Objects

Safari, Dashboard, and WebKit-based applications support the JavaScript XMLHttpRequest object. XMLHttpRequest (often abbreviated as XHR) allows you to easily fetch content from a server and use it within your webpage or widget without requiring a page reload.

For example, you can use XHR to update a store search page so that when the user enters a Zip code, your site can display stores within a reasonable distance. Clicking on a store could then fill a particular content div with details on that store.

Of course, you could do any of these things without XHR (by requiring a full page load or by including information about every store in the country in a single page), but XHR provides a way to do this more efficiently with less bandwidth.

Introduction to XMLHttpRequest

XMLHttpRequest is a JavaScript object provided by WebKit that fetches data via HTTP for use within your JavaScript code. It’s tuned for retrieving XML data but can be used to perform any HTTP request. XML data is made available in a DOM object that lets you use standard DOM operations, as discussed in “Using the Document Object Model From JavaScript,” to extract data from the request response.

Typically, you define an XMLHttpRequest object’s options and provide an onload or onreadystatechange handler, then send the request. When the request is complete, you work with either the request’s response text or its response XML, as discussed in “XMLHttpRequest Responses.”

Defining an XMLHttpRequest Object

To create a new instance of the XMLHttpRequest object, call the object’s constructor with the new keyword and save the result in a variable, like this:

var myRequest = new XMLHttpRequest();

Note: If you are writing a webpage, you should be aware that most versions of Microsoft Internet Explorer on Windows do not support creating an XMLHttpRequest object in this way. Jibbering.com has cross-browser sample code at http://jibbering.com/2002/4/httprequest.html if you need to support Internet Explorer prior to version 7.

After you have created a new XMLHttpRequest object, call open to initialize the request:

myRequest.open("GET", "http://www.apple.com/");

The open method requires two arguments: the HTTP method and the URI of the data to fetch. It also can take three more arguments: an asynchronous flag, a username, and a password. By default, XMLHttpRequest executes asynchronously.

After you open the request, use setRequestHeader to provide any optional HTTP headers for the request, like this:

myRequest.setRequestHeader("Cache-Control", "no-cache");

Note: This particular header asks web caches between the browser and the server to not serve the request from a cache. Not all caches respect these flags, however, and some browsers do not consistently respect it, either.

This can be problematic if, for example, you send a request in an onChange handler on a form field. If that request can be cached, any request that changes the field back to a previous value won’t ever reach the server, resulting in the UI not matching the actual values stored on the server.

Thus, if it is absolutely essential that a request not be served from a cache, you should err on the side of caution by adding a timestamp or other nonrecurring value to the end of each URL. For example: http://mysite.mydomain.top/file.html?junktimevalue=1187999959.

To handle the different states of a request, set a handler function for the onreadystatechange event:

myRequest.onreadystatechange = myReadyStateChangeHandlerFunction;

If the only state you’re concerned about is the loaded state (state 4), try using the onload event instead:

myRequest.onload = myOnLoadHandlerFunction;

If you are sending a cross-site request (see “Using XMLHttpRequest for Cross-Site Requests” for more information) and want cookies or authentication information to be sent to the remote server, you need to enable credentials:

myRequest.withCredentials = "true";

When the request is ready, use the send method to send it:

myRequest.send();

If your request is sending content, like a string or DOM object, pass it in as the argument to the send method.

XMLHttpRequest Responses

Once your send your request, you can abort it using the abort method:

myRequest.abort();

If you provided an onreadystatechange handler, you can query your request to find its current state using the readyState property:

var myRequestState = myRequest.readyState;

A readyState value of 4 means that content has loaded. This is similar to providing an onload handler, which is called when a request’s readyState equals 4.

When a request is finished loading, you can query its HTTP status using the status and statusText properties:

var myRequestStatus = myRequest.status;
var myRequestStatusText = myRequest.statusText;

Also, you can fetch the request’s HTTP response headers using the getResponseHeader method:

var aResponseHeader = myRequest.getResponseHeader("Content-Type");

To obtain a list of all of the response headers for a request, use getAllResponseHeaders:

var allResponseHeaders = myRequest.getAllResponseHeaders();

To obtain the request’s response XML as a DOM object, use the responseXML property:

var myResponseXML = myRequest.responseXML;

This object responds to standard DOM methods, like getElementsByTagName. If the response is not in a valid XML format, use the responseText property to access the raw text response:

var myResponseText = myRequest.responseText;

Security Considerations

Within Safari, the XMLHttpRequest object can only make requests to http and https URIs in the same domain as the webpage.

As an exception, however, beginning with Safari 4.0, a website can allow content served by other websites to request data from specific http and https URLs on their servers.

Note: To enable this behavior, the site must send specific response headers conforming to the Cross-Origin Resource Sharing specification, defined by the Web Applications Working Group. It is not possible to make HTTP requests to arbitrary sites without the cooperation of those sites.

Using XMLHttpRequest for Cross-Site Requests

For the most part, the XMLHttpRequest object works the same way when used in a cross-site fashion. There are a few exceptions, however.

Warning: Data requested from a remote site should be treated as untrusted. For example, you should not execute JavaScript code retrieved from a remote site without thoroughly checking it for validity.

Access Control Request Headers

Before performing the actual request, the browser first sends an OPTIONS query to the server to ask if it is allowed to send the actual request. The following headers are sent by the browser as part of this query and may be used by scripts on the remote web server when deciding whether or not to allow the request:

Origin

Contains the non-path portion of the resource making the request (for example, http://example.com).

Access-Control-Request-Method

Contains the method that the actual request will use (GET or POST, for example).

Access-Control-Request-Headers

Indicates which HTTP headers will be sent in the actual request.

Access Control Response Headers

Before performing the actual request, the browser first sends an OPTIONS query to the server to ask if it is allowed to send the actual request. The following headers may be sent by the remote web server (or scripts running on that server) in response to this request to control cross-site access policies:

Access-Control-Allow-Origin

Indicates that a particular origin can access the resource. The value may be either a specific origin (http://example.com, for example) or an asterisk (*) wildcard, which allows any domain to access the resource.

Access-Control-Max-Age

Indicates how long a browser should continue to cache the site’s acceptance of requests from other domains. If your site only allows requests from other domains after some specific handshake by a user, for example, you might set this to a short value.

Access-Control-Allow-Credentials

Indicates that the request may be made with credentials. The only allowable value is true. To disallow credentials, omit this header.

Access-Control-Allow-Methods

Provides a request method that the script may use for future requests (GET or POST, for example). The valid methods are defined in RFC 2616. This field may be specified more than once to allow multiple methods.

Access-Control-Allow-Headers

Provides a header field name that the client has permission to use in the actual request.




Last updated: 2010-01-20

Did this document help you? Yes It's good, but... Not helpful...