Vous êtes sur la page 1sur 30

Ajax.

Wzorce
i najlepsze rozwizania
Autor: Christian Gross
Tumaczenie: Maciej Jezierski
ISBN: 83-246-0554-1
Tytu oryginau: Ajax Patterns and Best Practices
Format: B5, stron: 392

Ajax to nowoczesna technologia umoliwiajca budowanie witryn internetowych nowej


generacji. Oddzielenie klienta od serwera i zastosowanie usug internetowych pozwala
na tworzenie aplikacji czcych w sobie atrakcyjny i szybki interfejs, znany ze
standardowych programw, z zaletami korzystania ze stron WWW. Dziki temu moemy
obniy koszty produkcji, zapewni byskawiczny dostp do nowych danych i aktualizacji
czy uatwi uywanie aplikacji z dowolnego komputera na wiecie majcego dostp do
sieci WWW. Ponadto Ajax bazuje na standardowych technologiach, zatem mona
stosowa go na wszystkich platformach.
Ksika Ajax. Wzorce i najlepsze rozwizania rozpoczyna si od wprowadzenia do
tego podejcia. Tam te znajdziesz opis zwizanych z nim mechanizmw, takich jak
architektura REST czy obiekty XMLHttpRequest, co pozwoli Ci szybko zrozumie
funkcjonowanie i zalety tej technologii. Jednak gwn cz ksiki stanowi
praktyczne wzorce. Dziki nim dowiesz si, jak usprawni wczytywanie aplikacji
poprzez stopniowe pobieranie kodu HTML, jak przyspieszy dziaanie witryny za
pomoc pamici podrcznej, a take jak dynamicznie modyfikowa zawarto stron.
Nauczysz si te zwiksza komfort pracy uytkownikw poprzez tworzenie wygodnego
i niezawodnego systemu nawigacyjnego oraz sprawne pobieranie danych.
W ksice omwiono:

Wydawnictwo Helion
ul. Kociuszki 1c
44-100 Gliwice
tel. 032 230 98 63
e-mail: helion@helion.pl

Funkcjonowanie technologii Ajax


Architektura REST
Obiekty XMLHttpRequest
Stopniowe wczytywanie stron
Obsuga pamici podrcznej
Przetwarzanie i reprezentacja danych
Obsuga nawigacji
Dynamiczne modyfikowanie stron
Staa komunikacja midzy serwerem a klientem
Stosuj sprawdzone wzorce i najlepsze praktyki budowania witryn internetowych

O autorze ......................................................................................... 9
Wstp ............................................................................................ 11
Rozdzia 1. Wprowadzenie do Ajaksa ................................................................ 15
Obraz znaczy wicej ni tysic sw ............................................................................... 16
Kolejny przykad Ajaksa ................................................................................................. 20
Podstawy architektury Ajaksa ......................................................................................... 22
Dane .......................................................................................................................... 23
Nawigacja .................................................................................................................. 24
Porwnanie Ajaksa do innych typw aplikacji ............................................................... 26
Rozbudowana aplikacja kliencka instalowana lokalnie ................................................ 26
Usugi internetowe z rozbudowan aplikacj klienck ............................................... 28
Zwyka aplikacja sieciowa ........................................................................................ 29
Kilka uwag na koniec ...................................................................................................... 29

Rozdzia 2. Ajax od rodka ............................................................................... 31


Ajax dla niecierpliwych ................................................................................................... 31
REST w teorii ............................................................................................................ 31
Implementowanie danych w REST ........................................................................... 33
Implementowanie aplikacji ajaksowej ...................................................................... 34
czenie Ajaksa i REST ........................................................................................... 35
Konsekwencje Ajaksa i REST .................................................................................. 36
Szczegy XMLHttpRequest ........................................................................................... 37
Korzystanie ze wzorca Fabryka ....................................................................................... 39
Definiowanie Fabryki XMLHttpRequest .................................................................. 40
Uycie wzorca Fabryka w aplikacji ajaksowej ......................................................... 41
Wykonywanie asynchronicznych da .......................................................................... 42
Praktyczne wykorzystanie XMLHttpRequest ................................................................. 46
Implementowanie mechanizmu wywoywania asynchronicznego ........................... 46
Wywoywanie domen innych ni domena serwisu ................................................... 57
Podsumowanie ................................................................................................................. 62

Rozdzia 3. Wzorzec Fragmentacja Zawartoci .................................................. 63


Cel .................................................................................................................................... 63
Przyczyny wykorzystania wzorca ................................................................................... 63
Zastosowanie ................................................................................................................... 64
Powizane wzorce ........................................................................................................... 65
Architektura ..................................................................................................................... 65

Ajax. Wzorce i najlepsze rozwizania


Implementowanie porzdku w aplikacji internetowej .............................................. 66
Okrelanie zawartoci wewntrz jej fragmentu ........................................................ 68
Implementacja ................................................................................................................. 70
Implementacja szkieletu strony HTML ..................................................................... 70
Umieszczanie zawartoci przy uyciu dynamicznego HTML-a ............................. 72
Fragmenty w postaci danych binarnych, URL i obrazkw ....................................... 78
Fragmentacja JavaScriptu ......................................................................................... 82
Najwaniejsze elementy wzorca ...................................................................................... 87

Rozdzia 4. Wzorzec Kontroler Pamici Podrcznej ............................................ 89


Cel .................................................................................................................................... 89
Przyczyny wykorzystania wzorca ................................................................................... 89
Zastosowanie ................................................................................................................... 91
Powizane wzorce ........................................................................................................... 92
Architektura ..................................................................................................................... 92
Dyrektywy pamici podrcznej w HTTP i HTML ................................................... 93
Wykorzystanie pamici podrcznej opartej
na modelu wygasania HTTP to zy pomys .......................................................... 94
Lepsze podejcie: wykorzystanie poprawnoci danych HTTP ................................. 95
Kilka ciekawostek dotyczcych pamici podrcznej po stronie serwera .................. 97
Statyczna kontrola aktualnoci HTTP ....................................................................... 99
Dynamiczna kontrola aktualnoci HTTP ................................................................ 100
Implementacja ............................................................................................................... 102
Implementacja pasywnej pamici podrcznej ......................................................... 102
Implementacja kontroli aktualnoci HTTP po stronie serwera ............................... 112
Najwaniejsze elementy wzorca .................................................................................... 120

Rozdzia 5. Wzorzec Permutacje ..................................................................... 121


Cel .................................................................................................................................. 121
Przyczyny wykorzystania wzorca ................................................................................. 121
Zastosowanie ................................................................................................................. 125
Powizane wzorce ......................................................................................................... 126
Architektura ................................................................................................................... 126
Dlaczego zasb jest oddzielony od reprezentacji? .................................................. 126
Wykorzystywanie cookie i uwierzytelniania HTTP
tylko do autoryzowania dostpu ........................................................................... 129
Korzystanie z cookie ............................................................................................... 132
Przykadowa aplikacja z ksikami ......................................................................... 133
Implementacja ............................................................................................................... 138
Przepisywanie adresw URL .................................................................................. 138
Przykad aplikacji z koszykiem zakupw ............................................................... 146
Najwaniejsze elementy wzorca .................................................................................... 161

Rozdzia 6. Wzorzec Podzielona Nawigacja ..................................................... 163


Cel .................................................................................................................................. 163
Przyczyny wykorzystania wzorca ................................................................................. 163
Zastosowanie ................................................................................................................. 167
Powizane wzorce ......................................................................................................... 169
Architektura ................................................................................................................... 170
Implementacja ............................................................................................................... 172
Implementacja funkcjonalnoci Dziaanie .............................................................. 173
Definicja i implementacja funkcjonalnoci Wsplne Dane .................................... 182
Implementacja funkcjonalnoci Prezentacja ........................................................... 198
Wykorzystanie komponentw HTML .................................................................... 203
Najwaniejsze elementy wzorca .................................................................................... 204

Spis treci

Rozdzia 7. Wzorzec Przemienianie Reprezentacji ............................................ 209


Cel .................................................................................................................................. 209
Przyczyny wykorzystania wzorca ................................................................................. 209
Zastosowanie ................................................................................................................. 214
Powizane wzorce ......................................................................................................... 215
Architektura ................................................................................................................... 215
Podstawy teorii wzorca ........................................................................................... 216
Dlaczego wzorzec nie jest komponentem HTML? ................................................. 217
Okrelenie bloku stanu ............................................................................................ 219
Implementacja ............................................................................................................... 223
Implementacja szkieletu .......................................................................................... 223
Implementacja punktw odniesienia reprezentacji ................................................. 225
Szczegy implementacji ......................................................................................... 233
Najwaniejsze elementy wzorca .................................................................................... 235

Rozdzia 8. Wzorzec Trwaa Komunikacja ........................................................ 237


