Zajęcia 4

Materiały do warsztatów technologii webowych prowadzonych na Wydziale Matematyki i Informatyki Uniwersytetu im. Adama Mickiewicza w Poznaniu.
Wróć do spisu materiałów Tu będziemy testować kod źródłowy

4. Technologia AJAX

4.1. Podstawowe informacje

AJAX to technika wczytywania wczytywania danych we fragmencie strony bez potrzeby odświeżania jej całości. Dane są najczęściej dostarczane w formacie o nazwie JSON.

AJAX wykorzystuje model przetwarzania asynchronicznego. Oznacza to, że użytkownik może wykonywać inne zadania, gdy przeglądarka internetowa oczekuje na wczytanie danych.

Jak to działa?

  • Żądanie - przeglądarka wysyła do serwera WWW żądanie pewnych danych. Żądanie może zawierać informacje wymagane przez serwer; podobnie formularz sieciowy wysyła dane do serwera. W przeglądarkach implementowany jest obiekt o nazwie XMLHttpRequest przeznaczony do obsługi żądań AJAX. Po wysłaniu żądania przeglądarka nie musi czekać na udzielenie odpowiedzi przez serwer.

  • Serwer WWW - udziela odpowiedzi, dostarczając żądane dane (najczęściej w formacie HTML, XML lub JSON). Operacje przeprowadzane na serwerze nie są częścią tego, co określamy mianem AJAX.

  • Odpowiedź - kiedy serwer zakończy udzielanie odpowiedzi na żądanie, przeglądarka wywołuje zdarzenie. Zdarzenie to można wykorzystać do uruchomienia funkcji JS przetwarzającej dane i umieszczającej je na stronie.

Przykład 4.1.1.

/* Żądanie */
let xhr = new XMLHttpRequest(); // utworzenie obiektu XHR
xhr.open('GET', 'data/test.json', true); // przygotowanie żądania
/* W powyższej metodzie pierwszy argument to nazwa metody HTTP, drugi to adres URL strony, która będzie obsługiwać żądanie, trzeci to wartość boolowska, wskazująca, czy żądanie powinno być asynchroniczne*/
xhr.send(null); // wysłanie żądania bez dodatkowych informacji dodatkowych

/* Odpowiedź */
xhr.onload = function() { // wykonanie funkcji anonimowej dla zdarzenia ONLOAD
	if (xhr.status === 200) { // jeśli status wynosi 200 to OK
		// przetworzenie odpowiedzi
	}
}

4.2. Formaty danych

4.2.1. XML

Przykład 4.2.1.1.

<?xml version="1.0" encoding="utf-8" ?>
<events>
  <event>
    <location>San Francisco, CA</location>
    <date>1 maja</date>
    <map>img/map-ca.png</map>
  </event>
  <event>
    <location>Austin, TX</location>
    <date>15 maja</date>
    <map>img/map-tx.png</map>
  </event>
  <event>
    <location>Nowy Jork, NY</location>
    <date>30 maja</date>
    <map>img/map-ny.png</map>
  </event>
</events>

4.2.2. JSON

Przykład 4.2.2.1.

{
  "events": [
    {
      "location": "San Francisco, CA",
      "date": "1 maja",
      "map": "img/map-ca.png"
    },
    {
      "location": "Austin, TX",
      "date": "15 maja",
      "map": "img/map-tx.png"
    },
    {
      "location": "Nowy Jork, NY",
      "date": "30 maja",
      "map": "img/map-ny.png"
    }
  ]
}

Jak przekonwertować obiekt JavaScript na JSON?

JSON.stringify(obiekt);

Jak przetworzyć JSON na obiekt JavaScript?

JSON.parse(daneJSON);

Ćwiczenie 4.2.1.

Przygotuj pliki XML oraz JSON, w których będą znajdowały się informacje o Twoich 5 ulubionych piosenkach. Dla pojedynczej piosenki powinny się tam znaleźć dane takie jak: tytuł, wykonawca, gatunek, album, rok wydania.

Rozwiązanie wyślij na repozytorium Githuba do katalogu Lesson_04. Pliki z rozwiązaniem nazwij exercise_421.xml i exercise_421.json.

