Except where otherwise noted, the contents of this presentation are Copyright 2009 Marty Stepp and Jessica Miller.
XMLHttpRequest
Ajax: Asynchronous JavaScript and XML
XMLHttpRequest
object can fetch files from a web server
XMLHttpRequest
objectXMLHttpRequest
object requests a document from a web serverXMLHttpRequest
fires event to say that the data has arrived
XMLHttpRequest
XMLHttpRequest
objectthe core JavaScript object that makes Ajax possible
abort
, getAllResponseHeaders
, getResponseHeader
, open
, send
, setRequestHeader
onreadystatechange
, readyState
, responseText
, responseXML
, status
, statusText
ActiveXObject
instead
var ajax = new XMLHttpRequest();
ajax.open("GET", url, false);
ajax.send(null);
// at this point, the request will have returned with its data
do something with ajax.responseText;
send
returns, the fetched text will be stored in request's responseText
property
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = functionName;
ajax.open("get", url, true);
ajax.send(null);
// don't process ajax.responseText here, but in your function
...
onreadystatechange
eventtrue
as third parameter to open
readyState
propertyXMLHttpRequest
readyState
property:
State | Description |
---|---|
0 | not initialized |
1 | set up |
2 | sent |
3 | in progress |
4 | complete |
readyState
changes → onreadystatechange
handler runsreadyState
of 4 (complete)XMLHttpRequest
template
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (ajax.readyState == 4) { // 4 means request is finished
do something with ajax.responseText;
}
};
ajax.open("get", url, true);
ajax.send(null);
ajax
)
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (ajax.readyState == 4) {
if (ajax.status == 200) { // 200 means request succeeded
do something with ajax.responseText;
} else {
code to handle the error;
}
}
};
ajax.open("get", url, true);
ajax.send(null);
new Ajax.Request( "url", { option : value, option : value, ... option : value } );
Ajax.Request
object constructor accepts 2 parameters:
{}
bracesonreadystatechange
, etc.)Ajax.Request
constructor:
method
: how to fetch the request from the server (default "post"
)
parameters
: query parameters to pass to the server, if any
asynchronous
(default true
),
contentType
,
encoding
,
requestHeaders
Ajax.Request
object that you can handle:
onSuccess
: request completed successfully
onFailure
: request was unsuccessful
onCreate
,
onComplete
,
onException
,
on###
(handler for HTTP error code ###)
new Ajax.Request( "url", { method: "get", onSuccess: functionName } ); ... function functionName(ajax) { do something with ajax.responseText; }
onSuccess
eventXMLHttpRequest
object, ajax
, as a parameternew Ajax.Request( "url", { method: "get", onSuccess: functionName, onFailure: ajaxFailure } ); ... function ajaxFailure(ajax) { alert("Error making Ajax request:" + "\n\nServer status:\n" + ajax.status + " " + ajax.statusText + "\n\nServer response text:\n" + ajax.responseText); }
POST
request
new Ajax.Request(
"url",
{
method: "POST", // optional
parameters: { name: value, name: value, ..., name: value },
onSuccess: functionName,
onFailure: functionName
}
);
Ajax.Request
can also be used to post data to a web servermethod
should be changed to "post"
(or omitted; post
is default)parameters
parameter, written between {}
braces as name: value pairs
get
request parameters can also be passed this way, if you likenew Ajax.Updater( "id", "url", { method: "get" } );
Ajax.Updater
can be used if you want to fetch a file via Ajax and inject its text/HTML contents into an onscreen elementid
of the element into which to inject the contentWhen writing Ajax programs, there are new kinds of bugs that are likely to appear.
responseText
or responseXML
has no properties.How do we find and fix such bugs?
XMLHttpRequest
security restrictions
www.foo.com/a/b/c.html
can only fetch from www.foo.com
XMLHttpRequest
<... ...="..."></...>
h1
, img
) and attributes (id
/class
on all elements, src
/alt
on img
tag)<?xml version="1.0" encoding="UTF-8"?> <note> <to>Tove</to> <from>Jani</from> <subject>Reminder</subject> <message language="english"> Don't forget me this weekend! </message> </note>
note
)to
, from
, subject
book
, title
, author
<bloop bleep="flibbetygibbet">quirkleblat</bloop>
new Ajax.Request(
"url",
{
method: "get",
onSuccess: functionName
}
);
...
function functionName(ajax) {
do something with ajax.responseXML;
}
ajax.responseText
contains the XML data in plain textajax.responseXML
is a pre-parsed DOM object representing the XML file as a tree (more useful)responseXML
object, using DOM methods and propertiesAll of the DOM properties and methods we already know can be used on XML nodes:
firstChild
, lastChild
, childNodes
, nextSibling
, previousSibling
, parentNode
nodeName
, nodeType
, nodeValue
, attributes
appendChild
, insertBefore
, removeChild
, replaceChild
getElementsByTagName
, getAttribute
, hasAttributes
, hasChildNodes
<?xml version="1.0" encoding="UTF-8"?> <categories> <category>children</category> <category>computers</category> ... </categories>
<?xml version="1.0" encoding="UTF-8"?> <foo bloop="bleep"> <bar/> <baz><quux/></baz> <baz><xyzzy/></baz> </foo>
We can use DOM properties and methods on ajax.responseXML
:
// zeroth element of array of length 1 var foo = ajax.responseXML.getElementsByTagName("foo")[0]; // same var bar = foo.getElementsByTagName("bar")[0]; // array of length 2 var all_bazzes = foo.getElementsByTagName("baz"); // string "bleep" var bloop = foo.getAttribute("bloop");
<?xml version="1.0" encoding="UTF-8"?> <foo bloop="bleep"> <bar/> <baz><quux/></baz> <baz><xyzzy/></baz> </foo>
We are reminded of some pitfalls of the DOM:
// works - XML prolog is removed from document tree var foo = ajax.responseXML.firstChild; // WRONG - just a text node with whitespace! var bar = foo.firstChild; // works var first_baz = foo.getElementsByTagName("baz")[0]; // WRONG - just a text node with whitespace! var second_baz = first_baz.nextSibling; // works - why? var xyzzy = second_baz.firstChild;
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="cooking"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year><price>30.00</price> </book> <book category="computers"> <title lang="en">XQuery Kick Start</title> <author>James McGovern</author> <year>2003</year><price>49.99</price> </book> <book category="children"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year><price>29.99</price> </book> <book category="computers"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year><price>39.95</price> </book> </bookstore>
id
s or class
es to use to get specific nodesfirstChild
/nextSibling
properties are unreliablegetElementsByTagName
:
node.getElementsByTagName("tagName")
"book"
, "subject"
, etc.)node.getAttribute("attributeName")
category
, lang
)// make a paragraph for each book about computers var books = ajax.responseXML.getElementsByTagName("book"); for (var i = 0; i < books.length; i++) { var category = books[i].getAttribute("category"); if (category == "computers") { var title = books[i].getElementsByTagName("title")[0].firstChild.nodeValue; var author = books[i].getElementsByTagName("author")[0].firstChild.nodeValue; // make an XHTML <p> tag based on the book's XML data var p = document.createElement("p"); p.innerHTML = title + ", by " + author; document.body.appendChild(p); } }
ajax.responseText
responseXML
in Firebug