Cel .................................................................................................................................. 237
Przyczyny wykorzystania wzorca ................................................................................. 237
Zastosowanie ................................................................................................................. 239
Powizane wzorce ......................................................................................................... 240
Architektura ................................................................................................................... 240
Dlaczego internet jest uszkodzony? ..................................................................... 241
Implementacja rozwizania odpytujcego serwer ................................................... 244
Implementacja ............................................................................................................... 246
Przykad: oglny zasb statusu ............................................................................... 246
Przykad: wykrywanie obecnoci ............................................................................ 260
Przykad: wypychanie danych przez serwer ........................................................... 265
Numery wersji i aktualizacje ................................................................................... 274
Problemy wydajnociowe ....................................................................................... 274
Najwaniejsze elementy wzorca .................................................................................... 274

Rozdzia 9. Wzorzec Stan Nawigacji ............................................................... 277


Cel .................................................................................................................................. 277
Przyczyny wykorzystania wzorca ................................................................................. 277
Zastosowanie ................................................................................................................. 279
Powizane wzorce ......................................................................................................... 280
Architektura ................................................................................................................... 280
Rozwizania bliskie idealnemu z punktu widzenia uytkownika ........................... 280
Rozszerzenie rozwizania dla celw aplikacji internetowej ................................... 283
Zarzdzanie stanem na poziomie protokou ............................................................ 288
Implementacja ............................................................................................................... 291
Przetwarzanie stanu po stronie klienta .................................................................... 292
Przetwarzanie da po stronie serwera .................................................................. 302
Najwaniejsze elementy wzorca .................................................................................... 311

Rozdzia 10. Wzorzec Nieskoczone Dane ......................................................... 313


Cel .................................................................................................................................. 313
Przyczyny wykorzystania wzorca ................................................................................. 313
Zastosowanie ................................................................................................................. 314
Powizane wzorce ......................................................................................................... 315
Architektura ................................................................................................................... 315
Implementacja ............................................................................................................... 319
Implementacja klienta HTML ................................................................................. 320
Implementacja zarzdzania zadaniami .................................................................... 327
Najwaniejsze elementy wzorca .................................................................................... 343

Ajax. Wzorce i najlepsze rozwizania

Rozdzia 11. Wzorzec Model Widok Kontroler oparty na REST ........................... 345
Cel .................................................................................................................................. 345
Przyczyny wykorzystania wzorca ................................................................................. 345
Zastosowanie ................................................................................................................. 347
Powizane wzorce ......................................................................................................... 347
Architektura ................................................................................................................... 348
Oglny obraz ........................................................................................................... 348
Definiowanie odpowiedniego zasobu ..................................................................... 350
Definicja interfejsu wywoujcego .......................................................................... 353
Definicja podstawowego i rozszerzonego formatu danych ..................................... 356
Implementacja ............................................................................................................... 359
Implementacja wyszukiwania ................................................................................. 359
Tworzenie infrastruktury klienta wyszukiwarki ..................................................... 363
Poczenie wszystkiego ze sob .............................................................................. 369
Najwaniejsze elementy wzorca .................................................................................... 380

Skorowidz .................................................................................... 383

Rozdzia 3.

Cel
Wzorzec Fragmentacja Zawartoci umoliwia stopniowe budowanie strony HTML.
Dziki temu logika pojedynczej strony HTML moe by rozproszona, a uytkownik
moe decydowa o czasie i fragmencie logiki, ktry ma by pobrany.

Przyczyny wykorzystania wzorca


W czasie, kiedy strony internetowe dopiero zaczynay powstawa, projektanci zawartoci
HTML tworzyli dokumenty, ktre byy niekompletne. Niekompletne strony byy uzupeniane za pomoc czy do innych dokumentw. Cay dokument by sum stron w drzewie
dokumentw.
Pomyl o tym nastpujco: zamiast tworzy ksik, ktrej zawarto czytasz strona
po stronie, w przypadku witryny internetowej zebraby materiay razem jak artykuy
w gazecie. Ale w przeciwiestwie do gazety, ktra wymaga przewracania stron, witryna
internetowa umoliwia kliknicie i przeskoczenie do innej zawartoci. W miar upywu
czasu witryny internetowe odchodziy od struktury rozproszonej do cile samodzielnej
struktury hierarchicznej.
Przykad strony o cile samodzielnej strukturze hierarchicznej zosta pokazany na rysunku 3.1.

64

Ajax. Wzorce i najlepsze rozwizania

Rysunek 3.1. cisa struktura hierarchiczna witryny internetowej

Na rysunku 3.1 strona internetowa zostaa podzielona na dwie czci nawigacyjn


z niebieskim tem i zawarto z brzowym tem. Kiedy uytkownik kliknie cze nawigacyjne, zmienia si zawarto. Problem ley w tym, e przeadowywana jest caa
strona, nawet jeli uytkownik jest zainteresowany tylko zawartoci z brzowym tem.
Jednym ze sposobw na obejcie tego problemu byoby uycie ramek HTML, tak eby cz nawigacyjna znajdowaa si w jednej ramce, a zawarto w drugiej. Po klikniciu cza nawigacyjnego zmieniaaby si tylko ramka z zawartoci. Jednak, jak
pokaza czas, mimo e ramki rozwizuj problem osobnego pobierania zawartoci, s
problematyczne z perspektywy nawigacji i interfejsu uytkownika. Dlatego te w witrynach internetowych ramki s uywane w coraz mniejszym stopniu.
Dla twrcy witryny internetowej najlepszym rozwizaniem byaby moliwo zmieniania tylko tej czci zawartoci, ktra powinna zosta zmieniona, i pozostawienia
reszty bez zmian. W kocu zawarto, ktrej nie musimy zmienia, dziaa.

Zastosowanie
Uywaj wzorca Fragmentacja Zawartoci w nastpujcych sytuacjach:
t Rodzaj witryny powoduje, e nie wiadomo, jak powinna wyglda strona

HTML. Na rysunku 3.1 znajduje si cz nawigacyjna z niebieskim tem


i cz z zawartoci na brzowym tle. Nie jest znana zawarto adnej
z czci, ale wiadomo, gdzie znajduje si cz z zawartoci.

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

65

t Zawarto do pobrania jest zbyt dua i mogaby spowodowa, e uytkownik

dugo czekaby na jej wywietlenie. Na przykad wyszukiwanie i oczekiwanie


na zebranie wszystkich wynikw nie jest dobrym wyjciem, poniewa
uytkownik mgby zbyt dugo czeka. Lepszym podejciem byoby
wykonywanie wyszukiwania i wywietlanie wynikw w miar ich
znajdowania.
t Wywietlana zawarto nie jest powizana. Yahoo!, MSN i Excite s

aplikacjami portalowymi wywietlajcymi jedn zawarto obok innej,


zupenie z ni niezwizanej. Jeli zawarto miaaby by generowana
z pojedynczej strony HTML, logika po stronie serwera musiaaby zawiera
olbrzymi blok decyzyjny, eby wiedzie, ktra zawarto zostaa pobrana,
a ktra nie. Lepszym podejciem jest uznanie kadego bloku za odrbn
cz, ktra jest oddzielnie pobierana.

Powizane wzorce
Fragmentacja Zawartoci jest podstawowym wzorcem kadej aplikacji ajaksowej, Moesz nawet zaoy, e zastosowanie tego wzorca wynika wprost z zastosowania Ajaksa.
Tak czy inaczej, wci trzeba zidentyfikowa i okreli kontekst wzorca Fragmentacja
Zawartoci. Jego unikaln cech jest to, e korzystanie z niego polega na wykonywaniu zawsze tych samych krokw, do ktrych nale: wygenerowanie zdarzenia, danie,
odpowied i wstawienie czci zawartoci. Inne wzorce omwione w tej ksice s
podobne, maj jednak rne odchylenia, takie jak wykonanie dania i niepobieranie
zawartoci od razu (na przykad wzorzec Trwaa Komunikacja).

Architektura
Architektura wzorca Fragmentacja Zawartoci jest stosunkowo prosta. Klient wywouje URL. Serwer wysya odpowied z jak zawartoci, ktra jest nastpnie odbierana
i przetwarzana przez klienta. Implementacja wzorca Fragmentacja Zawartoci zawsze
wykonuje nastpujce kroki:
1. Generowane jest zdarzenie, ktre moe by wynikiem nacinicia

przycisku albo pobrania strony HTML.


2. Zdarzenie wywouje funkcj, ktra jest odpowiedzialna za stworzenie

adresu URL uywanego do wysania dania do klienta.


3. Serwer odbiera danie i na jego podstawie tworzy jak zawarto.

Zawarto jest wysyana jako odpowied do klienta.


4. Klient otrzymuje odpowied i umieszcza j w odpowiednim miejscu

strony HTML.

66

Ajax. Wzorce i najlepsze rozwizania

Implementowanie porzdku w aplikacji internetowej


Po ponownym spojrzeniu na rysunek 3.1 mona stwierdzi, e cile hierarchiczna
struktura strony internetowej nie jest z rzecz. Uycie HTML powoduje, e w wyniku
zastosowania takiej struktury trzeba generowa zawarto w jednym kroku. Wanie
to caociowe tworzenie zawartoci powoduje problemy. Tradycyjne aplikacje nie dziaaj
w ten sposb, co wida na rysunku 3.2.
Rysunek 3.2.
Tradycyjna aplikacja
kliencka