4.2.3. Wczytywanie HTML

Pobierz archiwum AJAX.

Przykład 4.2.3.1.

var xhr = new XMLHttpRequest();                 // Utworzenie obiektu XMLHttpRequest.

xhr.onload = function() {                       // Po wczytaniu odpowiedzi.
  if(xhr.status === 200) {                       // Jeżeli stan serwera wskazuje, że wszystko jest w porządku.
    document.getElementById('content').innerHTML = xhr.responseText; // Uaktualnienie.
  }
};

xhr.open('GET', 'data/data.html', true);        // Przygotowanie żądania.
xhr.send(null);                                 // Wykonanie żądania.

4.2.4. Wczytywanie XML

Przykład 4.2.4.1.

var xhr = new XMLHttpRequest();        // Utworzenie obiektu XMLHttpRequest.

xhr.onload = function() {              // Po wczytaniu odpowiedzi.
 if (xhr.status === 200) {             // Jeżeli stan serwera wskazuje, że wszystko jest w porządku.

// Ten fragment jest inny, ponieważ przetwarzane są dane XML, a nie HTML.
var response = xhr.responseXML;                      // Pobranie danych XML z serwera.
var events = response.getElementsByTagName('event'); // Wyszukanie elementów <event>.

for (var i = 0; i < events.length; i++) {            // Iteracja przez znalezione elementy.
 var container, image, location, city, newline;      // Deklaracja zmiennych.
 container = document.createElement('div');          // Utworzenie pojemnika <div>.
 container.className = 'event';                      // Dodanie atrybutu class.

 image = document.createElement('img');              // Dodanie obrazu mapy.
 image.setAttribute('src', getNodeValue(events[i], 'map'));
 image.appendChild(document.createTextNode(getNodeValue(events[i], 'map')));
 container.appendChild(image);

 location = document.createElement('p');             // Dodanie danych dotyczących lokalizacji.
 city = document.createElement('b');
 newline = document.createElement('br');
 city.appendChild(document.createTextNode(getNodeValue(events[i], 'location')));
 location.appendChild(newline);
 location.insertBefore(city, newline);
 location.appendChild(document.createTextNode(getNodeValue(events[i], 'date')));
 container.appendChild(location);

 document.getElementById('content').appendChild(container);
}
function getNodeValue(obj, tag) {                   // Pobranie zawartości z danych XML.
 return obj.getElementsByTagName(tag)[0].firstChild.nodeValue;
}

 // Ostatni fragment jest taki sam jak w przypadku danych HTML, ale żądanie dotyczy pliku XML.
 }
};

xhr.open('GET', 'data/data.xml', true);             // Przygotowanie żądania.
xhr.send(null);                                     // Wykonanie żądania.

4.2.5. Wczytywanie danych JSON

var xhr = new XMLHttpRequest();                 // Utworzenie obiektu XMLHttpRequest.

xhr.onload = function() {                       // Po zmianie stanu.
  if(xhr.status === 200) {                      // Jeżeli stan serwera wskazuje, że wszystko jest w porządku.
    responseObject = JSON.parse(xhr.responseText);

    // Utworzenie ciągu tekstowego wraz z nową zawartością (można użyć także operacji opartych na modelu DOM).
    var newContent = '';
    for (var i = 0; i < responseObject.events.length; i++) { // Iteracja przez obiekt.
      newContent += '<div class="event">';
      newContent += '<img src="' + responseObject.events[i].map + '" ';
      newContent += 'alt="' + responseObject.events[i].location + '" />';
      newContent += '<p><b>' + responseObject.events[i].location + '</b><br>';
      newContent += responseObject.events[i].date + '</p>';
      newContent += '</div>';
    }

    // Uaktualnienie strony nową zawartością.
    document.getElementById('content').innerHTML = newContent;

  }
};

xhr.open('GET', 'data/data.json', true);        // Przygotowanie żądania.
xhr.send(null);                                 // Wykonanie żądania.

Ćwiczenie 4.2.2.

