Vous êtes sur la page 1sur 68

01

chapter

Ajax
Hacks #1~#11

(world wide wait)


.
. , ,
, , , , ,
... .
( )
.
, .

.

.
.
.
?

Ajax Hacks :



. . Ajax
. Ajax Asynchronous JavaScript and XML .
Ajax , . Ajax
.
: .
(

). .

XMLHttpRequest : API HTTP


(connect) . Ajax ,

( , 6, 1.3, 2.0, 7.6)


. Ajax (asynchronous) .*
XML(eXtensible Markup Language) : (Language)
. XMLHttpRequest
XML .
HTML CSS(Cascading Style Sheets) : .
HTML CSS
.
DOM(Document Object Model) : DOM XML
. , ,
, . HTML
( ). DOM
.
XSLT(eXtensible Stylesheet Language and Transformation) :
XML .

[*] XMLHttpquest . ,
. XMLHttpquest .

24

1. Ajax

Ajax . ,
5.0 HTTP (XMLHTTP
) ( IE 6, 7 ).

Ajax
Ajax Rich Internet Application(
.Web 2.0
RIA )

, , (Zimbra),
(Rollyo, http://www.rollyo.com), (http://map.search.ch/index
.en.html) Web 2.0 . Ajax

. .
http://en.wiki pedia.org/wiki/List_of_websites_using_Ajax.


