Czym jest a czym nie jest AJAX ?
- AJAX jest skrótem od Asynchronous JavaScript And XML
- AJAX nie jest nową, samodzielną technologią
- AJAX to nowy sposób myślenia o aplikacjach internetowych z wykorzystaniem istniejących rozwiązań: XML, CSS, JavaScript, DOM
Model aplikacji

- Praca w trybie żądanie-odpowiedź
- Logika biznesowa w całości po stronie serwera
- Interakcja z serwerem poprzez linki i formularze HTML
- Asynchroniczna komunikacja z serwerem z poziomu kodu JavaScript w przeglądarce
- Serwer wysyła dane, fragmenty kodu, a nie całe strony
- Dokument w przeglądarce modyfikowany programowo poprzez interfejs DOM
Co do czego ...
- HTML (lub XHTML) + CSS – prezentacja danych
- JavaScript – implementacja części logiki aplikacji po stronie klienta
- Document Object Model (DOM) – programowa modyfikacji dokumentu w przeglądarce
- XML – podstawowy format przesyłanych danych (alternatywnie czysty tekst lub format JSON)
- Obiekt XMLHttpRequest – asynchroniczna komunikacja z serwerem
Zalety i wady ...
Zalety:
- redukuje ruch w sieci i zmniejsza obciążenie serwera
- odciąża serwer (przetwarzanie po stronie klienta)
- separacja danych i formatowania
- interaktywne, szybkie i przyjazne aplikacje
- oparty o znane i dojrzałe już dziś technologie
- nie wymaga instalacji wtyczek w przeglądarce (por. Java, Java Web Start, Flash)
- prefetching
- język JavaScript nieodpowiedni dla dużych aplikacji
- konieczność włączenia obsługi JavaScript
- problem historii przeglądanych stron
- problem zakładek do dynamicznych stron wyszukiwarki (identyfikator fragmentu #abc)
- wrażliwy na opóźnienia w komunikacji sieciowej
- trudna implementacja, testowanie i debugowanie aplikacji
- niedojrzałe biblioteki i narzędzia programistyczne
XML
1<book> 2 <isbn>99-99999-99-9</isbn> 3 <title>AJAX</title> 4 <authors> 5 <author> 6 <first_name>John</first_name> 7 <last_name>Smith</last_name> 8 </author> 9 <author> 10 <first_name>James</first_name> 11 <last_name>White</last_name> 12 </author> 13 </authors> 14</book>[pokaż zawartość pliku] [pobierz plik] idź do góry
JSON
- Obiekty
- sekwencja par atrybut-wartość
- Tabele: sekwencja wartości w nawiasach kwadratowych
- Kodowanie UTF-8
- Wartości specjalne: true, false, null
- Znaki specjalne: \", \\, \t, \uXXXX
- Wsparcie dla języków skryptowych, np. PHP: json_decode, json_encode
1{ 2 "isbn": "99-99999-99-9", 3 "title": "AJAX", 4 "authors": [ 5 {"first_name": "John", "last_name": "Smith"}, 6 {"first_name": "James", "last_name": "White"} 7 ], 8 "date": { 9 "year": 2006, 10 "month": sep, 11 "day": 12 12 } 13}[pokaż zawartość pliku] [pobierz plik] idź do góry
Który format wybrać ?
Zalety XML:
- powszechnie znany format ogólnego przeznaczenia
- bogactwo narzędzi po stronie serwera (np. parsery)
- możliwość przetwarzania odebranych z serwera danych za pomocą transformacji XSLT
- silne wsparcie ze strony biznesu
- łatwość i szybkość parsowania w języku JavaScript
- czytelny dla człowieka i maszyny
- samodokumentujący się format
- proste i jasne reguły poprawności powodują że parsery są szybkie i łatwe do napisania
Metody obiektu XMLHttpRequest
- abort()
- Zatrzymuje aktualne żądanie.
- getAllResponseHeaders()
- Zwraca kompletny nagłówek (zbiór etykiet i wartości) jako string.
- getResponseHeader(”etykieta”)
- Zwraca wartość pojedynczego nagłówka (jako string), którego etykieta została podana jako parametr.
- open(”metoda”, ”URL”, asyn)
- Określenie docelowego adresu URL i metody planowanego żądania.
- send(dokument)
- Wysłanie żądania.
- setRequestHeader(”etykieta”, ”wartość”)
- Określenie elementów nagłówka, który zostanie wysłany razem z żądaniem.
Atrybuty obiektu
- onreadystatechange
- Uchwyt dla funkcji wywoływanej przy każdej zmianie stanu.
- readyState
- Stan obiektu (integer):
0 = zapytania niezainicjowane
1 = cel otwarty
2 = zapytanie wysłane
3 = odbieranie odpowiedzi
4 = żądanie zakończone - responseText
- Pole przechowuje dane pobrane z serwera.
- responseXML
- Dane kompatybilne z DOM zwrócone z serwera.
- status
- Numeryczny kod zwrócony przez serwer (np. 404, 200).
- statusText
- Opis kodu zwróconego przez serwer.
Tworzenie obiektu XMLHttpRequest
Obsługa tworzenia obiektu XMLHttpRequest nie jest niestety identyczna we wszystkich przeglądarkach. W przypadku IE należy to zrobić inaczej niż w pozostałych przeglądarkach. Stąd, skrypt JavaScript odpowiedzialny za utowrzenie instancji XMLHttpRequest próbuje tworzyć ten obiekt korzystając z obydwu API, przy czym co najmniej jedna z tych prób jest zawsze nieudana.
Kod tworzący instancję XMLHttpRequest jest zwykle pewną odmianą kodu zaprezentowanego poniżej.1function getHTTPObject() { 2 var xhr = false; 3 if (window.XMLHttpRequest) { 4 xhr = new XMLHttpRequest(); 5 } 6 else if (window.ActiveXObject) { 7 try { 8 xhr = new XMLHttpRequest(); 9 } 10 catch(e) { 11 try { 12 xhr = new ActiveXObject("Microsoft.XMLHTTP"); 13 } 14 catch(e) { 15 xhr = false; 16 } 17 } 18 } 19 return xhr; 20}[pokaż zawartość pliku] [pobierz plik] idź do góry
Obsługa odpowiedzi
W trakcie wysyłania zapytania została określona funkcja, której zadaniem jest obsługi odpowiedzi. Jest to funkcja przypisana do atrybutu
onreadystatechange
.
request.onreadystatechange = nazwaFunkcjiObsługi;
Funkcja ta powinna sprawdzić stan zapytania zapisany w atrybucie readyState
. Możliwe stany zostały opisane w rozdziale dotyczącym atrybutów obiektu XMLHttpRequest
. Jeżeli stan ma wartość 4
, oznacza to, że odebrano już pełną odpowiedź z serwera i można kontynuować przetwarzanie.
if (request.readyState == 4) {
// wszystko jest OK, odpowiedź została odebrana
} else {
// ciągle nie gotowe
}
W następnym kroku należy sprawdzić status odpowiedzi serwera HTTP. Wszystkie możliwe kody są opisane na stronie W3C. Najczęściej sprawdza się jednak czy status ma wartość 200, oznaczającą poprawną sytuację.
if (request.status == 200) {
// świetnie!!
} else {
// wystąpił jakiś problem z zapytaniem,
// na przykład odpowiedzią mogło być 404 (Nie odnaleziono)
// lub 500 (Wewnętrzny błąd serwera)
}
Dopiero po sprawdzeniu powyższych warunków można przystąpić do dalszego przetwarzania otrzymanej z serwera odpowiedzi. Może ona mieć formę danyych XML (atrybut responseXML
) lub czystego tekstu (atrybut responseText
) idź do góry
Hello World
function onResponse() {
if (req.readyState==4) {
if (req.status==200) {
document.getElementById("msg").innerHTML = req.responseText;
}
}
};
UWAGA: Zwróć uwagę na zawartość pola TextBox po naciśnięciu przycisku "test".Pobierz kod plik z komunikatem
Pobierz kod wykonywany po stronie klienta
idź do góry
GET vs. POST
metoda GET:
var url = "ajaxParamsGET.php"; var params = "pin="+vPin+"&code="+vCode; request.open("GET", url+"?"+params, true); request.send(null);
Pobierz kod wykonywany po stronie serwera
Pobierz kod wykonywany po stronie klienta
metoda POST:
var url = "ajaxParamsPOST.php"; var params = "pin="+vPin+"&code="+vCode; request.open("POST", url, true); request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); request.setRequestHeader("Content-length", params.length); request.setRequestHeader("Connection", "close"); request.send(params);
Pobierz kod wykonywany po stronie serwera
Pobierz kod wykonywany po stronie klienta
idź do góry
Pobieranie danych w formacie XML
txt="<table border='0'>"; tBooks=request.responseXML.documentElement.getElementsByTagName("product"); for (i=0;i<tBooks.length;i++) { tTitle=tBooks[i].getElementsByTagName("title"); if (tTitle[0].hasChildNodes()) { vTitle=tTitle[0].firstChild.nodeValue; } tAuthor=tBooks[i].getElementsByTagName("author"); { try { vAuthor = tAuthor[0].firstChild.nodeValue; } catch (er) { vAuthor = ""; } } txt=txt + "<tr><td><b>" + vAuthor+ "</b></td><td>" + vTitle+ "</td></tr>"; } txt=txt + "</table>"; document.getElementById('ProductList').innerHTML=txt;
Pobierz kod plik z danymi o książkach
Pobierz kod plik z danymi o płytach CD
Pobierz kod wykonywany po stronie klienta
idź do góry
Dynamiczne podpowiedzi
Pobierz kod wykonywany po stronie serwera
Pobierz kod wykonywany po stronie klienta
idź do góry
Element canvas
Warto zajrzeć Instrukcja krok po kroku:
- Pobierz szablon dokumentu HTML
- Narysuj prostokąty
ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 380, 50); ctx.fillStyle = "rgba(0, 0, 200, 0.2)"; ctx.fillRect (30, 30, 55, 210); ctx.fillStyle = "rgb(0,255,0)"; ctx.strokeRect (100, 75, 285, 165);
- Narysuj krzywe
x = 170; y = 160; ctx.beginPath(); ctx.arc(x,y,50,0,Math.PI*2,true); // Outer circle ctx.moveTo(x+35,y); ctx.arc(x,y,35,0,Math.PI,false); // Mouth (clockwise) ctx.moveTo(x-10,y-15); ctx.arc(x-15,y-15,5,0,Math.PI*2,true); // Left eye ctx.moveTo(x+20,y-15); ctx.arc(x+15,y-15,5,0,Math.PI*2,true); // Right eye ctx.stroke();
- Narysuj obraz z pliku PNG
var img = new Image(); img.onload = function() { ctx.drawImage(img, 240, 95); } img.src = "ajaxCanvasImage01.png";
- Blobs
- Elektroniczny zegar
- Canvas Painter
- Funkcje 3D
- Galeria zdjęć
- Suprise !
- Torus Tetris
- Dynamicznie generowany wykres
- Wizualny tezaurus
Google Maps API
Zadanie
Wyświetl mapę prezentującą obszar okolic Centrum Wykładowego PP, zaznacz na niej samo centrum, obszar Poligrodu oraz ścieżkę prowadzącą z Centrum Wykładowego do ronda Śródka.
- Dokumentacja API GoogleMaps
- Generator punktów dla Google Maps
- Blog na temat wykorzystania Google Maps
- Pobierz szablon dokumentu HTML
- Uzyskaj swój własny klucz, żeby móc korzystać z GoogleMaps
Rejestracja adresu w GoogleMaps - Pokaż mapę dla zadanej lokalizacji
var myOptions = { zoom: 15, center: new google.maps.LatLng(52.403767285812464,16.950294971466064), mapTypeId: google.maps.MapTypeId.ROADMAP };
- Dodaj kontrolki pozwalające na zmianę parametrów wyświetlania mapy
var myOptions = { panControl: true, zoomControl: true, mapTypeControl: false, scaleControl: true, streetViewControl: true, overviewMapControl: false }
- Wskaż CW PP na mapie
var cwPPmarker = new google.maps.Marker({ position: new google.maps.LatLng(52.403767285812462,16.950294971466064), map: map, title:"Centrum Wykładowe Politechniki Poznańskiej" });
- Dodaj opis CW PP
var contentString = "tutaj można umieścić opis </br>"+ "<a href='http://images.google.com/images?hl=en&q=Centrum+Wyk%C5%82adowe+Politechniki+Pozna%C5%84skiej&btnG=Search+Images&gbv=2'>"+ "Zobacz jak wygląda w rzeczywistości</a>"; var infowindow = new google.maps.InfoWindow({ content: contentString }); google.maps.event.addListener(cwPPmarker, 'click', function() { infowindow.open(map,cwPPmarker); });
- Wskaż na mapie Poligród
var poligrodCoords = [ new google.maps.LatLng(52.40306035658953,16.950488090515137), new google.maps.LatLng(52.40091331691532,16.948320865631104), new google.maps.LatLng(52.39960409510452,16.95211887359619), new google.maps.LatLng(52.402458148687266,16.954264640808105), new google.maps.LatLng(52.40350546149509,16.95411443710327), new google.maps.LatLng(52.403531643996764,16.951797008514404), new google.maps.LatLng(52.40472293138462,16.9494366645813), new google.maps.LatLng(52.403858923956435,16.948471069335938), new google.maps.LatLng(52.40306035658953,16.950488090515137) ]; poligrod = new google.maps.Polygon({ paths: poligrodCoords, strokeColor: "#f33f00", strokeOpacity: 2, strokeWeight: 1, fillColor: "#ff0000", fillOpacity: 0.2 }); poligrod.setMap(map);
- Wskaż na mapie trasę z CW na rondo Śródka
var routeCoords = [ new google.maps.LatLng(52.40380655932604, 16.950488090515137), new google.maps.LatLng(52.40384583280466, 16.95117473602295), new google.maps.LatLng(52.403531643996764, 16.951818466186523), new google.maps.LatLng(52.40358400895346, 16.954565048217773), new google.maps.LatLng(52.404631295035315, 16.95413589477539), new google.maps.LatLng(52.40577019043, 16.954050064086914), new google.maps.LatLng(52.40672579261582, 16.9543719291687), new google.maps.LatLng(52.40892490805024, 16.9559383392334), new google.maps.LatLng(52.40968410101556, 16.956946849822998) ]; var route = new google.maps.Polyline({ path: routeCoords, strokeColor: "##0000ff", strokeOpacity: 1.0, strokeWeight: 4 }); route.setMap(map);
- Animowana trasa między dwoma zadanymi punktami
- Wykorzystanie ikon z Google Earth
- Wskazanie zadanej pozycji
- Opis punktu z wykorzystaniem zakładek
- Dwie mapy skorelowane ze sobą
- Wskazówki dotyczące podróży