Przygotuj stronę, na której zostaną wyświetlone informacje o Twoich 5 ulubionych piosenkach. Na stronie powinno być 5 przycisków - każdy z tytułem piosenki. Po kliknięciu na przycisk ten staje się nieaktywny a na stronie pojawiają się szczegóły pobrane z pliku (XML lub JSON). Po kliknięciu innego przycisku ten stary jest aktywny a obecnie kliknięty nieaktywny. W tym momencie dane są aktualizowane na stronie bez odświeżania całości. Napisz dwa skrypty języka JavaScript, które będą wczytywać dane, które przygotowałeś(łaś) w poprzednim zadaniu. Pierwszy wczytuje dane XML a drugi dane JSON.

Rozwiązanie wyślij na repozytorium Githuba do katalogu Lesson_04. Skrypty z rozwiązaniem nazwij exercise_422XML.js oraz exercise_422JSON.js.

4.3. Praca z danymi pochodzącymi z innych serwerów

AJAX działa doskonale w przypadku danych pochodzących z Twojego serwera, ale ze względów bezpieczeństwa przeglądarki internetowe nie wczytują odpowiedzi AJAX z innych domen (odpowiedzi będących wynikiem tzw. żądań typu cross-domain). Dostępne są trzy najczęściej stosowane rozwiązania tego problemu:

  • plik proxy w serwerze WWW - utworzenie we własnym serwerze pliku przeznaczonego na dane pochodzące ze zdalnego serwera. Strony w Twojej witrynie będą żądały danych ze wspomnianego pliku w serwerze, który z kolei pobierze odpowiednie dane z serwera zdalnego. Takie rozwiązanie nosi nazwę proxy, ponieważ działa w imieniu innej strony;
  • Cross-Origin-Resource-Sharing - w trakcie komunikacji przeglądarki internetowej i serwera WWW informacje między nimi są przekazywane za pomocą nagłówków HTTP. CORS (ang. Cross-Origin Resource Sharing) oznacza umieszczanie w nagłówkach HTTP dodatkowych informacji, które wskazują przeglądarce i serwerowi WWW sposób prowadzenia komunikacji;
  • JSONP - obejmuje dodanie na stronie elementu <script> odpowiedzialnego za wczytanie danych JSON z innego serwera. Takie rozwiązanie działa, ponieważ nie istnieją ograniczenia dotyczące źródła pochodzenia skryptu w elemencie <script>. Skrypt zawiera wywołanie funkcji, a dane w formacie JSON dostarczane są jako argument funkcji. Wywołana funkcja jest zdefiniowana na stronie żądającej danych i używana jest do ich przetworzenia oraz wyświetlenia.

Zadania domowe

Zadanie 1.

Przygotuj plik o nazwie data.json i wypełnij go danymi na temat swoich ulubionych filmów. W pliku powinno być 5 obiektów, każdy powinien zawierać informacje takie jak: tytuł filmu, gatunek, reżyser, rok nakręcenia, krótki opis fabuły.

Przygotuj kod HTML oraz JavaScript, który wyświetli te dane na stronie w następujący sposób:

  • jest 5 przycisków, każdy ma jako treść tytuł filmu (pobrany z pliku JSON);
  • po kliknięciu danego przycisku pojawiają się wszystkie szczegóły wybranego pliku (te, które są w data.json) - kliknięty przycisk powinien stać się nieaktywny;
  • po kliknięciu innego przycisku dane na temat filmu są aktualizowane bez odświeżania całej strony a poprzedni przycisk staje się znów aktywny - nieaktywny za to staje się aktualnie kliknięty.

Rozwiązanie wyślij na repozytorium Githuba do katalogu Lesson_04. Skrypt z rozwiązaniem nazwij homework_task_01.js, kod strony homework_task_01.html oraz dane - data.json.

Zadanie 2.

Wymień w punktach (jako stronę HTML), jakie Twoim zdaniem są wady i zalety korzystania z formatów danych (HTML, XML, JSON), w których otrzymujemy odpowiedź na żądanie przeglądarki.

Rozwiązanie wyślij na repozytorium Githuba do katalogu Lesson_04. Plik z rozwiązaniem nazwij homework_task_02.html.

Źródła

  • Duckett Jon, JavaScript and JQuery: Interactive Front-End Web Development, przeł. Robert Górczyński, Helion, 2015, ISBN 978-83-283-0126-9.