Lekcja 13: AJAX w jQuery - Wprowadzenie i $.ajax()
AJAX (Asynchronous JavaScript and XML) to technika pozwalająca na komunikację z serwerem w tle, bez konieczności przeładowywania całej strony. jQuery znacznie upraszcza wykonywanie zapytań AJAX, oferując zestaw wygodnych metod, z których najbardziej podstawową i elastyczną jest $.ajax()
.
Podstawy AJAX
Dzięki AJAX, strona internetowa może:
- Wysyłać dane do serwera (np. z formularza) bez przeładowania.
- Pobierać dane z serwera (np. w formacie JSON, XML, HTML) i aktualizować fragmenty strony.
- Tworzyć bardziej dynamiczne i responsywne interfejsy użytkownika.
Metoda $.ajax()
$.ajax()
to niskopoziomowa, ale bardzo konfigurowalna metoda do wykonywania asynchronicznych zapytań HTTP. Przyjmuje jeden argument – obiekt konfiguracyjny z wieloma opcjami.
Podstawowa składnia:
$.ajax({
url: "adres_url_serwera", // Adres URL, do którego wysyłane jest zapytanie
method: "GET", // Metoda HTTP (GET, POST, PUT, DELETE, etc.) - domyślnie GET
dataType: "json", // Oczekiwany typ danych odpowiedzi (np. "json", "xml", "html", "text")
data: { klucz1: "wartosc1", klucz2: "wartosc2" }, // Dane do wysłania (dla POST, PUT)
// Funkcje zwrotne (callbacki)
beforeSend: function(xhr) {
// Wykonywane przed wysłaniem zapytania
console.log("Wysyłanie zapytania...");
// Można np. pokazać wskaźnik ładowania
},
success: function(data, textStatus, xhr) {
// Wykonywane, gdy zapytanie zakończy się sukcesem
console.log("Sukces! Otrzymano dane:", data);
// `data` zawiera przetworzone dane odpowiedzi (np. obiekt JSON)
},
error: function(xhr, textStatus, errorThrown) {
// Wykonywane, gdy wystąpi błąd
console.error("Błąd AJAX:", textStatus, errorThrown);
console.error("Status:", xhr.status, "Odpowiedź:", xhr.responseText);
},
complete: function(xhr, textStatus) {
// Wykonywane zawsze po zakończeniu zapytania (po success lub error)
console.log("Zapytanie zakończone.");
// Można np. ukryć wskaźnik ładowania
}
});
Najważniejsze Opcje Konfiguracyjne $.ajax()
:
url
: Adres URL zasobu na serwerze.method
(lubtype
): Metoda HTTP (GET
,POST
,PUT
,DELETE
itp.).dataType
: Typ danych, jakiego oczekujemy od serwera. jQuery spróbuje automatycznie sparsować odpowiedź do tego formatu (np. string JSON do obiektu JavaScript).data
: Dane do wysłania na serwer. Mogą być obiektem JavaScript (jQuery przekształci go na query string dla GET lub dane formularza dla POST) lub stringiem.contentType
: Typ zawartości wysyłanych danych (np."application/json"
,"application/x-www-form-urlencoded; charset=UTF-8"
- domyślny).timeout
: Czas w milisekundach, po którym zapytanie zostanie uznane za nieudane (timeout).cache
: Czy przeglądarka powinna cache'ować odpowiedzi na zapytania GET (domyślnietrue
, alefalse
dladataType: 'script'
i'jsonp'
).async
: Czy zapytanie ma być asynchroniczne (domyślnietrue
). Ustawienie nafalse
sprawia, że przeglądarka czeka na odpowiedź, blokując interfejs użytkownika (zdecydowanie niezalecane!).
Przykład: Pobieranie danych JSON
Załóżmy, że pod adresem /api/produkty
serwer zwraca listę produktów w formacie JSON:
// Pobierz listę produktów po kliknięciu przycisku
$("#pobierz-produkty").on("click", function() {
$.ajax({
url: "/api/produkty", // Zastąp prawdziwym adresem URL
method: "GET",
dataType: "json",
beforeSend: function() {
$("#lista-produktow").html("Ładowanie...");
},
success: function(produkty) {
let listaHtml = "";
produkty.forEach(function(produkt) {
listaHtml += `- ${produkt.nazwa} - ${produkt.cena} zł
`;
});
listaHtml += "
";
$("#lista-produktow").html(listaHtml);
},
error: function() {
$("#lista-produktow").html("Nie udało się pobrać produktów.
");
},
complete: function() {
console.log("Zakończono próbę pobrania produktów.");
}
});
});
Przykład: Wysyłanie danych POST
Wysyłanie danych z formularza na serwer:
$("#formularz-kontaktowy").on("submit", function(event) {
event.preventDefault(); // Zatrzymaj domyślne wysyłanie formularza
let daneFormularza = $(this).serialize(); // Zbierz dane formularza jako query string
$.ajax({
url: "/api/kontakt", // Zastąp prawdziwym adresem URL
method: "POST",
data: daneFormularza,
dataType: "json", // Oczekujemy odpowiedzi JSON od serwera
beforeSend: function() {
$("#status-wysylania").text("Wysyłanie...").show();
},
success: function(odpowiedz) {
if (odpowiedz.sukces) {
$("#status-wysylania").text("Wiadomość wysłana!").css("color", "green");
$("#formularz-kontaktowy")[0].reset(); // Wyczyść formularz
} else {
$("#status-wysylania").text("Błąd: " + odpowiedz.wiadomosc).css("color", "red");
}
},
error: function() {
$("#status-wysylania").text("Błąd serwera. Spróbuj ponownie.").css("color", "red");
}
});
});
Zadanie praktyczne
Użyj publicznego API, np. JSONPlaceholder (https://jsonplaceholder.typicode.com/users/1
), aby pobrać dane pojedynczego użytkownika.
Stwórz plik HTML z przyciskiem "Pobierz Użytkownika" i pustym div-em z ID "dane-uzytkownika".
Używając $.ajax()
:
- Po kliknięciu przycisku, wykonaj zapytanie GET do
https://jsonplaceholder.typicode.com/users/1
. - Ustaw oczekiwany
dataType
na"json"
. - W funkcji
success
, wyświetl imię (name
), email (email
) i miasto (address.city
) użytkownika w div-ie "dane-uzytkownika". - W funkcji
error
, wyświetl komunikat błędu w tym samym div-ie. - W funkcji
beforeSend
, wyświetl tekst "Ładowanie danych użytkownika..." w div-ie. - W funkcji
complete
, wypisz w konsoli "Zakończono zapytanie o użytkownika.".
Pokaż rozwiązanie
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test $.ajax()</title>
</head>
<body>
<button id="pobierz-usera">Pobierz Użytkownika</button>
<div id="dane-uzytkownika" style="margin-top: 10px; border: 1px solid #ccc; padding: 10px; min-height: 50px;">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>
$(function() {
$("#pobierz-usera").on("click", function() {
$.ajax({
url: "https://jsonplaceholder.typicode.com/users/1",
method: "GET",
dataType: "json",
beforeSend: function() {
$("#dane-uzytkownika").html("Ładowanie danych użytkownika...");
},
success: function(user) {
let userInfo = `<h3>${user.name}</h3>`;
userInfo += `<p>Email: ${user.email}</p>`;
userInfo += `<p>Miasto: ${user.address.city}</p>`;
$("#dane-uzytkownika").html(userInfo);
},
error: function(xhr, status, error) {
$("#dane-uzytkownika").html("<p style='color: red;'>Błąd pobierania danych: " + status + " - " + error + "</p>");
},
complete: function() {
console.log("Zakończono zapytanie o użytkownika.");
}
});
});
});
</script>
</body>
</html>
Zadanie do samodzielnego wykonania
Użyj API JSONPlaceholder dla postów (https://jsonplaceholder.typicode.com/posts
).
Stwórz formularz z jednym polem tekstowym (textarea
) dla treści posta i przyciskiem "Dodaj Post". Dodaj też div z ID "status-posta".
Używając $.ajax()
:
- Po wysłaniu formularza (przechwyć zdarzenie
submit
i użyjevent.preventDefault()
): - Wykonaj zapytanie POST do
https://jsonplaceholder.typicode.com/posts
. - Wyślij dane w obiekcie
data
, np.{ title: 'Mój nowy post', body: trescZPolaTextarea, userId: 1 }
. - Ustaw
dataType
na"json"
. - W funkcji
success
, wyświetl w div-ie "status-posta" komunikat "Post dodany pomyślnie! ID: [ID zwrócone przez API]". API zwróci obiekt z dodanym postem, w tym jego nowe ID. - W funkcji
error
, wyświetl komunikat błędu.
Uwaga: JSONPlaceholder symuluje dodawanie danych, faktycznie ich nie zapisuje, ale zwraca obiekt tak, jakby post został dodany (zazwyczaj z ID 101).
FAQ - AJAX w jQuery ($.ajax()
)
Czym różni się $.ajax()
od $.get()
i $.post()
?
$.get()
i $.post()
to uproszczone metody-skróty dla typowych zapytań GET i POST. Są one zbudowane na bazie $.ajax()
i oferują mniej opcji konfiguracyjnych, ale są szybsze w użyciu dla prostych przypadków. $.ajax()
daje pełną kontrolę nad wszystkimi aspektami zapytania.
Co to jest CORS (Cross-Origin Resource Sharing)?
CORS to mechanizm bezpieczeństwa przeglądarek, który ogranicza możliwość wykonywania zapytań AJAX do innych domen (innych niż ta, z której pochodzi strona). Aby zapytanie do innej domeny się powiodło, serwer docelowy musi wysłać odpowiednie nagłówki HTTP (np. Access-Control-Allow-Origin
), zezwalające na takie zapytanie. JSONPlaceholder wysyła te nagłówki, dlatego możemy go używać w przykładach.
Jak obsługiwać różne kody statusu HTTP w error
?
Obiekt xhr
(XMLHttpRequest) przekazywany do funkcji error
zawiera właściwość status
z kodem odpowiedzi HTTP (np. 404, 500). Możesz użyć instrukcji if
lub switch
, aby zareagować inaczej w zależności od kodu błędu: if (xhr.status === 404) { ... } else if (xhr.status === 500) { ... }
.
Czy muszę używać wszystkich callbacków (beforeSend
, success
, error
, complete
)?
Nie, wszystkie funkcje zwrotne są opcjonalne. Najczęściej używa się success
do obsługi pomyślnej odpowiedzi i error
do obsługi błędów. beforeSend
i complete
są przydatne np. do zarządzania wskaźnikami ładowania.
Co jeśli serwer nie odpowiada (timeout)?
Jeśli ustawisz opcję timeout
i serwer nie odpowie w określonym czasie, zostanie wywołana funkcja error
. Wartość textStatus
będzie wtedy zazwyczaj równa "timeout"
.