Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.
XMLHttpRequest
(and why we won't use it)XMLHttpRequest
object that can fetch files from a web server
XMLHttpRequest
objectXMLHttpRequest
object requests page from serverXMLHttpRequest
fires an event when data arrives
new Ajax.Request("url", { option : value, option : value, ... option : value } );
Ajax.Request
object to request a page from a server using Ajax{}
braces
(an anonymous JS object)
XMLHttpRequest
; works well in all browsersoption | description |
---|---|
method
|
how to fetch the request from the server (default "post" )
|
parameters
|
query parameters to pass to the server, if any (as a string or object) |
asynchronous
|
should request be sent asynchronously in the background? (default true )
|
others: contentType , encoding ,
requestHeaders
|
new Ajax.Request("http://www.example.com/foo/bar.txt",
{
method: "get",
parameters: {name: "Ed Smith", age: 29}, // "name=Ed+Smith&age=29"
...
}
);
event | description |
---|---|
onSuccess
|
request completed successfully |
onFailure
|
request was unsuccessful |
onException
|
request has a syntax error, security error, etc. |
others: onCreate , onComplete ,
on### (for HTTP error code ###)
|
new Ajax.Request("http://www.example.com/foo.php",
{
parameters: {password: "abcdef"}, // "password=abcdef"
onSuccess: mySuccessFunction
}
);
new Ajax.Request("url", { method: "get", onSuccess: functionName } ); ... function functionName(ajax) { do something with ajax.responseText; }
onSuccess
eventajax
, as a parameterproperty | description |
---|---|
status
|
the request's HTTP error code (200 = OK, etc.) |
statusText
|
HTTP error code text |
responseText
|
the entire text of the fetched file, as a String
|
responseXML
|
the entire contents of the fetched file, as a DOM tree (seen later) |
function handleRequest(ajax) { alert(ajax.responseText); }
responseText
, to access the fetched text contentXMLHttpRequest
security restrictions
http://www.foo.com/a/b/c.html
can only connect to www.foo.com
new Ajax.Request("url", { method: "get", onSuccess: functionName, onFailure: ajaxFailure, onException: ajaxFailure } ); ... function ajaxFailure(ajax, exception) { alert("Error making Ajax request:" + "\n\nServer status:\n" + ajax.status + " " + ajax.statusText + "\n\nServer response text:\n" + ajax.responseText); if (exception) { throw exception; } }
POST
request
new Ajax.Request("url",
{
method: "post", // optional
parameters: { name: value, name: value, ..., name: value },
onSuccess: functionName,
onFailure: functionName,
onException: functionName
}
);
method
should be changed to "post"
(or omitted; post
is default)parameters
parameter
{}
braces as a set of name : value pairs (another anonymous object)get
request parameters can also be passed this way, if you likenew Ajax.Updater("id", "url", { method: "get" } );
Ajax.Updater
fetches a file and injects its content into an element as innerHTML
id
of element to inject intoonSuccess
handler not needed (but onFailure
, onException
handlers may still be useful)new Ajax.PeriodicalUpdater("id", "url", { frequency: seconds, name: value, ... } );
Ajax.PeriodicalUpdater
repeatedly fetches a file at a given interval and injects its content into an element as innerHTML
onSuccess
handler not needed (but onFailure
, onException
handlers may still be useful)Ajax.Responders.register( { onEvent: functionName, onEvent: functionName, ... } );
My note: BEGIN TO: Tove FROM: Jani SUBJECT: Reminder MESSAGE (english): Hey there, Don't forget to call me this weekend! END
<element attribute="value">content</element>
h1
, div
, img
, etc.id
/class
, src
, href
, etc.<?xml version="1.0" encoding="UTF-8"?> <!-- XML prolog --> <note> <!-- root element --> <to>Tove</to> <from>Jani</from> <!-- element ("tag") --> <subject>Reminder</subject> <!-- content of element --> <message language="english"> <!-- attribute and its value --> Don't forget me this weekend! </message> </note>
<?xml ... ?>
header tag ("prolog")note
)to
, from
, subject
book
, title
, author
<?xml version="1.0" encoding="UTF-8"?> <categories> <category>children</category> <category>computers</category> ... </categories>
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
innerHTML
in the XML DOM!
* (though not Prototype's, such as up
, down
, ancestors
, childElements
, or siblings
)
id
s or class
es to use to get specific nodes (no $
or $$
). Instead:
// returns all child tags inside node that use the given element
var elms = node.getElementsByTagName("tagName");
innerHTML
to get the text inside a node. Instead:
var text = node.firstChild.nodeValue;
.attributeName
to get an attribute's value from a node. Instead:
var attrValue = node.getAttribute("attrName");
XMLnode.getElementsByTagName("tag")
XMLelement.getAttribute("name")
, XMLelement.firstChild.nodeValue
, etc.document.createElement("tag")
, HTMLelement.innerHTML
HTMLelement.appendChild(element)
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 XML DOM object<?xml version="1.0" encoding="UTF-8"?> <employees> <lawyer money="5"/> <janitor name="Sue"><vacuumcleaner/></janitor> <janitor name="Bill">too poor</janitor> </employees>
We can use DOM properties and methods on ajax.responseXML
:
// zeroth element of array of length 1 var employeesTag = ajax.responseXML.getElementsByTagName("employees")[0]; // how much money does the lawyer make? var lawyerTag = employeesTag.getElementsByTagName("lawyer")[0]; var salary = lawyerTag.getAttribute("money"); // "5" // array of 2 janitors var janitorTags = employeesTag.getElementsByTagName("janitor"); var excuse = janitorTags[1].firstChild.nodeValue; // " too poor "
<?xml version="1.0" encoding="UTF-8"?> <employees> <lawyer money="5"/> <janitor name="Bill"><vacuumcleaner/></janitor> <janitor name="Sue">too poor</janitor> </employees>
What are the results of the following expressions?
// zeroth element of array of length 1
var employeesTag = ajax.responseXML.getElementsByTagName("employees")[0];
employeesTag.firstChild
ajax.responseXML.getElementsByTagName("lawyer")
employeesTag.getElementsByTagName("janitor").length
employeesTag.getElementsByTagName("janitor")[0].firstChild
employeesTag.getElementsByTagName("janitor")[1].firstChild
employeesTag.getElementsByTagName("janitor")[0].nextSibling
<?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>
// 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") { // extract data from XML var title = books[i].getElementsByTagName("title")[0].firstChild.nodeValue; var author = books[i].getElementsByTagName("author")[0].firstChild.nodeValue; // make an XHTML <p> tag containing data from XML var p = document.createElement("p"); p.innerHTML = title + ", by " + author; document.body.appendChild(p); } }
http://webster.cs.washington.edu/cse190m/hw/hw.php
assignment=hwN
animalgame.php
.<node nodeid="id"> <question>question</question> <yes nodeid="id" /> <no nodeid="id" /> </node>
<node nodeid="id"> <answer>answer</answer> </node>
animalgame.php?nodeid=id
nodeid
of 1
to get the first questionQuestions we should ask ourselves:
responseXML
in FirebugJavaScript Object Notation (JSON): Data format that represents data as a set of JavaScript objects
var person = { name: "Philip J. Fry", // string age: 23, // number "weight": 172.5, // number friends: ["Farnsworth", "Hermes", "Zoidberg"], // array getBeloved: function() { return this.name + " loves Leela"; } }; alert(person.age); // 23 alert(person["weight"]); // 172.5 alert(person.friends[2])); // Zoidberg alert(person.getBeloved()); // Philip J. Fry loves Leela
this
.fieldName
or ["fieldName"]
syntaxweight
above)<?xml version="1.0" encoding="UTF-8"?> <note private="true"> <from>Alice Smith (alice@example.com)</from> <to>Robert Jones (roberto@example.com)</to> <to>Charles Dodd (cdodd@example.com)</to> <subject>Tomorrow's "Birthday Bash" event!</subject> <message language="english"> Hey guys, don't forget to call me this weekend! </message> </note>
{ "private": "true", "from": "Alice Smith (alice@example.com)", "to": [ "Robert Jones (roberto@example.com)", "Charles Dodd (cdodd@example.com)" ], "subject": "Tomorrow's \"Birthday Bash\" event!", "message": { "language": "english", "text": "Hey guys, don't forget to call me this weekend!" } }
method | description |
---|---|
JSON.parse(string)
|
converts the given string of JSON data into an equivalent JavaScript object and returns it |
JSON.stringify(object)
|
converts the given object into a string of JSON data (the opposite of JSON.parse )
|
JSON.parse
on it to convert it into an objectvar data = JSON.parse(ajax.responseText);
{ "window": { "title": "Sample Widget", "width": 500, "height": 500 }, "image": { "src": "images/logo.png", "coords": [250, 150, 350, 400], "alignment": "center" }, "messages": [ {"text": "Save", "offset": [10, 30]} {"text": "Help", "offset": [ 0, 50]}, {"text": "Quit", "offset": [30, 10]}, ], "debug": "true" }
Given the JSON data at right, what expressions would produce:
var title = data.window.title; var coord = data.image.coords[2]; var len = data.messages.length; var y = data.messages[len - 1].offset[1];
Suppose we have a service books_json.php
about library books.
{ "categories": ["computers", "cooking", "finance", ...] }
category
query parameter to see all books in one category: { "books": [ {"category": "cooking", "year": 2009, "price": 22.00, "title": "Breakfast for Dinner", "author": "Amanda Camp"}, {"category": "cooking", "year": 2010, "price": 75.00, "title": "21 Burgers for the 21st Century", "author": "Stuart Reges"}, ... ] }
Write a page that processes this JSON book data.
function showBooks(ajax) { // add all books from the JSON data to the page's bulleted list var data = JSON.parse(ajax.responseText); for (var i = 0; i < data.books.length; i++) { var li = document.createElement("li"); li.innerHTML = data.books[i].title + ", by " + data.books[i].author + " (" + data.books[i].year + ")"; $("books").appendChild(li); } }
eval
function// var data = JSON.parse(ajax.responseText); var data = eval(ajax.responseText); // don't do this! ...
eval
keyword that takes a string and runs it as codeJSON.parse
does,JSON.parse
filters out potentially dangerous code; eval
doesn'teval
is evil and should not be used!