Na rysunku 3.2 znajduje si RealPlayer, ktry jest przykadem tradycyjnej aplikacji


klienckiej mieszajcej nowsze technologie oparte na HTML z tradycyjnymi elementami
interfejsu uytkownika. Kliknicie przycisku Burn Your CD spowoduje, e RealPlayer
nagra Twoj pyt CD, ale nie spowoduje zmian w reklamie znajdujcej si na grnej
poowie aplikacji. Logika zwizana z reklam i ta zwizana z nagrywaniem pyt to dwa
oddzielne fragmenty logiki, ktre akurat s wykorzystywane w tym samym oknie.
Na rysunku 3.3 z aplikacji internetowej z rysunku 3.1 wydzielono odrbne fragmenty
logiki.
Oryginalna strona HTML na rysunku 3.3 zawiera cza do dwch innych stron, ktre
reprezentuj przykadowy blog i zawarto artykuu. Przykadowa zawarto ma dwa
bloki wykonawcze Pobierz Nawigacj i Pobierz Zawarto (1,2). Logika uyta do
wygenerowania Pobierz Zawarto 1 jest inna ni ta uyta do wygenerowania Pobierz
Zawarto 2. W kontekcie generowania strony HTML, kiedy wykonywana jest logika Pobierz Zawarto 1 czy Pobierz Zawarto 2, wykonywana jest take logika Pobierz
Nawigacj. Oznacza to, e logika Pobierz Zawarto jest wykonywana wielokrotnie
w celu wygenerowania tej samej zawartoci. Niektrzy czytelnicy mog si kci, e
Pobierz Nawigacj generuje rne dane (na przykad rne foldery s otwarte), ale
w rzeczywistoci s to te same dane tylko inaczej sformatowane. Krtko mwic,
wystpuje tu nadmiarowe generowanie danych, ktre powinno by unikane.

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

67

Rysunek 3.3. Architektura witryny internetowej

Rozwizaniem jest rozproszenie logiki, dziki czemu strona HTML bdzie generowana
przy uyciu architektury podobnej do przedstawionej na rysunku 3.4.

Rysunek 3.4. Ulepszona architektura strony internetowej

68

Ajax. Wzorce i najlepsze rozwizania

Strona na rysunku 3.4 jest zoeniem wielu fragmentw logiki umieszczonej po stronie
serwera. Po pobraniu szkieletu strony HTML obiekt XMLHttpRequest pobiera zawarto
blokw Pobierz Nawigacj, Pobierz Zawarto 1 i Pobierz Zawarto 2. To, kiedy i jak
pobierane s poszczeglne bloki zawartoci, zaley od tworzonych przez nie zdarze
i czy. Kady blok zawartoci jest oddzielnym daniem, ktre musi zosta wywoane
przez typ XMLHttpRequest.
Proponowana architektura ma nastpujce zalety:
t Klient pobiera tylko to, co konieczne, i tylko wtedy, kiedy to konieczne.

Nie ma potrzeby ponownego pobierania bloku zawartoci, chyba e jest


to niezbdne.
t Architektura jest rozdzielona na rne bloki kodu, ktre mog by

dynamicznie czone w rnych kontekstach.


t Architektura podobna do tej w przypadku tradycyjnej aplikacji klienckiej

w tym, e modyfikuje si tylko te elementy, ktrych dotycz zdarzenia.


t Caociowy wygld aplikacji nie zmienia si, poniewa wygenerowane

bloki kodu skadaj si na wygld strony HTML, ktra je pobiera.


Na rysunku 3.4 wida, skd wzi swoj nazw wzorzec Fragmentacja Zawartoci:
zawarto pojedynczej strony jest sum fragmentw, na ktre zostaa ona podzielona.
Kady z tych blokw jest obsugiwany i pobierany osobno.

Okrelanie zawartoci wewntrz jej fragmentu


Fragmenty zawartoci, do ktrych odwouje si obiekt XMLHttpRequest, mog mie
dowolny format zrozumiay zarwno dla serwera, jak i klienta. Cokolwiek wyle serwer,
musi by to zrozumiae dla klienta. Na rysunku 3.4 fragmenty zawartoci bd w HTML,
poniewa zostan umieszczone bezporednio w stronie HTML. Jednak HTML nie jest
jedynym formatem, ktry moe by wysany przez serwer.
W tym rozdziale omwione bd nastpujce formaty:
t HTML. Serwer moe wysa HTML bezporednio do klienta. Otrzymany

HTML nie jest przetwarzany, lecz bezporednio umieszczany w stronie HTML.


Jest to podejcie lepego przetwarzania, poniewa klient nie wie, co wykonuje
pobrany kod HTML. Bezporednie umieszczanie kodu HTML jest bardzo
prostym i idiotoodpornym sposobem budowania zawartoci. Klient nie musi
niczego przetwarza, wystarczy tylko, e zna miejsce, w ktrym ma zosta
umieszczony kod HTML. Jeli przetwarzanie bdzie konieczne, pobrana
zawarto (o ile jest zgodna z XML-em) bdzie rwnie dostpna w postaci
instancji modelu obiektowego. Instancja modelu obiektowego pozwala na
rczne zmienianie zawartoci HTML. Zaleca si, eby HTML wysyany
do klienta by zgodny z XHTML-em (HTML-em, ktry jest implementacj
odpowiedniego schematu XML) albo przynajmniej z XML-em.
t Obrazki. Nie ma moliwoci bezporedniego wysyania obrazkw,
poniewa maj one posta binarn, a obiekt XMLHttpRequest nie moe

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

przetwarza takich danych. Zazwyczaj odnoniki do obrazkw s wysyane


w postaci znacznikw HTML. Te s nastpnie umieszczane w dokumencie
HTML, co powoduje pobranie zdalnych obrazkw. Mona pobiera binarne
dane i korzysta z tych, ktre zostay zakodowane, przesane, a nastpnie
zdekodowane przy uyciu kodowania Base64. Jednake operacje na danych
binarnych nie s zalecane, poniewa powoduj wicej problemw ni korzyci.
t JavaScript. Serwer moe wysa do klienta JavaScript, ktry moe by
wykonany za pomoc instrukcji eval, a klient moe wysya istniejce

obiekty JavaScriptu do serwera w celu dalszego przetwarzania. Na pierwszy


rzut oka moe wydawa si, e wykonywanie pobranych JavaScriptw jest
potencjalnie niebezpieczne. Zazwyczaj jednak nie jest to problemem, poniewa
implementacje JavaScriptu we wszystkich przegldarkach uywaj polityki
tego samego rda i piaskownicy. Wysyanie zewntrznego JavaScriptu
do wykonania moe by problemem bezpieczestwa, jeli w implementacji
jzyka JavaScript znajduje si bd. Wysyanie JavaScriptu jest podane,
jeli chcesz dynamicznie wykonywa i dodawa logik, ktra nie zostaa
pobrana wraz z pocztkow stron HTML. Ta metoda daje bardzo due
moliwoci rozbudowy funkcjonalnoci klienta, ktry nie musi nawet o tym
wiedzie. Na przykad element formularza HTML wymaga sprawdzenia
poprawnoci. Poniewa dla rnych uytkownikw inaczej sprawdzana jest
poprawno, wysyanie wszystkich implementacji sprawdzania poprawnoci
byoby niepodane. Rozwizaniem mogoby by umoliwienie okrelenia,
ktre elementy formularza bd prezentowane, i nastpnie dynamiczne
adowanie odpowiedniej implementacji sprawdzania poprawnoci jako
fragmentu zawartoci. Pamitaj jednak o tym, e przesyanie fragmentw
JavaScriptu moe narazi Twoj aplikacj na atak hakerw. Dlatego
te dobrze przemyl uycie tej techniki.
t XML. Preferowanym podejciem jest wysyanie i odbieranie danych w postaci

XML. XML moe by przetworzony albo sparsowany po stronie klienta za


pomoc obiektowego modelu XML lub poprzez uycie biblioteki XSLT
(ang. Extensible Stylesheet Language Transformations transformacje
rozszerzalnego jzyka arkuszy stylw), ktra moe przeksztaci go na inny
model obiektowy, taki jak HTML. XML jest preferowany, poniewa stanowi
dobrze poznan technologi, a narzdzia do wykonywania na nim operacji
s sprawdzone, dziaajce i stabilne. XML jest technologi o uznanej pozycji,
dziki czemu stworzone w niej dokumenty moesz przeszukiwa, rozdziela
i tworzy, a take sprawdza ich poprawno bez potrzeby pisania dodatkowego
kodu. Niektrzy uwaaj, e XML ma due rozmiary z powodu duej liczby
nawiasw ostrych i innych znacznikw XML. Jednak zalet tego jest to, e
XML wygenerowany przez aplikacj po stronie serwera moe by przetworzony
zarwno przez klienta opartego na przegldarce internetowej, jak i klienta
bez graficznego interfejsu uytkownika. Wybr sposobu parsowania XML-a
i informacji, ktre naley przetwarza, w caoci zaley od klienta, o ile potrafi
on parsowa XML. XML jest elastyczny i powinno si z niego korzysta.
Bdzie on bardzo czsto wykorzystywany w tej ksice i traktowany jako
podstawowy format wymiany danych.