Ajax .
Ajax
. URL
.
(
<> [Hack #68] RSH
,
<
Ajax
[Hack #69] ).
> <>

Ajax (Form) select , textarea,


text , ( )
. Ajax
, .

XMLHttpRequest
XMLHttpRequest .

25

Ajax Hacks :

. API , API .
[Hack #1] .
,
.

. XMLHttpRequest
open( ), send( ), abort( ) .

XMLHttpRequest (property) (IE 5.0


, 1.3, 2.0, 7, 7.6 ) .

*
.
onreadystatechange :

readyState .
readyState :

0 : uninitialized(open( ) )
1 : loading(send( ) )
2 : loaded(send( ) . header status )
3 : interactive(reponseText )
4 : completed
responseText :

[*] XMLHttpRequest onload, onprogress, onerror


. addEventListener( ), dispatchEvent( ), overrideMimeType( ), removeEventListenner( )
. http://www.xulplanet.com/references/objref/XMLHttpRequest.
html .

26

HACK

1. Ajax

responseXML : DOM

XML
status :

200(Okay), 404(Not Found)


statusText :

HTTP

.
abort() : void

HTTP .
getAllResponseHeaders() :

HTTP [Hack #9] ).


(
getResponseHeader(string header) :

.
open(string method,string url,boolean asynch) : void

HTTP / .
send(string) : void

HTTP .
setRequestHeader(string header,string value) : void

. open( ) .

HACK

#1

. Ajax

27

#1

HACK

#1

Ajax Hacks :

,
.
HTTP Ajax
. (, )
XMLHttpRequest. IE . IE 5.0
IE Microsoft.XMLHTTP( Msxml2.XMLHTTP) ActiveX
.

Microsoft.XMLHTTP Msxml2.XMLHTTP MSXML .


IE .
Microsoft.XMLHTTP , ActiveX Object Prog.ID
. MSXML 1.0.
IE 6 MSXML 1.0
. MSXML 1.0 . MSXML2.XMLHTTP
, MSXML 2.0 .
- MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.5.0 -
.

IE ,

(request object)
.
Ajax ( ,
ActiveX ) .


HTTP
. 7.1 1.5

28

HACK

1. Ajax

Window .
window.XMLHttpRequest.
.
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
request.onreadystatechange=handleResponse;
request.open("GET",theURL,true);
request.send(null);
}

request .

Prototype Ajax.Request
(6 ).

XMLHttpRequest
if(widows.XMLHttpRequest) : XMLHttpRequest null undefined
true .
new .
onreadystatechange handleResponse( ) (
XMLHttpRequest ).

open( ), send( ) .

, IE 7
XMLHttpRequest .

29

#1

HACK

#1

Ajax Hacks :

windows.XMLHttpRequest .
.
else if (window.ActiveXObject){
request=new ActiveXObject("Microsoft.XMLHTTP");
if (! request){
request=new ActiveXObject("Msxml2.XMLHTTP");
}
if(request){
request.onreadystatechange=handleResponse;
request.open(reqType,url,true);
request.send(null);
}
}

window ActiveXObject
. program ID(
Microsoft.XMLHTTP Msxml2.XMLHTTP) .

IE , Msxml2.XMLHTTP.4.0
. MSXML .
.
(if (request) {...}) .
request null undefined
Ajax .
.
/*
:
reqType: HTTP . GET POST
url: URL
asynch: */
function httpRequest(reqType,url,asynch){
//
if(window.XMLHttpRequest){
30

HACK

1. Ajax

request = new XMLHttpRequest();


} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
// ActiveXObject request null
if(request){
initReq(reqType,url,asynch);
} else {
alert( "Your browser does not permit the use of all "+
"of this application's features!");
}
}
/* */
function initReq(reqType,url,bool){
/* HTTP */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.send(null);
}

POST [Hack #2] XMLHttpRequest


POST .

HACK

#2

POST
POST

, POST HTTP
. Ajax
POST .

31

#2

HACK

#2

Ajax Hacks :

.

. POST , POST
.
( ) .
. , ,
<> POST . [ 1-1]
.

[ 1-1] POST

HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="/parkerriver/js/hack2.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Send a data tidbit</title>
</head>
<body>
<h3>A Few Facts About Yourself...</h3>
<form action="javascript:void%200" onsubmit="sendData();return false">

32

HACK

1. Ajax

<p>First name:<input type="text" name="firstname" size="20"> </p>


<p>Last name:<input type="text" name="lastname" size="20"> </p>
<p>Gender:<input type="text" name="gender" size="2"> </p>
<p>Country of origin:<input type="text" name="country" size="20"> </p>
<p><button type="submit">Send Data</button></p>
</form>
</body>
</html>

action=
javascript:void%200 .
action .
URLjavascritp:void 0
. void 0
%20 .
? action URL , < >
. action=

(hack2.js ) .
onsubmit sentData( ) . POST
(setQueryString( ) ) .
[Hack #22] ).
(
textarea
text

.
hack2.js .
setQueryString( ) .
function setQueryString(){
queryString=" ";
var frm = document.forms[0];
var numberElements = frm.elements.length;
for(var i = 0; i < numberElements; i++) {
if(i < numberElements-1) {
queryString += frm.elements[i].name+"="+

33

#2

HACK

#2

Ajax Hacks :

encodeURIComponent(frm.elements[i].value)+"&";
} else {
queryString += frm.elements[i].name+"="+
encodeURIComponent(frm.elements[i].value);
}
}
}

POST . = &
. .
firstname=Bruce&lastname=Perry&gender=M&country=USA

POST HTTP HTTP


. onsubmit
sendData( ) .
var request;
var queryString;
// POST .
function sendData(){
setQueryString();
var url="http://www.parkerriver.com/s/sender";
httpRequest("POST",url,true);
}
/*
:
reqType: HTTP . GET POST
url: URL
isAsynch: , */
function initReq(reqType,url,isAsynch){
/* HTTP */
request.onreadystatechange=handleResponse;
request.open(reqType,url,isAsynch);
/* POST Content-Type */
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
request.send(queryString);
}

34

HACK

1. Ajax

/*
Parameters:
reqType: HTTP . GET POST
url: URL
asynch: , */
function httpRequest(reqType,url,asynch){
//
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
// ActiveXObject request null
if(request){
initReq(reqType,url,asynch);
} else {
alert("Your browser does not permit the use of all "+
alert("of this application's features!");
}
}

(
httpRequest( )
[Hack #1] ). initReq( ) .

.
request.onreadystatechange=handleResponse;
. .
open( ) .


open( ) . , POST
Content-Type .

35

#2

HACK

#2

Ajax Hacks :

Content-Type , 1.3
( 1.02 ). ,
POST
.

POST .
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
request.send(queryString);

queryString .
send("firstname=Bruce&lastname=Perry&gender=M&country=USA");


.
handleResponse( ) . initReq( )
.
request.onreadystatechange=handleResponse;

readyState 4, ,
HTTP 200 . 200 HTTP
. responsText .
,
.
.
//XMLHttpRequest
function handleResponse(){

36

HACK

1. Ajax

if(request.readyState == 4){
if(request.status == 200){
alert(request.responseText);
} else {
alert("A problem occurred with communicating between "+
alert("the XMLHttpRequest object and the server program.");
}
}// if
}

[ 1-2] .

[ 1-2] !

POST XML .
. POST param
. .
.
protected void doPost(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws
ServletException, IOException {
Map reqMap = httpServletRequest.getParameterMap();
String val=null;
String tag = null;
StringBuffer body = new StringBuffer("<params>\n");
boolean wellFormed = true;
Map.Entry me = null;
for(Iterator iter= reqMap.entrySet().iterator();iter.hasNext();) {
me=(Map.Entry) iter.next();

37

#2

HACK

#3

Ajax Hacks :

val= ((String[])me.getValue())[0];
tag = (String) me.getKey();
if (! XMLUtils.isWellFormedXMLName(tag)){
wellFormed=false; break;
}
body.append("<").append(tag).append(">").
append(XMLUtils.escapeBodyValue(val)).
append("</").append(tag).append(">\n");
}
if(wellFormed) {
body.append("</params>");
sendXML(httpServletResponse,body.toString());
} else {
sendXML(httpServletResponse,"<notWellFormedParams />");
}
}

Jakarta Commons Betwixt XMLUtils


. ,
XML . POST
(name na< >me ) , XML
.

HACK

#3

XMLHttpRequest

Ajax , XMLHttpRequest
.
,
.
http_request.js , XML

38

HACK

1. Ajax

HttpRequest .
<script type="text/javascript" src="js/http_request.js"></script>

http_request.js .
var request = null;
/*
:
reqType: HTTP . GET POST
url: URL
asynch:
respHandle:
(arguments[4]) POST */
function httpRequest(reqType,url,asynch,respHandle){
//
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
//
if(request) {
//reqType POST 5
if(reqType.toLowerCase() != "post") {
initReq(reqType,url,asynch,respHandle);
} else {
//POST
var args = arguments[4];
if(args != null && args.length > 0){
initReq(reqType,url,asynch,respHandle,args);
}
}
} else {
alert("Your browser does not permit the use of all "+
alert("of this application's features!");
}
}
39

#3

HACK

#3

Ajax Hacks :

/* */
function initReq(reqType,url,bool,respHandle){
try{
/* HTTP */
request.onreadystatechange=respHandle;
request.open(reqType,url,bool);
//reqType POST 5
if(reqType.toLowerCase() == "post") {
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
request.send(arguments[4]);
} else {
request.send(null);
}
} catch (errv) {
alert(
"The application cannot contact "+
"the server at the moment.\n"+
"Please try again in a few seconds.\n"+
"Error detail: "+errv.message);
}
}

4~5 httpRequest( )
. .
.
var _url = "http://www.parkerriver.com/s/sender";
var _data="first=Bruce&last=Perry&middle=W";
httpRequest("POST",_url,true,handleResponse,_data);

. POST
.

POST HTTP POST . GET /


URL .

40

HACK

1. Ajax

POST , 4 .
(, http_request.js )
.
. HTTP
.
var _url = "http://www.parkerriver.com/s/sender";
//
httpRequest("POST",_url,true,function(){alert(request.responseText);});

httpRequest( ) [Hack #1] ,


XMLHttpRequest . initReq( )
onreadystatechange open( ),
send( ) HTTP . try/catch
. ,
URL open( ) , try/catch .
http_request.js , request
.

var request request


. request
.
function handleResponse(){
var request = null;
try{
if(request.readyState == 4){
if(request.status == 200){...

41

#3

HACK

#4

Ajax Hacks :

HACK

#4

XML
Ajax DOM Document .

XML ,
XML . XML
.
( ) GPS (Global
Positioning System) . GPS

USB .
GPS XML. XML
GPS
.
XML ,
. XML
(meta). XML XML (
<?xml version=
1.0encoding=
UTF-8
?>). 0

. .
<?xml version="1.0" encoding="UTF-8"?>
<gps>
<gpsMaker>Garmin</gpsMaker>
<gpsDevice>
Forerunner 301
</gpsDevice>
</gps>

gps gpsMaker gpsDevice .


Ajax XML . XML (Web
Service) . HTTP ,

responseXML . Ajax DOM

42

HACK

1. Ajax

. .
function handleResponse(){
if(request.readyState == 4){
if(request.status == 200){
var doc = request.responseXML;
...
}

doc DOM .
API . XML XML
DOM .

XML , request.responseText .

HTML POST [Hack #2]


. XML div .
HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="js/hack3.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Receive XML response</title>
</head>
<body>
<h3>A Few Facts About Yourself...</h3>
<form action="javascript:void%200" onsubmit="sendData();return false">
<p>First name: <input type="text" name="firstname" size="20"> </p>
<p>Last name: <input type="text" name="lastname" size="20"> </p>
<p>Gender: <input type="text" name="gender" size="2"> </p>
<p>Country of origin: <input type="text" name="country" size="20"> </p>

43

#4

HACK

#4

Ajax Hacks :

<p><button type="submit">Send Data</button></p>


<div id="docDisplay"></div>
</form>
</body>
</html>

[ 1-3] .

[ 1-3] XML

hack3.js POST .
XML . [Hack
#22]

.
, <params><firstname>Bruce</firstname>
</params> /
. POST [Hack #2]
. Ajax XML
.
var request;
var queryString;

//POST

function sendData(){

44

HACK

1. Ajax

setQueryString();
var url="http://www.parkerriver.com/s/sender";
httpRequest("POST",url,true);
}
//XMLHttpRequest
function handleResponse(){
if(request.readyState == 4){
if(request.status == 200){
var doc = request.responseXML;
var info = getDocInfo(doc);
stylizeDiv(info,document.getElementById(""docDisplay""));
} else {
alert( ""A problem occurred with communicating between ""+
alert( ""the XMLHttpRequest object and the server program."");
}
}// if
}
/* */
function initReq(reqType,url,bool){
/*HTTP */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.setRequestHeader(""Content-Type"",
""application/x-www-form-urlencoded; charset=UTF-8"");
/* */
//request.overrideMimeType(""text/xml"");
request.send(queryString);
}
/*
:
reqType:HTTP . GET POST
url: URL
asynch: */
function httpRequest(reqType,url,asynch){
// Hack #1
}
function setQueryString(){
queryString="";
var frm = document.forms[0];
45

#4

HACK

#4

Ajax Hacks :

var numberElements = frm.elements.length;


for(var i = 0; i < numberElements; i++) {
if(i < numberElements-1) {
queryString += frm.elements[i].name+"="+
encodeURIComponent(frm.elements[i].value)+"&";
} else {
queryString += frm.elements[i].name+"="+
encodeURIComponent(frm.elements[i].value);
}
}
}
/* div . */
function stylizeDiv(bdyTxt,div){
//DIV
div.innerHTML="";
div.style.backgroundColor="yellow";
div.innerHTML=bdyTxt;
}
/*DOM Document XML document */
function getDocInfo(doc){
var root = doc.documentElement;
var info = "<h3>Document root element name: <h3 />"+ root.nodeName;
var nds;
if(root.hasChildNodes()) {
nds=root.childNodes;
info+= "<h4>Root node's child node names/values:<h4/>";
for (var i = 0; i < nds.length; i++){
info+= nds[i].nodeName;
if(nds[i].hasChildNodes()){
info+= " : \"+nds[i].firstChild.nodeValue+"\"<br />";
} else {
info+= " : Empty<br />";
}
}
}
return info;
}

46

HACK

1. Ajax

request.overrideMimeType(
text/xml
) request.
overrideMimeType( ) mime
. 1.3 .

POST , getDocInfo( )
. XML
.
var doc = request.responseXML;
var info = getDocInfo(doc);

getDocInfo( ) XML (var root = doc.documentElement


;). / .

stylizeDiv( ) sytlizeDiv( ) HTML


div .
function stylizeDiv(bdyTxt,div){
//div
div.innerHTML="";
div.style.backgroundColor="yellow";
div.innerHTML=bdyTxt;
}

[ 1-4] XML .

text XML .

47

#4

HACK

#5

Ajax Hacks :

[ 1-4] XML

DOM API XML


.

HACK

#5


, , XML

XML ,
request.responseText .
. .

48

HACK

1. Ajax

.
HTML
. XMLHttp
Request [Hack #39] .

HTML. hack9.js .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="js/hack9.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Choose a stock</title>
</head>
<body>
<h3>Stock prices</h3>
<form action="javascript:void%200" onsubmit=
"getStockPrice(this.stSymbol.value);return false">
<p>Enter stock symbol: <input type="text" name=
"stSymbol" size="4"><span id="stPrice"></span></p>
<p><button type="submit">Get Stock Price</button></p>
</form>
</body>

[ 1-5] . GRMN
< > .
span .
getStockPrice( ). stSymbol
(
). .

49

#5

HACK

#5

Ajax Hacks :

[ 1-5]

var request;
var symbol;

//

function getStockPrice(sym){
symbol=sym;
if(sym){
var url="http://localhost:8080/parkerriver/s/stocks?symbol="+sym;
httpRequest("GET",url,true);
}
}
// XMLHttpRequest
function handleResponse(){
if(request.readyState == 4){
if(request.status == 200){
/* */
var stockPrice = request.responseText;
var info = "&#171;The price is: $"+stockPrice+"&#187;";
document.getElementById("stPrice").style.fontSize="0.9em";
document.getElementById("stPrice").style.
backgroundColor="yellow";
document.getElementById("stPrice").innerHTML=info;
} else {
alert("A problem occurred with communicating between "+
alert("the XMLHttpRequest object and the server program.");
}
}// if
}

50

HACK

1. Ajax

/* httpRequest() Hack #1 .
. */

getStockPrice( ) httpRequest( ) .
handle Res
ponse( ) .

[Hack #1] XMLHttpRequest


[Hack #3]

httpRequest( ) .

(request.readyState 4) HTTP 200( )


, request.responseText .
DOM . CSS .
document.getElementById("stPrice").style.fontSize="0.9em";
document.getElementById("stPrice").style.backgroundColor="yellow";
document.getElementById("stPrice").innerHTML =info;


, . span innerHtml
.

HACK

#6

,
.
.
51

#6

HACK

#6

Ajax Hacks :

Ajax
.
.
. undefined
.
.
.
.
[ 1-6] .

[ 1-6]

HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="/parkerriver/js/hack4.js">
</script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Tally your stocks</title>
</head>
<body>
<h3>Your total Stock Holdings</h3>

52

HACK

1. Ajax

<form action="javascript:void%200" onsubmit=


"getStockPrice(this.stSymbol.value,this.numShares.value);return
false">
<p>Enter stock symbol: <input type="text" name="stSymbol" size="4">
<span id="stPrice"></span></p>
<p>Enter share amount:<input type="text" name="numShares" size="10"></p>
<p><button type="submit">Get Total Value</button></p>
<div id="msgDisplay"></div>
</form>
</body>
</html>

< (Get Total Value)> , onsubmit


. getStockPrice( )
false (submit) .


, HTML hack4.js .
var request;
var symbol;
//
var numberOfShares;
function getStockPrice(sym,shs){
if(sym && shs){
symbol=sym;
numberOfShares=shs;
var url="http://localhost:8080/parkerriver/s/stocks?symbol="+sym;
httpRequest("GET",url,true);
}
}
//XMLHttpRequest
function handleResponse(){
if(request.readyState == 4){
alert(request.status);
if(request.status == 200){
/* . */
var stockPrice = request.responseText;

53

#6

HACK

#6

Ajax Hacks :

try{
if(isNaN(stockPrice)) { throw new Error(
"The returned price is an invalid number.");}
if(isNaN(numberOfShares)) { throw new Error(
"The share amount is an invalid number.");}
var info = "Total stock value:"+ calcTotal(stockPrice);
displayMsg(document.
getElementById("msgDisplay"),info,"black");
document.getElementById("stPrice").style.fontSize="0.9em";
document.getElementById("stPrice").innerHTML ="price:
"+stockPrice;
} catch (err) {
displayMsg(document.getElementById("msgDisplay"),
"An error occurred: "+
err.message,"red");
}
} else {
alert(
"A problem occurred with communicating between the "+
"XMLHttpRequest object and the server program.");
}
}// if
}
/* httpRequest() initReq() Hack #1 #2
. . */
function calcTotal(price){
return stripExtraNumbers(numberOfShares * price);
}
/* 4 */
function stripExtraNumbers(num){
//
var n2 = num.toString();
if(n2.indexOf(".") == -1) { return num; }
// 4 parseFloat
if(typeof num == "string"){
num = parseFloat(num).toFixed(4);
} else {
num = num.toFixed(4);
}
54

HACK

1. Ajax

// 0
return parseFloat(num.toString().replace(/0*$/,""));
}
function displayMsg(div,bdyText,txtColor){
//DIV
div.innerHTML="";
div.style.backgroundColor="yellow";
div.style.color=txtColor;
div.innerHTML=bdyText;
}

handleResponse( ). var
stockPrice = request.responseText stockPrice
. API isNaN( )(Not a Number) stockPrice
,

. ,goodbye
(
) true .
isNaNgoodbye

.
true ( )
.
.
. !
.

Ajax [Hack #8] .

. calcTotal( )
.
stripExtraNumbers( )

55

#6

HACK

#6

Ajax Hacks :

10.9876 ,
.

DOM
DOM(Document Object Model)
.
. handleResponse( )
displayMsg( ) .
. id stPrice div
innerHTML
.
displayMsg(document.getElementById("msgDisplay"),info,"black");
document.getElementById("stPrice").style.fontSize="0.9em";
document.getElementById("stPrice").innerHTML ="price: "+stockPrice;

displayMsg( ) . ,

.
function displayMsg(div,bdyText,txtColor){
//DIV
div.innerHTML="";
div.style.backgroundColor="yellow";
div.style.color=txtColor;
div.innerHTML=bdyText;
}

[ 1-7] .

56

HACK

1. Ajax

[ 1-7]

[ 1-8] ,
.

[ 1-8]

HACK

#7

JSON
Ajax JSON(JavaScript Object Notation)

Ajax
? JSON(JavaScript Object Notation) .
, JSON
.
57

#7

HACK

#7

Ajax Hacks :

JSON . JSON
.
JSON . JSON
.
({ )
(:) , : (,)
( })

.
hello
[1,2,3,4]

true, false, null


.

http://www.json.org .

JSON .
POST [Hack #2] JSON
.
{
firstname:"Bruce",
lastname:"Perry",
gender:"M",
country:"USA"
}

58

HACK

1. Ajax

JSON
POST [Hack #2]
HTML , .
Ajax JSON
. div JSON
.
HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="js/hack5.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Receive JSON response</title>
</head>
<body>
<h3>A Few Facts About Yourself...</h3>
<form action="javascript:void%200" onsubmit="sendData();return false">
<p>First name:<input type="text" name="firstname" size="20"> </p>
<p>Last name: <input type="text" name="lastname" size="20"> </p>
<p>Gender:<input type="text" name="gender" size="2"> </p>
<p>Country of origin:<input type="text" name="country" size="20"> </p>
<p><button type="submit">Send Data</button></p>
<div id="json"></div>
<div id="props"></div>
</form>
</body>
</html>

[ 1-9] .

59

#7

HACK

#7

Ajax Hacks :

[ 1-9] JSON

hack5.js .
. POST
[Hack #2] .

XSS(cross-site scripting)
. eval( )
.
, eval( ) responseText
(http://www.
perl.com/pub/a/2002/02/20/css.html ).

.
.
var request;
var queryString;

60

//POST

HACK

1. Ajax

function sendData(){
setQueryString();
url="http://localhost:8080/parkerriver/s/json";
httpRequest("POST",url,true);
}
// XMLHttpRequest
function handleJson(){
if(request.readyState == 4){
if(request.status == 200){
var resp = request.responseText;
var func = new Function("return "+resp);
var objt = func();
var div = document.getElementById("json");
stylizeDiv(resp,div);
div = document.getElementById("props");
div.innerHTML="<h4>In object form...</h4>"+
div.innerHTML="<h5>Properties</h5>firstname= "+
div.innerHTML=objt.firstname +"<br />lastname="+
div.innerHTML=objt.lastname+ "<br />gender="+
div.innerHTML=objt.gender+ "<br />country="+
div.innerHTML=objt.country;
} else {
alert("A problem occurred with communicating between "+
alert("the XMLHttpRequest object and the server program.");
}
}// if
}
/* */
function initReq(reqType,url,bool){
/* HTTP */
request.onreadystatechange=handleJson;
request.open(reqType,url,bool);
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
request.send(queryString);
}
/*
:
reqType: HTTP . GET POST
61

#7

HACK

#7

Ajax Hacks :

url: URL
asynch: */
function httpRequest(reqType,url,asynch){
// Hack #1, #2
}
function setQueryString(){
queryString="";
var frm = document.forms[0];
var numberElements = frm.elements.length;
for(var i = 0; i < numberElements; i++){
if(i < numberElements-1){
queryString += frm.elements[i].name+"="+
encodeURIComponent(frm.elements[i].value)+"&";
} else {
queryString += frm.elements[i].name+"="+
encodeURIComponent(frm.elements[i].value);
}
}
}
function stylizeDiv(bdyTxt,div){
//DIV
div.innerHTML=" ";
div.style.fontSize="1.2em";
div.style.backgroundColor="yellow";
div.appendChild(document.createTextNode(bdyTxt));
}

, initReq( ) HTTP
.
handleJson( ).
XML JSON .
.
( HTTP
/ JSON ).

62

HACK

1. Ajax

[Hack #8]
.

( )handleJson( ) , resp HTTP

request.responseText . .
Functio .
var func = new Function("return"+resp);

func .

.
. Function .

http://www.jibbering.com/2002/4/httprequest.html
.
JSON .
var resp = request.responseText;
var obj = eval( "(" + resp + ")" );

resp .
var resp = request.responseText;
// resp "[1,2,3,4]"
var arrObject = eval(resp);

. (
) DOM

63

#7

HACK

#7

Ajax Hacks :

( (serialization) ).
var objt = func();
var div = document.getElementById("json");
stylizeDiv(resp,div);
div = document.getElementById("props");
div.innerHTML="<h4>In object form...</h4><h5>Properties</h5>
firstname= "+
objt.firstname +"<br />lastname="+
objt.lastname+ "<br />gender="+
objt.gender+ "<br />country="+
objt.country;

objt . objt.firstname
. [ 1-10]
.

[ 1-10]

64

HACK

1. Ajax


Java .
doPost( ) .
protected void doPost(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws
ServletException, IOException {
Map valMap = httpServletRequest.getParameterMap();
StringBuffer body = new StringBuffer("{\n");
if(valMap != null) {
String val=null;
String key = null;
Map.Entry me = null;
Set entries = valMap.entrySet();
int size = entries.size();
int counter=0;
for(Iterator iter= entries.iterator();iter.hasNext();) {
counter++;
me=(Map.Entry) iter.next();
val= ((String[])me.getValue())[0];
key = (String) me.getKey();
if(counter < size) {
body.append(key).append(":\"").append(val).append("\",\n");
} else {
//remove comma for last entry
body.append(key).append(":\"").append(val).append("\"\n");
}
}
}
body.append("}");
AjaxUtil.sendText(httpServletResponse,body.toString());
}

AjaxUtil Content-Type text/plain; charset=UTF-8 HTTP


. JSON Contetn-Type application/x-json
.

65

#7

HACK

#8

Ajax Hacks :

.
AjaxUtil .
.
response.setHeader("Cache-Control", "no-cache");

HACK

#8


Ajax

Ajax .
( ,
, ) ( ).


.
(backend) .
Ajax ,
.

, ...
,
.

, URL

open( )
. .

66

HACK

1. Ajax

.
[Hack #6]
.
hack6.js HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="js/hack6.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Tally your stocks</title>
</head>
<body>
<h3>Your total Stock Holdings</h3>
<form action="javascript:void%200" onsubmit=
"getStockPrice(this.stSymbol.value,this.numShares.value);return
false">
<p>Enter stock symbol: <input type="text" name="stSymbol" size="4">
<span id="stPrice"></span></p>
<p>Enter share amount:<input type="text" name="numShares" size="10">
</p>
<p><button type="submit">Get Total Value</p>
<div id="msgDisplay"></div>
</form>
</body>
</html>

, [ 1-11] .
URL ,
, ,
. handelResponse( ) request.onreadystatechange= handle
Response .
try/catch/finally [Hack #6]
.

67

#8

HACK

#8

Ajax Hacks :

[ 1-11]

function handleResponse(){
var statusMsg="";
try{
if(request.readyState == 4){
if(request.status == 200){
/*
*/
var stockPrice = request.responseText;
try{
if(isNaN(stockPrice)) { throw new Error(
"The returned price is an invalid number.");}
if(isNaN(numberOfShares)) { throw new Error(
"The share amount is an invalid number.");}
var info = "Total stock value: "+
calcTotal(stockPrice);
displayMsg(document.
getElementById("msgDisplay"),info,"black");
document.getElementById("stPrice").style.fontSize="0.
9em";
document.getElementById("stPrice").innerHTML ="price: "+
stockPrice;
} catch (err) {
displayMsg(document.getElementById("msgDisplay"),
"An error occurred: "+
err.message,"red");
}

68

HACK

1. Ajax

} else {
// request.status 503
// 500
alert(
"A problem occurred with communicating between the "
"XMLHttpRequest object and the server program. "+
"Please try again very soon");
}
}// if
} catch (err) {
alert("It does not appear that the server "+
alert("is available for this application. Please "+
alert("try again very soon.\nError: "+err.message);
}
}


try .
catch . try
[Hack #6]
.
. ?
, status
, request.status .
catch . [ 1-12]
.

. .

69

#8

HACK

#8

Ajax Hacks :

[ 1-12] !

err . message
( err.message) .

try/catch/finally ,
.
.

(Backend)
,
(
Unavailable
)
. request.status 503Service

. status 200 else


.
} else {
// 503;
// 500
alert(
"A problem occurred with communicating between the "
"XMLHttpRequest object and the server program. "+
"Please try again very soon");
}

, .

70

HACK

1. Ajax

. 500Inter
(
nal Server Error
) . 404 URL

try/catch/finally 1.4 . catch


finally . finally { ... }
.

URL
Ajax request.open( ) URL
? request.open( ) . try/
catch/finally .
.[Hack #1] initReq( )
.
function httpRequest(reqType,url,asynch){
//
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
//ActiveXObject request null
//
if(request){
initReq(reqType,url,asynch);
} else {
alert("Your browser does not permit the use of all "+
alert("of this application's features!");

71

#8

HACK

#9

Ajax Hacks :

}
}
/* */
function initReq(reqType,url,bool){
try{
/*HTTP */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.send(null);
} catch (err) {
alert(
"The application cannot contact the server at the moment. "+
"Please try again in a few seconds.");
}
}


URL request.open( ) .
http://www.myorg.com/app open ( ) URL http://www.
yourorg.com . try/catch/finally .

catch request.abort( )
. HTTP [Hack #70]
. [Hack #70]
.

HACK

#9

HTTP
HTTP

HTTP HTTP 1.1 (descriptive)

72

HACK

1. Ajax

.
XMLHttpRequest , request.status
HTTP . HTTP
.

200( ), 404( URL ), 500( )


.

(Server ),
(Content-Type ) HTTP .
URL

HTTP . Ajax
.

Content-Type, Date, Server, Content-Length


.

HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="js/hack7.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>view response headers</title>
<link rel="stylesheet" type="text/css" href="/parkerriver/css/ hacks.
css"/>

73

#9

HACK

#9

Ajax Hacks :

</head>
<body onload="document.forms[0].url.value=urlFragment">
<h3>Find out the HTTP response headers when you "GET" a Web page</h3>
<form action="javascript:void%200">
<p>Enter a URL:
<input type="text" name="url" size="20" onblur="getAllHeaders
(this.value)">
<span class="message">::press tab when finished editing the field::
</span></p>
<div id="msgDisplay"></div>
</form>
</body>
</html>

[ 1-13] .

[ 1-13] ]

.
( ) .
URL

text , text

onblur . getAllHeaders( )
URL URL
.
hack7.js .
.
[Hack #1]
[Hack #8] .

74

HACK

1. Ajax

var request;
var urlFragment="http://localhost:8080/";
function getAllHeaders(url){
httpRequest("GET",url,true);
}
//XMLHttpRequest onreadystatechange
function handleResponse(){
try{
if(request.readyState == 4){
if(request.status == 200){
/* */
var headers = request.getAllResponseHeaders();
var div = document.getElementById("msgDisplay");
div.className="header";
div.innerHTML="<pre>"+headers+"</pre>";
} else {
// 503
// 500
alert(request.status);
alert("A problem occurred with communicating between "+
alert("the XMLHttpRequest object and the server program.");
}
}// if
} catch (err)
{
alert("It does not appear that the server is "+
alert("available for this application. Please "+
alert("try again very soon. \nError: "+err.message);
}
}
/* /
function initReq(reqType,url,bool){
try{
/* HTTP */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.send(null);
} catch (errv) {
alert(
75

#9

HACK

#9

Ajax Hacks :

"The application cannot contact the server at the moment."+


"Please try again in a few seconds."
}
}
/*
:
reqType:HTTP . GET POST
url: URL
asynch: , */
function httpRequest(reqType,url,asynch){
//
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
//ActiveXObject request null
//
if(request){
initReq(reqType,url,asynch);
} else {
alert("Your browser does not permit the use of all "+
alert("of this applications features!");
}
}

handleResponse( ) .
getAllResponseHeaders( ) .

, JSON .

request.getResponseHeader( ) . request. get


ResponseHeader(
Contetn-Type
) .

76

HACK

1. Ajax

div .
if(request.status == 200){
/* */
var headers = request.getAllResponseHeaders();
var div = document.getElementById("msgDisplay");
div.className="header";
div.innerHTML="<pre>"+headers+"</pre>";
}...

header
(
) div className
CSS . .
div.header{ border: thin solid black; padding: 10%;
font-size: 0.9em; background-color: yellow}
span.message { font-size: 0.8em; }

CSS div
. .
div innerHTML . pre
.

[ 1-14] URL .

77

#9

HACK

#10

Ajax Hacks :

[ 1-14]

HACK

CSS

#10

.
. HTML select
URL , URL text
.
.[Hack #9]
.
HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="js/hack8.js"></script>
<script type="text/javascript">
function setSpan(){
document.getElementById("instr").onmouseover=function(){
this.style.backgroundColor='yellow';};

78

HACK

1. Ajax

document.getElementById("instr").onmouseout=function(){
this.style.backgroundColor='white';};
}
</script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>view response headers</title>
<link rel="stylesheet" type="text/css" href="/parkerriver/css/hacks.
css"/>
</head>
<body onload="document.forms[0].url.value=urlFragment;setSpan()">
<h3>Find out the HTTP response headers when you "GET" a Web page</h3>
<h4>Choose the style for your message</h4>
<form action="javascript:void%200">
<p>
<select name="_style">
<option label="Loud" value="loud" selected>Loud</option>
<option label="Fancy" value="fancy">Fancy</option>
<option label="Cosmopolitan" value="cosmo">Cosmopolitan
</option>
<option label="Plain" value="plain">Plain</option>
</select>
</p>
<p>Enter a URL: <input type="text" name="url" size="20" onblur=
"getAllHeaders(this.value,this.form._style.value)"> <span
id="instr" class="message">&#171;press tab or click
outside the field when finished editing&#187;</span></p>
<div id="msgDisplay"></div>
</form>
</body>
</html>

setSpan( ) (


) .

79

#10

HACK

#10

Ajax Hacks :

,
[ 1-15] .

[ 1-15]

CSS hack.css . select


text

text

, (id msgDisplay div)


.
hacks.css .
div.header{ border: thin solid black; padding: 10%;
font-size: 0.9em; background-color: yellow; max-width: 80%}
span.message { font-size: 0.8em; }
div { max-width: 80% }
.plain { border: thin solid black; padding: 10%;
font: Arial, serif font-size: 0.9em; background-color: yellow; }
.fancy { border: thin solid black; padding: 5%;
font-family: Herculanum, Verdana, serif;
font-size: 1.2em; text-shadow: 0.2em 0.2em grey; font-style: oblique;
color: rgb(21,49,110); background-color: rgb(234,197,49)}
.loud { border: thin solid black; padding: 5%; font-family:
Impact, serif;
font-size: 1.4em; text-shadow: 0 0 2.0em black; color: black;
background-color: rgb(181,77,79)}
.cosmo { border: thin solid black; padding: 1%;
font-family: Papyrus, serif;

80

HACK

1. Ajax

font-size: 0.9em; text-shadow: 0 0 0.5em black; color: aqua;


background-color: teal}

(plain, fancy, louc, cosmo) . CSS


. ( .fancy), ,
.
.
. .
Ajax
.
.
onblur getAllHeaders( ) . text
select .
onblur="getAllHeaders(this.value,this.form._style.value)"

this.form._style.value select this.value text


.
hack8.js .
.
var request;
var urlFragment="http://localhost:8080/";
var st;
function getAllHeaders(url,styl){
if(url){
st=styl;
httpRequest("GET",url,true);
}
}
//XMLHttpRequest
function handleResponse(){

81

#10

HACK

#10

Ajax Hacks :

try{
if(request.readyState == 4){
if(request.status == 200){
/* */
var headers = request.getAllResponseHeaders();
var div = document.getElementById("msgDisplay");
div.className= st == "" ? "header" : st;
div.innerHTML="<pre>"+headers+"</pre>";
} else {
// 503
// 500
alert(request.status);
alert("A problem occurred with communicating between "+
alert("the XMLHttpRequest object and the server program.");
}
}// if
} catch (err)
{
alert("It does not appear that the server"+
"is available for this application. Please"+
" try again very soon. \nError: "+err.message);
}
}
/* httpRequest() initReq() Hack #1, #2
. . */


getAllHeaders( ) st CSS (plain, fancy, loud, cosmo)
. div className (st) .
.
if(request.status == 200){
/* */
var headers = request.getAllResponseHeaders();
var div = document.getElementById("msgDisplay");
div.className= st == "" ? "header" : st;
div.innerHTML="<pre>"+headers+"</pre>";
}

82

HACK

1. Ajax

CSS ( select
), header

,
.

hacks.css header .
. [ 116] Cosmopolitan .

[ 1-16] Cosmopolitan

[ 1-17] .

83

#10

HACK

#11

Ajax Hacks :

[ 1-17] Plain

HACK

#11

CSS

DOM CSS
.
(iki) .

.

.


.
HTML . .
.
var request;

84

HACK

1. Ajax

var urlFragment="http://localhost:8080/";
var st;
function getAllHeaders(url,styl){
if(url){
st=styl;
httpRequest("GET",url,true);
}
}
/* DOM CSS2Properties
:
stType ('plain', 'fancy', 'loud', 'cosmo')
stylObj div.style HTML .stylObj div.style
HTML .*/
function setStyle(stType,stylObj){
switch(stType){
case 'plain' :
stylObj.maxWidth="80%";
stylObj.border="thin solid black";
stylObj.padding="5%";
stylObj.textShadow="none";
stylObj.fontFamily="Arial, serif";
stylObj.fontSize="0.9em";
stylObj.backgroundColor="yellow"; break;
case 'loud' :
stylObj.maxWidth="80%";
stylObj.border="thin solid black";
stylObj.padding="5%";
stylObj.fontFamily="Impact, serif";
stylObj.fontSize="1.4em";
stylObj.textShadow="0 0 2.0em black";
stylObj.backgroundColor="rgb(181,77,79)"; break;
case 'fancy' :
stylObj.maxWidth="80%";
stylObj.border="thin solid black";
stylObj.padding="5%";
stylObj.fontFamily="Herculanum, Verdana, serif";
stylObj.fontSize="1.2em";
stylObj.fontStyle="oblique";
85

#11

HACK

#11

Ajax Hacks :

stylObj.textShadow="0.2em 0.2em grey";


stylObj.color="rgb(21,49,110)";
stylObj.backgroundColor="rgb(234,197,49)"; break;
case 'cosmo' :
stylObj.maxWidth="80%";
stylObj.border="thin solid black";
stylObj.padding="1%";
stylObj.fontFamily="Papyrus, serif";
stylObj.fontSize="0.9em";
stylObj.textShadow="0 0 0.5em black";
stylObj.color="aqua";
stylObj.backgroundColor="teal"; break;
default :
alert('default');
}
}
//XMLHttpRequest
function handleResponse(){
try{
if(request.readyState == 4){
if(request.status == 200){
/* */
var headers = request.getAllResponseHeaders();
var div = document.getElementById("msgDisplay");
if(st){
setStyle(st,div.style);
} else {
setStyle("plain",div.style);
}
div.innerHTML="<pre>"+headers+"</pre>";
} else {
// 503
// 500
alert(request.status);
alert("A problem occurred with communicating between "+
"the XMLHttpRequest object and the server program.");
}
}// if
} catch (err) {
alert(alert("It does not appear that the server "+
86

HACK

1. Ajax

"is available for this application. Please "+


"try again very soon. \nError: "+err.message);
}
}
/* */
function initReq(reqType,url,bool){
try{
/* HTTP */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.send(null);
} catch (errv) {
alert(
"Your browser does not permit the use of all "+
"of this applications features!");
}
}
/*
:
reqType: HTTP . GET POST
url: URL
asynch: , */
function httpRequest(reqType,url,asynch){
//
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
//ActiveXObject request null
//
if(request){
initReq(reqType,url,asynch);
} else {
alert("Your browser does not permit the use of all "+
87

#11

HACK

#11

Ajax Hacks :

"of this application's features!");


}
}


CSS , HTML style
. div div.style .
div
Arial
). setStyle( )
(:div.style.fornFamily=
.
Fancy div .
div .
( ) .
, URL text

onblur . CSS
. HTMLCSS
[Hack #10] . .
hack10.js
. HTML .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<script type="text/javascript" src="/parkerriver/js/hack10.js">
</script>
<script type="text/javascript">
function setSpan(){
document.getElementById("instr").onmouseover=function(){
this.style.backgroundColor='yellow';};
document.getElementById("instr").onmouseout=function(){
this.style.backgroundColor='white';};
}
</script>

88

HACK

1. Ajax

<meta http-equiv="content-type" content="text/html; charset=utf-8" />


<title>view response headers</title>
</head>
<body onLoad="document.forms[0].url.value=urlFragment;setSpan()">
<h3>Find out the HTTP response headers when you "GET" a Web page</h3>
<h4>Choose the style for your message</h4>
<form action="javascript:void%200">
<p>
<select name="_style">
<option label="Loud" value="loud" selected>Loud</option>
<option label="Fancy" value="fancy">Fancy</option>
<option label="Cosmopolitan" value="cosmo">Cosmopolitan
</option>
<option label="Plain" value="plain">Plain</option>
</select>
</p>
<p>Enter a URL: <input type="text" name="url" size="20" onblur=
"getAllHeaders(this.value,this.form._style.value)">
<span id="instr" class="message">&#171;press tab or
click outside the field when finished editing&#187;
</span></p>
<div id="msgDisplay"></div>
</form>
</body>
</html>

onblur getAllHeader( ) select


(
) URL .
cosmo

. Ajax
.

setSpan( ) (

text
) .

89

#11

HACK

#11

Ajax Hacks :

[ 1-18] HTTP .

[ 1-18]

[ 1-19] URL

[ 1-19]


. ,
. Ajax!

90

Vous aimerez peut-être aussi