AJAX
Asynchronous JavaScript and XML
Honza Vrbata
[email protected]
1
Co to je ????
Technologie interaktivních webových
aplikací, které okamžitě reagují
na uživatelské pokyny a mění obsah
svých stránek bez nutnosti jejich
kompletního znovunačítání !!!
2
Technologie
WWW technologie pro AJAX :
●
●
●
●
HTML (nebo XHTML) a CSS pro prezentaci informací
DOM a JavaScript pro zobrazování a dynamické změny
prezentovaných informací
XMLHttpRequest pro asynchronní výměnu dat s webovým
serverem (typicky je užíván formát XML, ale je
možné použít libovolný jiný formát včetně HTML,
prostého textu, JSON či EBML)
PHP, Ruby on Rails, CGI scripting, ASP, JSP pro generování
dat na straně serveru
3
Jak to funguje ?
UŽIVATEL
PROHLÍŽEČ
SERVER
1.
Uživatel zadá do prohlížeče
požadavek na index.html
2.
Prohlížeč generuje požadavek
na index.html
3.
Server vrací v odpovědi
index.html s JS částí
AJAXu
5.
Uživatel začne provádět
na stránce akce
4.
Prohlížeč nahraje soubor
index.html s JS částmi AJAXu
6.
JS při uživatelské události
provede asynchronní volání
na serverovou aplikaci
9.
Zatímco uživatel pracuje
je stránka automaticky
aktualizována
7.
Server vrací odpověď
na asynchronní volání
ve formátu XML nebo jiném
8.
JS získá odpověď od serveru
a použije data k aktualizaci
informací na obrazovce
4
Klady
●
Umožňuje vytvářet lepší, přístupnější, uživatelsky
příjemnější a více interaktivní webové aplikace.
●
Používá stávající technologie a standardy.
●
Snižuje objem dat putujících po síti.
5
Zápory
●
●
●
●
Nutno používat moderní prohlížeče, které technologie
AJAXu podporují.
Protože se adresy stránek nemění není možné stránky
bookmarkovat.
Stisk tlačítka zpět může způsobit dosti neočekávané
chování !
Vyhledávače nemusí být schopny indexovat všechny
části stránky.
6
Alternativa pomocí IFRAME
<html>
<head>
<title>Vzdálené skriptování pomocí IFRAME</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<script type="text/javascript">
function odpoved() {
alert ("Tato funkce je volána z druhého souboru");
}
</script>
<body>
<h1>Vzdálené skriptování pomocí IFRAME</h1>
<iframe id="prvni" name="prvni" style="width:0px; height:0px;
border:0px" src="blank.html">
</iframe>
<a href="server.html" target="prvni">Zavolej server</a>
</body>
</html>
iframe/prvni.html
7
Alternativa pomocí IFRAME
<html>
<head>
<title>Vzdálené skriptování pomocí IFRAME - server</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<script type="text/javascript">
window.parent.odpoved();
</script>
<body>
</body>
</html>
iframe/server.html
8
První aplikace – HTML stránka
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Naše první AJAX aplikace</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="priklad1.js"></script>
</head>
<body onload="process()">
<h2>Pokusna aplikace demonstrujici AJAX !!!</h2>
Rádi bychom znali tvoje jméno :
<input type="text" id="jmeno" value="pepa"><br>
Tvoje jméno je :
<span id="divZprava"></span><br>
<img src="hippo.jpg">
</body>
</html>
priklad1/index.html
9
První aplikace – PHP skript na serveru
<?
header("Content-Type: text/xml");
echo ('<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>');
echo ("<response>");
$jmeno=$_GET["jmeno"];
echo(htmlentities($jmeno));
echo("</response>");
?>
priklad1/priklad1.php
10
První aplikace – JavaScript 1
var xmlHttp = createXmlHttpRequestObject();
function createXmlHttpRequestObject() {
var xmlHttp;
if (window.ActiveXObject) {
try {
xmlHttp = new ActiveXobject("Microsoft.XMLHTTP");
}
catch (e) {
xmlHttp = false;
}
}
else {
try {
xmlHttp = new XMLHttpRequest();
}
catch (e) {
xmlHttp = false;
}
}
priklad1/priklad1.js
11
První aplikace – JavaScript 2
if (!xmlHttp)
alert ("Nelze vytvorit klientsky objekt pro AJAX !!!!");
else
return (xmlHttp);
}
function process () {
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0) {
jmeno=encodeURIComponent(document.getElementById("jmeno").value);
xmlHttp.open("GET","priklad1.php?jmeno="+jmeno,true);
xmlHttp.onreadystatechange=handleServerResponse;
xmlHttp.send(null);
}
else {
setTimeout("process()",1000);
}
}
12
První aplikace – JavaScript 3
function handleServerResponse()
{
if (xmlHttp.readyState == 4)
{
if (xmlHttp.status == 200)
{
xmlDocumentElement = xmlHttp.responseXML.documentElement;
zprava=xmlDocumentElement.firstChild.data;
document.getElementById("divZprava").innerHTML="<b>"+zprava+"</b>";
setTimeout("process()",1000);
}
else
{
alert("Problem pri kontaktovani serveru : "+xmlHttp.statusText);
}
}
}
13
JavaScript a DOM
JavaScript umožňuje manipulovat s rodičovským
dokumentem. Toto se děje pomocí rozhraní DOM.
JavaScriptu a DOM lze využít k :
●
●
●
Manipulaci s objekty v HTML stránce
Čtení a parsování dokumentů XML získaných
ze serveru
Tvorbě dokumentů XML
14
JavaScript a DOM příklad I.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>JavaScript a DOM</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
var date=new Date();
var hour = date.getHours();
if (hour>=22 || hour<=5)
document.write("Měli byste všichni spát");
else
document.write("Hezký den všem");
</script>
</head>
<body>
Test JavaScriptu a DOM !!!
</body>
</html>
dom1/dom1.html
15
JavaScript a DOM příklad I.
Jak to funguje ?
●
●
JavaScript se spouští automaticky při načtení HTML stránky.
Kód JavaScriptu se provádí před parsováním ostatního kódu
HTML, takže se jeho výstup zobrazí před výstupem HTML
v části BODY !!!!
Nemáme tedy kontrolu nad tím, kde se má zobrazit výstup
kódu JavaScriptu !!!
16
JavaScript a DOM příklad II.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>JavaScript a DOM</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function process() {
var string;
string="<ul><li>Bílá</li><li>Červená</li><li>Zelená</li></ul>";
element=document.getElementById("seznam");
element.innerHTML=string;
}
</script>
</head>
<body onload="process()">
Vyberte si nějakou pěknou barvu z našeho seznamu :<br>
<div id="seznam"></div>
</body>
</html>
dom2/index.html
17
JavaScript a DOM
DOM je hierarchická struktura elementů. Každý může
mít jeden nebo více atributů.
Vyberte si nějakou pěknou barvu z našeho seznamu :
<br>
<body>
<div>
<ul>
<li>
<li>
<li>
Bílá
Červená
Zelená
18
JavaScript a DOM
19
JavaScript a DOM
Atributy a metody objektu document vhodné pro vytváření
dynamického obsahu :
createElement(název)
createTextNode(text)
<element>.appenChild(uzel)
vytvoří specifikovaný element
vytvoří uzel statického textu
přidá daný uzel mezi potomky
elementu
získání, resp. nastavní hodnoty
atributu elementu daného názvem
<element>.getAttribute(název)
<element>.setAttribute(název,h)
.................
<element>.removeAttribute(název)
<element>.removeChild(uzel)
.................
20
JavaScript a DOM příklad III.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function process() {
oHello=document.createTextNode("Textová položka v našem dokumentu");
oUl=document.createElement("ul");
oLiCerna=document.createElement("li");
oCerna=document.createTextNode("Černá");
oLiCerna.appendChild(oCerna);
oUl.appendChild(oLiCerna);
myDiv=document.getElementById("seznam");
myDiv.appendChild(oHello);
myDiv.appendChild(oUl);
}
</script>
</head>
<body onload="process()">
<div id="seznam"></div>
</body>
</html>
dom3/index.html
21
JavaScript a DOM příklad III.
●
●
●
Tvorba dynamických struktur HTML programově (například
pomocí cyklů) je v určitých případech pohodlná a výhodná.
Není například nutné manuálně přidávat uzavírací značky.
DOM se o to postará (viz. minulý příklad se značkou <li>).
S uzly pracujeme zcela nezávisle. O jejich hierarchickém
uspořádání rozhodneme později !!!!
22
JavaScript, DOM a CSS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="skript.js"></script>
<link href="styly.css" type="text/css" rel="stylesheet">
</head>
<body>
<table id="tabulka">
<tr>
<th id="zahlavi">Záhlaví tabulky</th>
</tr>
<tr>
<td id="radek">Řádek tabulky</td>
</tr>
</table>
<br>
<input type="button" value="Styl 1" onclick="setStyle1();">
<input type="button" value="Styl 2" onclick="setStyle2();">
</body>
</html>
dom+css/index.html
23
JavaScript, DOM a CSS
Soubor skript.js :
function setStyle1() {
oTabulka=document.getElementById("tabulka");
oZahlavi=document.getElementById("zahlavi");
oRadek=document.getElementById("radek");
oTabulka.className="Tabulka1";
oZahlavi.className="Zahlavi1";
oRadek.className="Radek1";
}
function setStyle2() {
oTabulka=document.getElementById("tabulka");
oZahlavi=document.getElementById("zahlavi");
oRadek=document.getElementById("radek");
oTabulka.className="Tabulka2";
oZahlavi.className="Zahlavi2";
oRadek.className="Radek2";
}
dom+css/skript.js
24
JavaScript, DOM a CSS
Soubor styly.css :
dom+css/styly.css
.Tabulka1
{
border: DarkGreen 10px solid;
}
.Zahlavi1
{
font-family: Arial;
color: Black;
}
.Radek1
{
font-family: Verdana;
}
.Tabulka2
{
border: DarkBlue 10px solid;
}
.Zahlavi2
{
font-family: Arial;
color: Green;
}
.Radek2
{
font-family: Verdana;
}
25
JavaScript a parsování XML
Atributy DOM elementů vhodné pro parsing XML :
childNodes
firstChild
lastChild
nextSibling
previousSibling
nodeValue
parentNode
innerHTML
pole potomků daného elementu
první přímý potomek elementu
poslední potomek elementu
element následující za daným elementem
element předcházející daný element
atribut pro čtení/zápis reprezentující hodnotu
elementu
rodičovský uzel elementu
veškerý obsah daného elementu
26
JavaScript a parsování XML
Atributy DOM elementů vhodné pro parsing XML příklady:
http://www.tvorba-webu.cz/dom/
27
JavaScript a parsování XML
Metody DOM elementů vhodné pro parsing XML :
getElementById(id)
vrátí element daný hodnotou id
getElementsByTagName(název)vrátí pole elementů specifického
typu
hasChildNodes()
vrací true pokud má element
nějaké potomky
getAttribute(název)
vrátí hodnotu atributu daného
elementu
28
JavaScript a parsování XML
Datový XML soubor :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<knihy>
<kniha>
<titul>Babička</titul>
<autor>Božena Němcová</autor>
</kniha>
<kniha>
<titul>Němý Bobeš</titul>
<autor>Jaroslav Cimrman</autor>
</kniha>
</knihy>
</response>
xml1/knihy.xml
29
JavaScript a parsování XML
Základní HTML stránka :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>JavaScript a XML</title>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
<script type="text/javascript" src="knihy.js"></script>
</head>
<body onLoad="process()">
Seznam knih : <br>
<div id="telo"></div>
</body>
</html>
xml1/index.html
30
JavaScript a parsování XML
Zpracování XML JavaScriptem :
..................
..................
function handleServerResponse () {
var xmlResponse=xmlHttp.responseXML;
xmlRoot=xmlResponse.documentElement;
titulArray=xmlRoot.getElementsByTagName("titul");
autorArray=xmlRoot.getElementsByTagName("autor");
var html="";
for (var i=0 ; i<titulArray.length ; ++i) {
html+=titulArray.item(i).firstChild.data+" - "+
autorArray.item(i).firstChild.data+"<br>";
}
myDiv=document.getElementById("telo");
myDiv.innerHTML="Odpověď ze serveru : <br>"+html;
}
xml1/knihy.js
31
JavaScript a JSON
JSON (JavaScript Object Notation) je odlehčený formát
pro výměnu dat. Je jednoduše čitelný i zapisovatelný
člověkem a snadno analyzovatelný i generovatelný
strojově.
JSON je založen na dvou strukturách :
●
●
Kolekce párů název/hodnota. Ta bývá v rozličných jazycích
realizována jako objekt, záznam (record),
struktura (struct), slovník (dictionary), hash tabulka,
klíčový seznam (keyed list) nebo asociativní pole.
Tříděný seznam hodnot. Ten je ve většině jazyků realizován
jako pole, vektor, seznam (list) nebo posloupnost (sequence).
32
JavaScript a JSON
Objekt je netříděná množina párů název/hodnota.
Objekt je uvozen znakem { (levá složená závorka)
a zakončen znakem } (pravá složená závorka).
Každý název je následován znakem : (dvojtečka) a páry
název/hodnota jsou pak odděleny znakem , (čárka).
33
JavaScript a JSON
Pole je setříděnou kolekcí hodnot. Začíná znakem
[ (levá hranatá závorka) and končí znakem ]
(pravá hranatá závorka). Hodnoty jsou odděleny
znakem , (čárka).
34
JavaScript a JSON
Hodnotou rozumíme řetezec uzavřený do dvojitých
uvozovek, číslo, true, false, null, objekt nebo pole.
Tyto struktury mohou být vnořovány.
35
JSON a XML
JSON :
XML :
{"jmeno":"Pepa",
"prijmeni":"Novák",
"cislo":123456,
"funkce":"ředitel"}
<zamestnanec>
<jmeno>Pepa</jmeno>
<prijmeni>Novák</prijmeni>
<cislo>123456</cislo>
<funkce>ředitel</funkce>
</zamestnanec>
36
JavaScript a události
Přehled některých událostí JavaScriptu vhodných
pro AJAX :
onLoad
body,img
při úplném načtení objektu
onClick
většina elementů
při kliknutí na prvek
onSubmit
form
před odesláním formuláře
onFocus
prvky formuláře
při zaměření políčka formuláře
onBlur
prvky formuláře
při opuštění políčka formuláře
onChange
prvky formuláře
při změně hodnoty políčka
...................................................................
37
Objekt XMLHttpRequest
Posloupnost operací s objektem XMLHttpRequest během
relace AJAXu :
1. Vytvoříme instanci objektu XMLHttpRequest.
2. Objekt použijeme k vytvoření asynchronního volání
stránky na serveru. Definujeme funkci zpětného
volání, která se automaticky provede při přijetí odpovědi
od serveru.
3. Ve funkci zpětného volání zpracujeme odpověď serveru.
4. Vracíme se do bodu 2.
38
Objekt XMLHttpRequest
Základní vlastnosti a metody objektu XMLHttpRequest :
abort()
getAllResponseHeaders()
getResponseHeader("nazev")
open("metoda","URL"[,async])
send(obsah)
setRequestHeader("nazev",
"hodnota")
onReadyStateChange
readyState
responseText
responseXML
Status
statusText
ukončí aktuální požadavek
vrátí hlavičky odpovědi jako řetězec
vrátí jednu hlavičku odpovědi
inicializuje parametry požadavku
provede požadavek http
vloží hlavičku do požadavku
definice funkce zpětného volání
vrátí stav požadavku (0...neinicializovaný,
1...zavádí se, 2...je zaveden, 3...přechodný,
4...kompletní)
vrátí odpověď serveru jako řetězec
vrátí odpověď serveru jako dokument XML
vrátí stavový kód požadavku
vrátí zprávu stavu požadavku
39
Objekt XMLHttpRequest
Volání serverové části AJAXu (předávání parametrů) :
xmlHttp.open("GET","http://www.server.cz/ajax.php?param1=x&param2=y");
xmlHttp.onreadystatechange=handleRequestStateChange;
xmlHttp.send(null);
xmlHttp.open("POST","http://www.server.cz/ajax.php");
xmlHttp.onreadystatechange=handleRequestStateChange;
xmlHttp.send("param1=x&param2=y");
xmlHttp.open("GET","http://www.server.cz/ajax.php");
xmlHttp.onreadystatechange=handleRequestStateChange;
xmlHttp.setRequestHeader("param1","x")
xmlHttp.setRequestHeader("param2","y")
xmlHttp.send(null);
40
Objekt XMLHttpRequest
Zpracování odpovědi serveru :
Metoda handeRequestStateChange je metoda zpětného volání,
ošetřující změnu stavu požadavku. Je obvykle volána několikrát,
vždy, když se požadavek dostane do nového stavu dle vlastnosti
readyState. Většinou nás zajímá pouze stav 4 a HTTP stavový
kód 200 (stránka v pořádku načtena) :
function handleRequestStateChange() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
.....
}
}
41
Odolnost proti chybám souběhu
Možná řešení problému :
●
●
●
●
Pro každou zprávu vytvořit novou instanci XMLHttpRequest
(jednoduše implementovatelné, sníží výkon serveru,
neovlivníme pořadí přijetí).
Uložit zprávu do FIFO fronty a odeslat ji později.
(vytváří se pouze jedna instance AJAX objektu, požadavky
se vytváří v daném pořadí).
Pokud je AJAX objekt aktivní naplánovat automaticky pokus
o vytvoření nového požadavku
(není garantováno pořadí požadavků)
Ignorovat :-)
42
Odolnost proti chybám souběhu
Programové řešení problému :
var cache = new Array();
......
if (xmlHttp) {
cache.push(data);
}
if ((xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
&& cache.length > 0)
{
var cacheEntry = cache.shift();
xmlHttp.open("POST",skript na serveru, true);
xmlHttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(cacheEntry);
}
43
SAJAX - Framework na serveru
<?
require("Sajax.php");
function secti($operand1, $operand2)
{
return $operand1 + $operand2;
}
sajax_init();
sajax_export("secti");
sajax_handle_client_request();
?>
sajax/index.php
44
SAJAX - Framework na serveru
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Použití frameworku Sajax</title>
<script>
<?
sajax_show_javascript();
?>
function zobrazVysledek(vysledek)
{
document.getElementById("vysledek").value = vysledek;
}
function provedSoucet()
{
var operand1, operand2;
operand1 = document.getElementById("operand1").value;
operand2 = document.getElementById("operand2").value;
x_secti(operand1, operand2, zobrazVysledek);
}
</script>
</head>
sajax/index.php
45
SAJAX - Framework na serveru
<body>
<center>
<h1>Použití frameworku Sajax</h1>
<input type="text" name="operand1" id="operand1" value="4" size="3">
+
<input type="text" name="operand2" id="operand2" value="5" size="3">
=
<input type="text" name="vysledek" id="vysledek" value="" size="3">
<input type="button" value="Seč ti"
onclick="provedSoucet(); return false;">
</center>
</body>
</html>
sajax/index.php
46
Praktické aplikace
47
Kontrola vstupů z formuláře
Možná řešení :
●
●
●
Kontrola na straně serveru je vždy funkční. Je nutné formulář
odeslat na server, kde se provede kontrola. V případě
nedostatků obdrží uživatel prázdný formulář, který musí
být vyplněn od začátku.
Kontrola na straně klienta pomocí JavaScriptu, atd. nemusí
být funkční (prohlížeč nepodporuje JS, nebo je JS zakázán).
Není tedy možné se na ni spolehnout ! Je uživatelsky
přívětivá, není nutné odesílat formulář pro kontrolu na
server. Je omezena pouze na data uložená v klientovi, není
možné čerpat údaje pro kontrolu ze serveru, např. z databáze.
Kombinovaná kontrola pomocí AJAXu je uživatelsky přívětivá.
Není nutné odesílat formulář na server. Díky AJAXu může
kontrola běžící na pozadí v klientovi čerpat údaje ze serveru.
48
Kontrola vstupů z formuláře
Ideální řešení :
●
●
1.fáze AJAX : Když libovolné pole formuláře ztratí focus
(událost onblur), bude zavolána kontrolní funkce, která vrátí
výsledek (0...chyba, 1...v pořádku). V případě chyby se na
stránce objeví chybová zpráva s výzvou k opravě.
2. fáze na straně serveru (PHP) : Provedena na serverové
straně po odeslání formuláře. Tato kontrola je vždy nutná !!!
V případě úspěšné kontroly bude aplikace pokračovat,
v případě neúspěchu bude vrácena stránka s formulářem, ve
kterém budou správně zadané údaje již předvyplněny
a chybně zadaná pole budou zvýrazněna.
49
Kontrola vstupů z formuláře
Příklad :
overeni/index.html
overeni/overeni.php
50
Nástroje pro vývojáře
Zajímavá rozšíření pro Firefox :
●
●
●
●
●
●
HTML validator
DOM inspector
JSlint
Web Developer
GreaseMonkey
Venkman
51
52
Download

html