69

70

Ajax. Wzorce i najlepsze rozwizania

S inne metody wymiany danych, takie jak JSON (ang. JavaScript Object Notation
zapis obiektw JavaScript)1. Jednake radz dobrze przemyle konsekwencje wynikajce z wyboru innych formatw. Nie chodzi o to, e uwaam je za le zaprojektowane
czy nieodpowiednie. Tym, co mnie do nich nie przekonuje, jest to, e nie udostpniaj
one tak rozbudowanego rodowiska do przetwarzania, wyszukiwania, sprawdzania
poprawnoci i tworzenia jak XML. Na przykad przy uyciu XPath mog wyszuka
konkretne elementy w XML-u bez parsowania caego dokumentu XML. Oczywicie,
w niektrych przypadkach XML moe nie zapewnia takiej wydajnoci jak na przykad
JSON. Dla czytelnikw, ktrzy s pewni, e nigdy nie bd potrzebowali rozbudowanych funkcji XML-a, JSON moe by odpowiedni. W tej ksice nie bd jednak
omawia innych technologii takich jak JSON.
Teraz, kiedy ju poznae architektur, moemy przej do przedstawienia implementacji demonstrujcych sposb jej realizacji.

Implementacja
Podczas implementacji wzorca Fragmentacja Zawartoci naley postpowa wedug
wczeniej wymienionych krokw (zdarzenie, danie, odpowied, umieszczenie). Logik
mona atwo zaimplementowa, uywajc obiektu Asynchronous, poniewa istnieje
moliwo wywoania go przez zdarzenie i zawiera on bezporedni implementacj
metody do pobierania odpowiedzi z serwera. Poniej przedstawi przykadow implementacj, ktra zilustruje, jak generowa zdarzenia w HTML-u, wywoywa funkcje,
tworzy dania za pomoc XMLHttpRequest oraz przetwarza odpowiedzi, uywajc
dynamicznego HTML-a i JavaScriptu.

Implementacja szkieletu strony HTML


Implementacja wzorca Fragmentacja Zawartoci wymaga stworzenia strony HTML
sucej jako szkielet. Zastosowanie szkieletu pozwoli udostpni struktur, w ktrej
umieszczane bd fragmenty zawartoci. Strona zawierajca szkielet jest kontrolerem
i ma minimaln zawarto.
Poniszy kod HTML jest przykadem szkieletowej strony HTML, w ktrej bd dynamicznie umieszczane fragmenty zawartoci:
<html>
<head>
<title>Fragment dokumentu HTML</title>
<script language="JavaScript" src="/lib/factory.js"></script>
<script language="JavaScript" src="/lib/asynchronous.js"></script>
<script language="JavaScript" type="text/javascript">
var asynchronous = new Asynchronous();
asynchronous.complete = function(status, statusText, responseText, responseXML) {
document.getElementById("insertplace").innerHTML = responseText;
1

http://www.crockford.com/JSON/index.html

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

71

}
</script>
</head>
<body onload="asynchronous.call('/chap03/chunkhtml01.html')">
<table>
<tr><td id="insertplace">Brak zawartoci</td></tr>
</table>
</body>
</html>

W powyszym kodzie HTML tworzona jest instancja klasy Asynchronous i przypisywana funkcja zwrotna do waciwoci asynchronous.complete. Sposb dziaania klasy
Asynchronous oraz waciwoci, do ktrych naley przypisa odpowiednie wartoci,
zostay opisane w rozdziale 2. Instancja asynchronous jest tworzona po wczytaniu strony
HTML. Po wczytaniu caej strony wykonywane jest zdarzenie onload. Jest to pierwszy krok implementacji wzorca: wygenerowanie zdarzenia. Zdarzenie onload wywouje
metod asynchronous.call, ktra wykonuje danie XMLHttpRequest w celu pobrania
fragmentu HTML. Jest to drugi krok implementacji wzorca: wykonanie dania.
Po zakoczeniu dania serwer generuje odpowied, ktra jest odbierana po stronie
klienta poprzez wywoanie metody asynchronous.complete. Pobranie odpowiedzi jest
kolejnym krokiem implementacji wzorca. W tym przykadzie do waciwoci asynchronous.complete jest przypisana anonimowa funkcja JavaScriptu. eby umieci wyniki
dania XMLHttpRequest w elemencie HTML, w jej implementacji wywoywana jest
metoda getElementById. Element HTML, w tym przypadku znacznik HTML td, jest odnajdywany poprzez identyfikator insertplace. Umieszczenie wynikw w kodzie HTML
polegajce na odwoaniu si do elementu HTML i przypisaniu do jego wasnoci innerHTML wynikw dania jest ostatnim krokiem implementacji wzorca.
Niespotykan dotd rzecz jest w tym przykadzie to, e po wczytaniu i przetworzeniu
strony HTML na stronie, ktra jest uwaana za kompletn, wywoywany jest inny
fragment logiki. Uywa si go do pobrania reszty zawartoci w postaci fragmentu zawartoci. Kod po stronie serwera mgby przecie wygenerowa ca stron. Jednak w ten
sposb mona pokaza, jak prosta moe by implementacja wzorca Fragmentacja
Zawartoci. Przykad ilustruje reakcj na zdarzenie onload, ale mona uy dowolnego
zdarzenia. Przykady w rozdziale 2. uyway zdarzenia wywoywanego naciniciem
przycisku. Skrypt mgby nawet emulowa zdarzenia poprzez uycie metody Click().
Powyszy przykad ilustruje oddzielenie wygldu strony HTML od jej logiki. W czci
strony, w ktrej umieszczana jest zawarto, projektant HTML musiaby tylko zamarkowa miejsce, na przykad wpisujc w nie jaki tekst. Programista aplikacji po stronie
serwera tworzyby zawarto, ktra nastpnie zastpowaaby tekst w zamarkowanym
miejscu. Projektant HTML nie musi przejmowa si jakkolwiek technologi programowania po stronie serwera, poniewa szkielet strony HTML zawiera tylko instrukcje
wykonywane po stronie klienta. Programista aplikacji po stronie serwera nie musi
przejmowa si wygldem strony HTML, poniewa tworzona przez niego zawarto
nie zawiera adnych informacji, ktre dotycz wygldu. W czasie testw programista
aplikacji internetowej skupia si na logice, podczas gdy projektant HTML skupia si na jej
wygldzie i zachowaniu.

72

Ajax. Wzorce i najlepsze rozwizania

Umieszczanie zawartoci
przy uyciu dynamicznego HTML-a
Magia tego przykadu tkwi w zdolnoci dynamicznego HTML-a do dynamicznego
umieszczania zawartoci w okrelonym miejscu. Zanim pojawi si dynamiczny HTML,
do poczenia wielu strumieni danych trzeba byo uywa ramek albo logiki po stronie serwera. Kilka lat temu dynamiczny HTML zosta formalnie ustandaryzowany przez
World Wide Web Consortium (W3C) jako HTML DOM (ang. HTML Document Object
Model obiektowy model dokumentu HTML). DOM okrelony przez W3C nie jest
tak rozbudowany jak modele obiektowe dostpne w Internet Explorerze Microsoftu czy
przegldarkach wywodzcych si z Mozilli. Model obiektowy uywany w tej ksice
jest mieszanin HTML DOM i funkcji dostpnych w wikszoci przegldarek (na
przykad w Internet Explorerze oraz w wywodzcych si z Mozilli).
W poprzednim przykadzie atrybut id unikalnie identyfikuje element na stronie HTML.
Dziki unikalnie identyfikowanemu elementowi mona okreli miejsce pocztkowe,
od ktrego moliwa jest nawigacja i manipulowanie obiektowym modelem HTML.
Innym sposobem na znalezienie miejsca pocztkowego jest bezporednie okrelenie
typu znacznika i na jego podstawie znalezienie odpowiedniego elementu HTML. Bez
wzgldu na to, ktre podejcie zastosujesz, jedno z nich musi zosta uyte do pobrania
miejsca pocztkowego. Niektrzy czytelnicy mog mwi, e mgby uy innych
waciwoci czy metod, ale nie s one kompatybilne z HTML DOM i dlatego powinno
si ich unika.
Nastpujcy kod HTML demonstruje, jak znale punkt pocztkowy przy uyciu
dwch podej:
<html>
<head>
<title>Fragment dokumentu HTML</title>
<script language="JavaScript" src="/lib/factory.js"></script>
<script language="JavaScript" src="/lib/asynchronous.js"></script>
<script language="JavaScript" type="text/javascript">
var asynchronous = new Asynchronous();
asynchronous.complete = function(status, statusText,
responseText, responseXML) {
document.getElementsByTagName("table")[ 0].rows[ 0].cells[ 0].innerHTML
= responseText;
document.getElementById("insertplace").innerHTML = responseText;
}
</script>
</head>
<body onload="asynchronous.call('/chap03/chunkhtml01.html')">
<table>
<tr><td>Brak zawartoci</td></tr>
<tr><td id="insertplace">Brak zawartoci</td></tr>
</table>
</body>
</html>

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

73

W implementacji anonimowej funkcji dla metody asynchronous.complete do umieszczenia zawartoci w elemencie dynamicznego HTML-a wykorzystane s dwie metody
(getElementsByTagName, getElementById). Obydwie pobieraj element reprezentujcy
(elementy reprezentujce) punkt pocztkowy.
Metoda getElementsByTagName pobiera wszystkie elementy HTML o typie okrelonym
przez przekazany parametr. W tym przykadzie parametrem jest table. Wskazuje on,
e z dokumentu maj zosta pobrane wszystkie elementy typu table. Zwracana jest
instancja kolekcji HTMLCollection zawierajca w tym przykadzie wszystkie elementy
typu table. Klasa HTMLCollection ma waciwo length, ktra okrela, ile elementw
zostao znalezionych. Do znalezionych elementw mona si odwoywa za pomoc
zapisu sucego do odwoywania si do elementw tablicy w JavaScripcie (nawiasy
kwadratowe), przy czym indeksem pierwszego elementu jest 0.
W tym przykadzie zaraz po identyfikatorze metody getElementsByTagName("table")
znajduje si kilka nawiasw kwadratowych ([[0) sucych do pobrania pierwszego
elementu kolekcji. Indeks zerowy jest tu uyty odgrnie i oznacza odniesienie do
pierwszej znalezionej tabeli. Indeks uyty w tym przykadzie jest prawidowy tylko
dlatego, e na stronie HTML znajduje si jedna tabela. Z tego powodu indeks zerowy
w tym przykadzie zawsze bdzie prawidowy, co oznacza, e bdzie odwoywa si
do odpowiedniej tabeli, wiersza i komrki. Wyobra sobie jednak sytuacj, w ktrej
na stronie znajduje si wiele tabel. W takim przypadku uywanie z gry okrelonego
indeksu moe, ale nie musi si wiza z odwoaniem do odpowiedniej tabeli. Co gorsza,
jeli wzorzec Fragmentacja Zawartoci by wielokrotnie wywoywany, kolejno znalezionych elementw moe ulec zmianie, co spowoduje, e wystpi odwoania do niewaciwych elementw.
Metody getElementsByTagName najlepiej uywa tylko w przypadku, gdy operacje s
wykonywane na wszystkich znalezionych elementach i nie ma potrzeby ich rozrniania.
Do przykadw takich operacji mona zaliczy dodawanie kolumny w tabeli czy zmian
stylu. Do operacji na pojedynczych elementach najlepiej uy metody getElementById.
Za pomoc metody getElementsByTagName mona pobra wszystkie elementy w dokumencie HTML. Ilustruje to poniszy przykad:
var collection = document.getElementsByTagName("*");

Wywoanie metody getElementsByTagName z gwiazdk jako parametrem powoduje


pobranie wszystkich elementw dokumentu HTML. Niektrzy mog zauway, e
mona to samo osign, odczytujc waciwo document.all. Chocia jest to prawda,
waciwo ta nie jest zgodna z DOM i spowoduje wywietlenie ostrzee w przegldarkach opartych na Mozilli.
Przyjrzyjmy si nastpujcemu fragmentowi przykadowego kodu:
document.getElementsByTagName("table")[0].rows[0].cells[0].innerHTML

Identyfikatory po nawiasach kwadratowych metody getElementsByTagName reprezentuj


wywoywane waciwoci i metody. Odnosz si one bezporednio do pobranego obiektu,
ktry w tym przypadku jest tabel zawierajc wiersze i komrki. Jeli pobrany element
nie byby tabel, wywoanie tych waciwoci i metod spowodowaoby powstanie bdu.

74

Ajax. Wzorce i najlepsze rozwizania

Powrmy do przykadowego kodu rdowego i przyjrzyjmy si temu fragmentowi:


document.getElementById("insertplace").innerHTML = responseText;

Metoda getElementById pobiera element HTML z podanym atrybutem id. W atrybucie id


wana jest wielko liter. Wynikiem wywoania tej metody jest pobranie znacznika td
z atrybutem id o wartoci insertplace. Jeli w dokumencie znajdowaoby si wiele
elementw z takim samym atrybutem id, wywoanie metody getElementById spowodowaoby pobranie tylko pierwszego znalezionego elementu. Pozostae elementy nie
s zwracane i bd niedostpne, poniewa metoda getElementById zwraca tylko instancj pojedynczego elementu HTML. W przeciwiestwie do metody getElementsByTagName, nie ma gwarancji, e zwrcony element bdzie mia okrelony typ, inny ni typ
elementu, ktrego atrybut id jest taki sam, jak parametr przekazywany podczas wywoywania metody getElementById. Dlatego te model obiektowy, ktrego uywamy
po wywoaniu tej metody, moe, ale nie musi by odpowiedni dla pobranego elementu.
W przypadku waciwoci innerHTML nie stanowi to problemu, poniewa maj j niemal wszystkie widoczne elementy. Problem moe si pojawi, jeli zaoymy, e pobrany
element jest tabel, podczas gdy w rzeczywistoci bdzie on komrk tabeli. W takim
wypadku zastosowanie do niego modelu obiektowego tabeli spowoduje powstanie
wyjtku.
Podczas pisania kodu w JavaScripcie dobr praktyk jest sprawdzanie pobranego
elementu przed wykonaniem na nim jakichkolwiek dziaa. Musisz zaoy, e podczas
uywania getElementsByTagName wiesz, jaki typ bd miay elementy HTML, ale nie
wiesz, gdzie si znajduj ani co reprezentuj. Z kolei podczas uywania getElementById wiesz, co reprezentuje i gdzie si znajduje element, ale nie znasz jego typu i, co
si z tym wie, hierarchii obiektw.

Szczeglna natura innerHTML


Waciwo innerHTML jest szczeglna, poniewa wydaje si atwa w uyciu, ale korzystanie z niej moe wiza si z powanymi konsekwencjami. eby pokaza, gdzie
ley problem, przyjrzyjmy si nastpujcemu kodowi HTML:
<html>
<head>
<title>Fragment dokumentu HTML</title>
<script language="JavaScript" type="text/javascript">
function foodteplace() {
document.getElementById("mycell").innerHTML = "witaj";
}
function Badteplace() {
document.getElementById("mytable").innerHTML = "witaj";
}
function TestTable() {
window.alert(document.getElementsByTagName(
"table")[0].rows[0].cells[0].innerHTML);
}
</script>
</head>
<body>
<button onclick="foodteplace()">Prawidowa wymiana</button>

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

75

<button onclick="Badteplace()">Nieprawidowa wymiana</button>


<button onclick="TestTable()">Sprawd tabel</button>
<table id="mytable" border="1">
<tr id="myrow"><td id="mycell">Brak zawartoci</td><td>Druga kom rka</td></tr>
</table>
</body>
</html>

W powyszym przykadzie znajduj si trzy przyciski (Prawidowa wymiana, Nieprawidowa wymiana i Sprawd tabel), a elementom HTML tabeli, jej wierszowi
i komrce nadano identyfikatory. Nacinicie przycisku Prawidowa wymiana
spowoduje prawidowe umieszczenie kodu HTML. Nacinicie przycisku Nieprawidowa
wymiana spowoduje nieprawidowe umieszczenie kodu HTML. Przycisk Sprawd tabel jest uywany do sprawdzenia wynikw umieszczenia HTML wykonanego przez
nacinicie Prawidowa wymiana albo Nieprawidowa wymiana. Efekt pobrania strony HTML do przegldarki bdzie podobny do rysunku 3.5.
Rysunek 3.5.
Pocztkowa
strona HTML

eby sprawdzi, czy strona HTML jest prawidowa, naley nacisn przycisk Sprawd
tabel. Spowoduje to wywoanie funkcji TestTable, ktra sprawdza, czy istnieje zawarto wewntrz komrek tabeli, a jeli tak, to wywietla j w okienku dialogowym.
Okienko dialogowe powinno wyglda podobnie do przedstawionego na rysunku 3.6.
Okienko dialogowe na rysunku 3.6 potwierdza, e komrka tabeli zawiera warto
Brak zawartoci. Oznacza to, e strona HTML jest prawidowa. Po naciniciu przycisku Prawidowa wymiana wywoywana jest funkcja GoodReplace zmieniajca zawarto
komrki tabeli z Brak zawartoci na witaj. eby sprawdzi, czy strona HTML jest
nadal prawidowa, naley nacisn przycisk Sprawd tabel. Jeli strona HTML jest
prawidowa, powinno si pokaza okienko dialogowe z napisem witaj i tak si dzieje,
co wida na rysunku 3.7.

76

Ajax. Wzorce i najlepsze rozwizania

Rysunek 3.6.
Wywietlenie
zawartoci komrki
mycell

Rysunek 3.7.
Zmodyfikowana
zawarto komrki
mycell

Sprbujmy rzecz nieco skomplikowa przez nacinicie przycisku Nieprawidowa


wymiana. Spowoduje ono wywoanie funkcji BadReplace, ktra przypisuje nowy tekst
do waciwoci innerHTML tabeli HTML. Oznacza to, e zawarto HTML <table><tr>
<td>...</table> zostaje zamieniona na <table>witaj</table>. Zmieniony HTML jest
nieprawidowy i zostanie wywietlony tak, jak pokazano na rysunku 3.8.
Na rysunku 3.8 wida, e wiersze tabeli zostay usunite. Nacinicie przycisku Sprawd
tabel w celu sprawdzenia poprawnoci strony spowoduje powstanie bdu przedstawionego na rysunku 3.9.

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

77

Rysunek 3.8.
Zawarto HTML
po podmianie wierszy
i komrek tabeli

Rysunek 3.9.
Wyjtek modelu
obiektowego

Wygenerowany wyjtek jest istotny i wynika ze sposobu dziaania waciwoci innerHTML.


Podczas przypisywania zawartoci HTML do innerHTML uywa si danych tekstowych.
Podczas pobierania wartoci waciwoci innerHTML elementy potomne zamieniane s
na tekst. Przypisywanie wartoci do waciwoci innerHTML oznacza zamian elementw
potomnych na podany tekst HTML. Nastpnie HTML podany w postaci tekstu jest
konwertowany na zestaw elementw HTML, ktre s pokazywane uytkownikowi.
Funkcje GoodReplace i BadReplace s przykadem przeprowadzania operacji na waciwoci innerHTML. Jednake zmiana wartoci waciwoci innerHTML w przypadku, kiedy
nie powinna ona by zmieniana, albo zmiana powodujca naruszenie struktury HTML
spowoduje powstanie nieprawidowoci. Na przykad w powyszym przypadku nie
moge stworzy tabeli bez wierszy czy komrek.
Innym sposobem operowania na obiektowym modelu dokumentu HTML jest uywanie pojedynczych elementw HTML. Mona tworzy ich instancje, przeprowadza
jakie operacje i usuwa. Dziki wykorzystaniu obiektowego modelu dokumentu znacznie
trudniej jest spowodowa nieprawidowoci, poniewa pozwala on na uywanie tylko

78

Ajax. Wzorce i najlepsze rozwizania

niektrych metod i waciwoci. Podczas korzystania z obiektowego modelu dokumentu HTML nie mona w prosty sposb usun wszystkich wierszy tabeli i zamieni
ich na tekst. Obiektowy model tabeli nie ma metod umoliwiajcych stworzenie konstrukcji przedstawionej na rysunku 3.8.
Naley pamita, e we wzorcu Fragmentacja Zawartoci wymieniane s cae fragmenty HTML. Dlatego mimo tego, e waciwo innerHTML jest elastyczna i daje due
moliwoci, wymiana nieodpowiedniego fragmentu w nieodpowiednim czasie moe
da w efekcie le sformatowany HTML. Powiniene pamita, e podczas odwoywania si do elementw HTML w kontekcie omawianego wzorca naley odwoywa si
tylko do tych elementw strony szkieletowej, w ktrych maj by umieszczane poszczeglne fragmenty zawartoci. Podstawow zasad powinno by to, e skrypt w szkielecie HTML nie odwouje si bezporednio do elementw w dynamicznie umieszczanych
fragmentach, poniewa tworzy to dynamiczne zalenoci, ktre mog, ale nie musz
dziaa. Jeli takie zalenoci s niezbdne, umie je w metodach zawartych w umieszczanym fragmencie kodu i nastpnie odwouj si tylko do tych metod. JavaScript
umoliwia przypisanie okrelonych funkcji do elementw HTML.

Identyfikowanie elementw
Jak ju wspomniaem, podczas wyszukiwania elementw z wykorzystaniem typu
znacznika nie jest moliwe okrelenie identyfikatora, a podczas wyszukiwania z wykorzystaniem identyfikatora nie jest moliwe okrelenie typu znacznika. Bez wzgldu
na to, w jaki sposb zostan znalezione elementy, bd one stanowiy pocztkowy
punkt, w ktrym zostan przeprowadzane operacje. Na podstawie tego punktu skrypt
moe porusza si po elementach bdcych jego rodzicami albo elementami potomnymi przy wykorzystaniu standardowych waciwoci i metod.
Owe standardowe waciwoci i metody s dostpne niemale dla wszystkich elementw HTML. Dlatego te programici skryptw powinni wykorzystywa je podczas poruszania si po hierarchii elementw, zmieniania wygldu czy przy prbie ich identyfikacji. W tabeli 3.1 przedstawiono waciwoci, ktre mog by wykorzystane podczas
pisania skryptw.

Fragmenty w postaci danych binarnych,


URL i obrazkw
Tworzenie fragmentw zawartoci z danych binarnych czy obrazkw w ich pierwotnej
postaci przy uyciu obiektu XMLHttpRequest jest raczej skomplikowane, poniewa ten
rodzaj danych jest uszkadzany podczas odczytu. Waciwoci responseText i responseXML
obiektu XMLHttpRequest oczekuj odpowiednio tekstu albo XML-a. Uycie danych
w innym formacie nie jest moliwe. Oczywicie jest wyjtek: dane binarne zakodowane
w formacie Base64 s traktowane jako tekst i mona je pobra, wykorzystujc obiekt
XMLHttpRequest. Innym rozwizaniem moe by uywanie odnonikw do danych binarnych zamiast samych danych. W przypadku znacznika img oznacza to, e do atrybutu
src naley przypisa URL wskazujcy, gdzie znajduje si obrazek.

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

79

Tabela 3.1. Waciwoci elementw HTML przydatne podczas pisania skryptw


Identyfikator
waciwoci

Opis

attributes[]

Zawiera przeznaczon tylko do odczytu kolekcj atrybutw zwizanych


z elementem HTML. Pojedynczy atrybut moe by pobrany przy uyciu
metody getAttribute. Do przypisania lub napisania atrybutu uywana
jest metoda setAttribute, a do jego usunicia removeAttribute.

childNodes[]

Do instancji NodeList odwouje si najczciej jak do tablicy, przy czym


jest ona tylko do odczytu. eby doda element potomny do biecego
elementu, naley uy appendChild. Do usuwania elementu potomnego
uywana jest metoda removeChild, a do zamiany replaceChild.

className

Suy do przypisywania do elementu HTML klasy z arkusza stylw.


Typ class jest bardzo wany w dynamicznym HTML-u, poniewa mona
dziki niemu dynamicznie zmienia wygld elementw HTML.

dir

Wskazuje na kierunek przepywu tekstu: z lewej do prawej (ltr) albo


z prawej do lewej (rtl).

disabled

Wcza (warto false) bd wycza (warto true) element. Jest przydatny,


jeli skrypt nie chce, eby uytkownik nacisn jaki przycisk albo inny
element interfejsu, zanim nie zostanie zakoczona jaka operacja.

firstChild, lastChild

Pobiera pierwszy albo ostatni wze potomny.

id

Identyfikator uywany do odnalezienia danego elementu. Waciwo ta


jest uywana na przykad podczas wywoywania metody getElementById.

nextSibling,
previousSibling

Pobiera nastpny albo poprzedni ssiedni element. W poczeniu


z firstChild i lastChild moe by uywany do przechodzenia przez
zbir elementw. To podejcie moe by uywane do przechodzenia listy,
w ktrej poszczeglne elementy wskazuj, jaki powinien by nastpny
element, na przykad podczas implementowania wzorca Dekorator
albo podobnej struktury.

nodeName

Zawiera nazw elementu, co w przypadku HTML-a oznacza nazw


znacznika (na przykad td, table itp.).

nodeType

Zawiera typ elementu, ale jest wykorzystywany gwnie podczas


przetwarzania XML-a. W odniesieniu do HTML-a ta waciwo
jest mao przydatna.

nodeValue

Zawiera warto danych w wle. Ta waciwo take jest bardziej przydatna


podczas przetwarzania dokumentw XML. W odniesieniu do HTML-a nie
mona uywa tej waciwoci jako zamiennika dla innerHTML.

parentElement

Pobiera element bdcy rodzicem biecego elementu. Moe by uywana


na przykad do poruszania si po tabeli zawierajcej wiersze i komrki.

style

Zawiera biece waciwoci stylu elementu. Jest instancj typu


CSSStyleDeclaration.

tabIndex

Okrela kolejno elementu podczas wybierania klawiszem Tab w odniesieniu


do caego dokumentu HTML.

tagName

Zawiera nazw znacznika biecego elementu. Ta waciwo moe by


uyta podczas prby okrelenia typu elementu po pobraniu go metod
getElementById.

80

Ajax. Wzorce i najlepsze rozwizania

Obrazki pobierane s porednio. eby zrozumie sposb, w jaki si to odbywa, spjrzmy


na aplikacj, ktra wykorzystuje XMLHttpRequest do pobrania dokumentu zawierajcego
jedn linijk. Linijka ta zawiera URL do pliku z obrazkiem.
Poniej znajduje si implementacja przykadowego programu:
<html>
<head>
<title>Fragment dokumentu HTML z obrazkiem</title>
<script language="JavaScript" src="/lib/factory.js"></script>
<script language="JavaScript" src="/lib/asynchronous.js"></script>
<script language="JavaScript" type="text/javascript">
var asynchronous = new Asynchronous();
asynchronous.complete = function(status, statusText, responseText, responseXML) {
document.getElementById("image").src = responseText;
}
</script>
</head>
<body>
<button onclick="asynchronous.call('/chap03/chunkimage01.html')">Pobierz
obrazek</button>
<br>
<img id="image" />
</body>
</html>

Do pobrania obrazka uywany jest znacznik img. W wikszoci obrazkw znacznik img
jest okrelony przy uyciu atrybutu src bdcego odnonikiem do miejsca, w ktrym si
one znajduj. W tym przykadzie nie ma atrybutu src, zamiast tego jest id. Po wczytaniu i pokazaniu strony HTML wywietlany jest uszkodzony obrazek, poniewa ze
znacznikiem img nie jest zwizany aden plik. eby znacznik img wywietla si prawidowo, naley nacisn przycisk Pobierz obrazek, ktry wykonuje danie pobierajce jednolinijkowy plik zawierajcy URL obrazka. Po pobraniu jednolinijkowego pliku
przez XMLHttpRequest wywoywana jest implementacja funkcji waciwoci complete.
Przypisuje ona do atrybutu (waciwoci) src URL zdalnego obrazka. Nastpnie
przegldarka aktualizuje dane, pobiera obrazek i wywietla go.
Jednolinijkowy plik znajduje si pod adresem URL /chap03/chunkimage01.html i ma
nastpujc zawarto:
/static/patches01.jpg

Gdy omawiana strona HTML, w ktrej nie zosta okrelony atrybut src, zostanie pobrana, bdzie ona wywietlona podobnie jak na rysunku 3.10.
Na rysunku 3.10, poniej przycisku Pobierz obrazek wida may prostokt wskazujcy
nieprawidowy znacznik img, ktry nie spowodowa wczytania adnego obrazka. Po
naciniciu przycisku Pobierz obrazek pobierane jest cze do obrazka. Nastpnie jest
ono przypisywane do znacznika img, co powoduje wczytanie obrazka. Na rysunku 3.11
wida przetworzon stron.

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

81

Rysunek 3.10.
Pocztkowa strona
HTML bez obrazka

Rysunek 3.11.
Strona HTML
po wczytaniu obrazka

Pobieranie i przypisywanie cza, ktre jest nastpnie przetwarzane przez przegldark,


wydaje si dziwne. To porednie podejcie nie ma przedstawia, jak skomplikowana
moe by aplikacja internetowa, ale jest potrzebne, poniewa nie ma moliwoci bezporedniego pobierania danych binarnych. Jednak nie jest to a tak wielki problem, poniewa przegldarka wczytuje obrazek, do ktrego si odnosimy, i umieszcza go w swojej
pamici podrcznej. Jeli bdziemy si do niego ponownie odnosi, zostanie on pobrany
wanie z pamici podrcznej przegldarki. Oczywicie dzieje si tak tylko w przypadku, kiedy serwer HTTP implementuje pami podrczn. Jest jeden minus tego
rozwizania. Jeli wykonujemy danie pobierajce URL, ktry jest odnonikiem do
obrazka, wymagane s dwa dania: jedno do pobrania adresu URL obrazka i drugie
do pobrania jego samego. Jeli oba dania uywaj protokou HTTP 1.1, a tak bdzie
w wikszoci przypadkw, zostan one wykonane podczas jednego poczenia.

82

Ajax. Wzorce i najlepsze rozwizania

Kolejn odmian przedstawionej strategii jest pobranie caego kodu HTML tworzcego
obrazek, a nie samego adresu URL. Ta strategia nie zachowuje poczenia dania,
ale jest samodzielnym rozwizaniem, ktre nie wymaga dodatkowego skryptu. Poniszy
fragment przedstawia, w jaki sposb pobierany jest cay znacznik img.
<img src="/static/patches01.jpg" />

Zarwno podczas umieszczania znacznika img, jak i odpowiedniego atrybutu src przegldarka dynamicznie pobierze obrazek, jak to pokazano w poprzednim przykadzie.
Zalet umieszczania kodu HTML jest to, e aplikacja po stronie serwera moe umieci wiele obrazkw albo inny rodzaj HTML. Ponadto podczas umieszczania caego
znacznika img nie wystpuje pierwszy etap, w ktrym wywietlany jest uszkodzony
obrazek. Jednake oba podejcia s tak samo dobre, a ich wybr zaley od rodzaju
aplikacji. Kiedy na stronie umieszczany jest HTML, moe ona migota, gdy bdzie
zmieniany jej rozmiar. Kiedy przypisujesz warto do waciwoci src, nie wystpuje
migotanie, ale trzeba okreli pusty obrazek albo ukry element obrazka.

Fragmentacja JavaScriptu
Kolejnym rodzajem fragmentacji jest wysyanie JavaScriptu. Moe ono by bardzo efektywne, poniewa nie musisz przetwarza danych, a tylko wykona JavaScript. Z punktu
widzenia skryptu po stronie klienta jest to bardzo atwe do zaimplementowania. Nie
powiniene jednak zakada, e pobranie JavaScriptu bdzie szybsze ni parsowanie
i przetworzenie danych XML, a nastpnie skonwertowanie ich przed wykonaniem.
Zalet podejcia wykorzystujcego JavaScript jest prostota i efektywno. Po prostu
atwiej jest wykona fragment JavaScriptu i odnosi si do udostpnionych waciwoci i funkcji.

Wykonywanie JavaScriptu
Rozpatrzmy poniszy kod HTML, ktry wykonuje okrelony JavaScript:
<html>
<head>
<title>Fragment zawartoci HTML z JavaScriptem</title>
<script language="JavaScript" src="/lib/factory.js"></script>
<script language="JavaScript" src="/lib/asynchronous.js"></script>
<script language="JavaScript" type="text/javascript">
var asynchronous = new Asynchronous();
asynchronous.complete = function(status, statusText, responseText, responseXML) {
eval(responseText);
}
</script>
</head>
<body>
<button onclick="asynchronous.call('/chap03/chunkjs01.html')">Pobierz
skrypt</button>
<table>

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

83

<tr><td id="insertplace">Brak zawartoci</td></tr>


</table>
</body>
</html>

Po naciniciu przycisku Pobierz skrypt wykonywane jest danie XMLHttpRequest


pobierajce dokument /chap03/chunkjs01.html. Dokument zawiera fragment JavaScriptu, ktry jest wykonywany za pomoc funkcji eval. Pobierany jest nastpujcy fragment kodu:
window.alert("hurra, wywoane dynamicznie");

Przykadowy fragment nie jest zbytnio rozbudowany i wywietla okienko dialogowe.


Tym, co niepokoi wielu ludzi podczas wykonywania takiego kodu JavaScript, jest to,
e jest on pobrany z zewntrz. Administrator i uytkownik moe zastanawia si nad
konsekwencjami zwizanymi z bezpieczestwem, poniewa pobrany JavaScript moe
zawiera wirusy. Jednake tak waciwie nie jest to moliwe, gdy JavaScript jest wykonywany w piaskownicy i dotyczy go polityka tego samego rda. Oczywicie jeli
programista ominie polityk tego samego rda, problemy zwizane z bezpieczestwem
nabior znaczenia.
Najprostsz implementacj pobierania fragmentu kodu do wykonania jest dynamiczne
tworzenie po stronie serwera fragmentw JavaScriptu, ktre wykonuj jakie metody.
Fragmenty JavaScriptu powoduj, e przegldarka wykonuje jakie polecenia. Na
przykad fragment JavaScriptu pobierany w poprzednim przykadzie mgby by wykorzystywany do przypisania jakich danych do znacznika span albo td, co przedstawiono
poniej:
document.getElementById("mycell").innerHTML = "witaj";

Wygenerowany skrypt jest zakodowany na sztywno, poniewa oczekuje, e na docelowej


stronie HTML bd znajdoway si okrelone elementy.

Generowanie JavaScriptu operujcego


na obiektowym modelu dokumentu
Wczeniej widziae rozwizanie, w ktrym obrazek pocztkowo by uszkodzony, a nastpnie wywietlony po pobraniu prawidowego cza. Obrazek mona take pobra poprzez zmian obiektowego modelu dynamicznego HTML-a. Model obiektowy zmieniasz poprzez wykorzystanie fragmentu JavaScriptu do wstawienia znacznika img.
Poniej znajduje si fragment JavaScriptu tworzcy znacznik img i wstawiajcy go do
dokumentu HTML.
var img = new Image();
img.src = "/static/patches01.jpg";
document.getElementById("insertplace").appendChild(img);

W tym przykadzie zmienna img jest instancj obiektu Image, ktry odnosi si do znacznika HTML img. Do waciwoci src przypisywany jest adres URL obrazka. Ostatnia
linia tego fragmentu kodu uywa metody appendChild, eby doda instancj obiektu
Image do dokumentu HTML. Jeli zmienna img nie zostanie powizana z dokumentem

84

Ajax. Wzorce i najlepsze rozwizania

HTML, obrazek zostanie pobrany, ale nie bdzie dodany do dokumentu HTML i w zwizku z tym nie bdzie wywietlony. Strona HTML wygenerowana po wykonaniu powyszego skryptu pokazana jest na rysunku 3.12.
Rysunek 3.12.
Strona HTML
wygenerowana
po wstawieniu obrazka

Rysunek 3.12 nie jest zbyt widowiskowy, poniewa ilustruje tylko sposb, w jaki obrazek
moe by wstawiony na stron HTML. Interesujce jest to, e pozosta tekst Brak zawartoci, ktry nie zosta zamieniony tak jak w poprzednich przykadach. Przyczyna
tego tkwi w tym, e zostaa wykorzystana metoda appendChild (a nie replaceChild
albo removeChild i nastpnie appendChild).
Zalet podejcia wykorzystujcego model obiektowy dynamicznego HTML-a jest to,
e umoliwia ono pobieranie obrazkw albo innych elementw w tle, a moment ich
wywietlenia moe by okrelony w skrypcie.

Tworzenie instancji obiektu


Innym rodzajem fragmentw JavaScriptu, ktre mog by pobierane, s stany obiektw. Przy wykorzystaniu stanu obiektu moesz wprowadzi poziom poredni umoliwiajcy dodawanie funkcji podczas wykonywania strony HTML. We wszystkich poprzednich przykadach fragmenty kodu HTML na pocztkowej stronie HTML musiay
mie wszystkie skrypty i zna adresy URL pobieranych zasobw. Dziki wykorzystaniu
poredniego poziomu JavaScript po stronie klienta nie musi zna szczegw adresw
URL czy struktur danych. Klient odwouje si do oglnego fragmentu kodu, ktry jest
wykonywany. Oglny fragment kodu jest zarzdzany przez serwer i zawiera poszczeglne instrukcje wykonujce, ktre mog wykonywa operacje niezaprogramowane
pierwotnie po stronie klienta. Uywanie poredniego poziomu umoliwia dodawanie
do klienta funkcji, ktrych nie mia on w czasie projektowania aplikacji.
Przyjrzyjmy si poniszemu przykadowi strony HTML:
<html>
<head>
<title>Fragment zawartoci HTML z JavaScriptem</title>

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

85

<script language="JavaScript" src="/lib/factory.js"></script>


<script language="JavaScript" src="/lib/asynchronous.js"></script>
<script language="JavaScript" type="text/javascript">
var asynchronous = new Asynchronous();
asynchronous.complete = function(status, statusText, responseText, responseXML) {
eval(responseText);
dynamicFiller.makeCall(document.getElementById("insertplace"));
}
</script>
</head>
<body>
<button onclick="asynchronous.call('/chap03/chunkjs0<.js')">tozpocznij
przetwarzanie</button>
<table>
<tr><td id="insertplace">Brak zawartoci</td></tr>
</table>
</body>
</html>

Podobnie jak w poprzednich przykadach tworzona jest instancja Asynchronous. Element button powoduje wykonanie asynchronicznego dania z adresem URL /chap03/
chunkjs04.js. Kiedy danie pobierze fragment JavaScriptu, jest on wykonywany
przez instrukcj eval. Po powrocie z instrukcji eval wykonywana jest metoda dynamicFiller.makeCall, ktrej wywoanie jest oglnym fragmentem kodu. Implementacja tej metody jest kodem zarzdzanym przez serwer, a odniesienie si do niej jest
wykonywane przy uyciu niekompletnej zmiennej, poniewa pocztkowy skrypt nie
zawiera definicji zmiennej dynamicFiller. Oczywicie wczytany i przetworzony skrypt
nie moe odnosi si do niekompletnej zmiennej, poniewa spowodowaoby to powstanie wyjtku. Ale tym, co moe zrobi skrypt, jest wczytanie implementacji, zanim
zostanie uyta niekompletna zmienna. I to wanie jest przedstawione w powyszej stronie
HTML. Uprzedzam pytanie: w plikach factory.js i asynchronous.js nie ma definicji
zmiennej dynamicFiller. JavaScript umoliwia stosowanie niekompletnych zmiennych,
typw i funkcji, co pozwala na wczytywanie i przetwarzanie skryptw bez wywoywania wyjtkw.
Poniszy kod rdowy zawiera implementacj niekompletnej zmiennej dynamicFiller:
var dynamicFiller = {
generatedAsync : new Asynchronous(),
reference : null,
complete : function(status, statusText, responseText, responseXML) {
dynamicFiller.reference.innerHTML = responseText;
},
makeCall : function(destination) {
dynamicFiller.reference = destination;
dynamicFiller.generatedAsync.complete = dynamicFiller.complete;
dynamicFiller.generatedAsync.call('/chap03/chunkjs05.html');
}
}

Przykadowy kod rdowy JavaScriptu jest napisany przy wykorzystaniu inicjalizatora


obiektu. Inicjalizator obiektu jest zapisan postaci obiektu JavaScript. Nie powiniene
porwnywa go do definicji klasy JavaScript. To dwie zupene rne rzeczy. Podczas

86

Ajax. Wzorce i najlepsze rozwizania

przetwarzania inicjalizatora obiektu tworzona jest instancja obiektu, ktrej identyfikatorem jest zadeklarowana zmienna. W tym przykadzie instancj obiektu jest zmienna
dynamicFiller.
Zmienna dynamicFiller ma dwie waciwoci (generatedAsync i reference) oraz dwie
metody (complete i makeCall). Waciwo generatedAsync jest instancj Asynchronous
wykorzystywan do wykonywania asynchronicznych da do serwera. Waciwo
reference jest elementem HTML, na ktrym metoda complete bdzie przeprowadza
operacje. Metoda makeCall jest wykorzystywana do wykonywania dania XMLHttpRequest, a do parametru destination przypisana jest waciwo reference.
Po poczeniu wszystkich fragmentw kod HTML szkieletu zawiera oglny kod, ktry
ma odniesienie do niekompletnej zmiennej. eby uzyska pen zmienn, pobierana
i wykonywana jest zawarto w jzyku JavaScript. Pena zmienna zawiera kod pobierajcy zawarto, ktra jest umieszczana w stronie szkieletowej. Na rysunku 3.13
przedstawiono sekwencj wykonywanych zdarze.
Rysunek 3.13.
Sekwencja zdarze
podczas pobierania
i wykonywania
JavaScriptu

Na rysunku 3.13 wida pocztkow stron pobieran po naciniciu przycisku. Pobieran


zawartoci jest JavaScript, przy czym pocztkowa strona nie wie, co on wykonuje.
Zawarto jest pobierana i nastpnie wykonywana. W szkieletowej stronie HTML zaprogramowano odniesienie do zmiennej dynamicFiller i wywoanie metody makeCall.
Metoda makeCall nie istnieje podczas wykonywania szkieletowej strony HTML i staje
si dostpna dopiero po pobraniu i wykonaniu zawartoci. Pobrana zawarto jest wykonywana i pobiera kolejny fragment zawartoci, ktry jest umieszczany w stronie HTML.
W wyniku tego pobierany jest obrazek wywietlany w miejscu, gdzie znajdowa si
tekst Nothing.

Rozdzia 3. Wzorzec Fragmentacja Zawartoci

87

Rola szkieletowej strony HTML zmienia si. Teraz staa si ona stron inicjalizujc,
ktra pobiera inne fragmenty kodu. Pobrane fragmenty kodu s cakowicie dynamiczne
i zawieraj odniesienia i kod, ktry nie jest znany w szkieletowej stronie HTML. Zalet
tej implementacji jest to, e dokument moe by pobierany stopniowo poprzez pobieranie fragmentw kodu, ktre s okrelane dopiero po ich pobraniu. Wzorzec Fragmentacja Zawartoci umoliwia dynamiczne adowanie zawartoci, a dodanie wczytywania JavaScriptu umoliwia dynamiczne okrelanie logiki uywanej przez szkieletow
stron HTML.

Najwaniejsze elementy wzorca


Poniej wymienione s najwaniejsze elementy wzorca Fragmentacja Zawartoci:
t Strona HTML jest poczeniem szkieletowej strony HTML i fragmentw

zawartoci.
t Szkieletowa strona HTML jest odpowiedzialna za organizowanie,

odniesienia i pobieranie odpowiednich fragmentw. Powinna sterowa


poszczeglnymi fragmentami. Szkieletowa strona HTML przenosi
przetwarzanie fragmentw zawartoci do innych fragmentw kodu.
t Fragmenty zawartoci s unikalnie identyfikowane przez URL.

Rne fragmenty zawartoci nie uywaj tych samych adresw URL.


Fragmenty zawartoci s uywane do zaimplementowania funkcji
okrelanych przez uytkownika.
t Fragmenty zawartoci mog przyjmowa jedn z trzech postaci:

XML (preferowany), HTML (preferowany XHTML) albo JavaScript.


S jeszcze inne rodzaje zawartoci, ale nie bd one omawiane
w tej ksice, a korzystanie z nich powinno by dobrze przemylane.