jQuery - Ajax

Ostatnia aktualizacja: 08 lutego 2020

Obsługa AJAX w czystym JavaScript nie zawsze była najwygodniejszą sprawą. Jasne - da się szybko przyzwyczaić (a nawet bardzo szybko), ale niektóre czynności mogą być dość dziwne - szczególnie gdy chcemy by działały na każdej przeglądarce.

Możliwe, że właśnie dlatego bardzo często do działania z AJAX wybierane są biblioteki dające "nakładkę". Jedną z najczęściej wybieranych bibliotek jest właśnie jQuery, która bardzo upraszcza działanie z asynchonicznymi połączeniami.

Warto byś przed poniższą lekturą zapoznał się minimum z rozdziałem Callback i Promise (a najlepiej z całym rozdziałem poświęconym Asynchroniczności).

$.ajax()

Funkcja $.ajax(), bo o niej mowa to główna, a zarazem najbardziej rozbudowana funkcja z tutaj omawianych. Ma ona postać:


$.ajax({
    url         : "http://localhost:5000/movies", //gdzie się łączymy
    method      : "post", //typ połączenia, domyślnie get
    dataType    : "json", //typ danych jakich oczekujemy w odpowiedzi

    contentType : "application/json", //gdy wysyłamy dane czasami chcemy ustawić ich typ
    data        : { //dane do wysyłki
        name : "Marcin",
        country : "Polska"
    })
});
method typ połączenia: post, get, delete, put, patch. Domyślnym jest get
dataType typ danych jaki oczekujemy w odpowiedzi. Omówimy go za moment. Jeżeli nie zostanie ustawiony, jQuery spróbuje określić typ danych na podstawie nagłówka Content-Type lub MIME type odpowiedzi. Najczęściej przez nas używanym będzie "json"
data obiekt zawierający przekazywane dane. Jeżeli wykonujemy połączenie typu GET, dane zostaną doklejone do adresu po znaku zapytania (jako query string - np. http://localhost:5000?pet=kot&food=myszka)
contentType typ danych jakie wysyłamy na serwer. Czasami musimy poinformować serwer jakiego typu dane mu ślemy. Domyślnie używany jest "application/x-www-form-urlencoded; charset=UTF-8

W praktyce parametrów możliwych do ustawienia jest o wiele więcej, przy czym najczęściej wystarczą powyższe. Warto jednak przyjrzeć się stronie http://jqapi.com/#p=jQuery.ajax i zapoznać się z kilkoma z nich.

Proste przykłady użycia tej funkcji mogą wyglądać tak jak poniżej:


//pobieranie danych
$.ajax({
    url : "http://localhost:5000/movies",
    dataType : "json"
})

//wysyłanie danych
$.ajax({
    url : "http://localhost:5000/movies",
    method : "post",
    dataType : "json",
    data : {
        name : "Karol",
        age : 13
    }
})

Funkcje zwrotne

Jak wiemy z rozdziału o Ajax, komunikacja zawsze działa na dwa kroki. Wysyłamy dane, i reagujemy na dane, które przychodzą nam z serwera. Aby móc operować na takich zwróconych danych, w przypadku ajax możemy skorzystać w dwóch sposobów.

Po pierwsze możemy użyć funkcji zwrotnych, które są dostępne dla nas w postaci dodatkowych parametrów:


$.ajax({
    url : "...",

    success : function(response) {...}, //gdy wszystko ok
    error : function() {...}, //gdy błąd połączenia
    complete : function() {...} //gdy połączenie zakończyło się (błędnie lub pozytywnie)
});

$.ajax({
    url : "https://jsonplaceholder.typicode.com/posts",
    success : function(response) {
        console.log(response);
    },
    error : function() {
        console.log("Wystąpił błąd z połączeniem");
    }
});

Jak sobie powiedzieliśmy w rozdziale o Promise, zastosowanie funkcji zwrotnych sprawdza się w wielu sytuacjach, a używanie ich nie jest niczym złym. Są jednak momenty, gdzie korzystanie z ich dobrodziejstw może być problematyczne - szczególnie wtedy, gdy wczytywanie jednych danych zależą od wczytania innych danych.

Wraz z wersją 1.5 do jQuery wprowadzono obiekt $.Deferred, który jest odpowiednikiem Promise dla jQuery. Obiekt taki pozwala nam - podobnie do Promise - skorzystać z dodatkowych metod, które pozwalają reagować na zakończenie obietnicy:


//teoretyczna funkcja wczytująca
function load() {
    const d = new $.Deferred();
    setTimeout(function() {
        d.resolve("superWczytaneDane");
    }, 1000);
    return d.promise();
}

promise
    .done(function(result) {...})
    .fail(function() {...})
    .always(function() {...});

Z naszego punktu widzenia najważniejsze jest to, że zarówno $.ajax(), jak i poniżej omawiane skrócone odpowiedniki zwracają taki obiekt, dzięki czemu dla każdej z takich funkcji możemy używać starszych callbacków, ale też omawianych metod.

Są to kolejno:

done() wywoływane po pomyślnym wysłaniu danych do skryptu (kiedy serwer nie zwrócił błędu typu 400, 404, 500 itp)
fail() wywoływane gdy nastąpi błąd w połączeniu - np. 404 - nie ma takiego adresu
always() wywoływane po zakończeniu połączenia - bez względu czy zakończyło się błędem czy sukcesem

Użycie takich funkcji może mieć postać:


$.ajax({
    url : "..."
})
.done(function(res) {
    console.log(res); //dostaliśmy odpowiedź z serwera, wypisujemy ją
})
.fail(function() {
    alert("Wystąpił błąd w połączeniu");
})
.always(function() {
    $(".loading").hide();
});

//wczytywanie danych z serwera
$.ajax({
    url : "http://localhost:3005/users",
    dataType : "json"
})
.done(function(response) {
    console.log(response);
});

//wysyłanie danych na serwer i wypisanie zwracanej odpowiedzi
$.ajax({
    url : "http://localhost:3005/users",
        method : "post",
        data : {
            name : "Marcin",
            pet : "pies"
        },
        dataType : "json"
})
.done(function(response) {
    console.log(response);
})
.fail(function() {
    $(".form-message").html( "Wystąpił błąd" );
})

//wysyłanie danych w formacie json i wypisanie zwracanej odpowiedzi
const ob = {
    name : "Marcin",
    pet : {
        name : "Szamson",
        color : "brown",
        speed : 1000000
    }
};

$.ajax({
    url : "http://localhost:3005/users",
    method : "post",
    contentType : "application/json",
    data : JSON.stringify(ob),
    dataType : "json"
})
.done(function(response) {
    console.log(response);
})
.fail(function() {
    alert("Wystąpił błąd w połączeniu");
})

Skrócone odpowiedniki

jQuery udostępnia nam też kilka funkcji będących alternatywnym, skróconymi wariantami użycia powyżej funkcji $.ajax():

$.get() połączenia typu get
$.post() połączenia typu post
$.getJSON() pobieranie danych w formacie JSON
$.getSCRIPT() pobieranie skryptów Javascript
$element.load() wczytywanie zasobów (np. stron, tekstu itp.)

$.get()

Funkcja $.get() jest skróconym zapisem wywołania funkcji $.ajax() w postaci:


$.ajax({
    url: url,
    method: "get",
    success: function(response) { ... },
    data: { ... }, //opcjonalne - dane do wysłania
});

i służy do wykonywania połączeń typu get. Przykładowe zastosowania tej funkcji mogą mieć postać:


//pobieranie danych
$.get("example.php", function(response){
    console.log("Dane otrzymane: ", response);
});

//pobieranie danych z dodatkowym wysłaniem jakiś danych
$.get("example.php", { page : 1 }, function(response){
    console.log("Dane otrzymane: ", response);
});

//pobieranie danych z wykorzystaniem funkcji done
$.get("example.php", { page : 1})
.done(function(response) {
    console.log(response);
})
.fail(function() {
    alert("Wystąpił błąd w połączeniu");
})
.always(function() {
    $(".loading").hide();
});

$.post()

Funkcja $.post jest skróconym zapisem wywołania funkcji $.ajax w postaci:


$.ajax({
    method: "POST",
    url: url,
    data: { ... },
    success: function(response) { ... },
    dataType: dataType
});

i służy do wykonywania połączeń typu post.

Funkcję tą możemy używać na kilka sposobów:


//używając callback
$.post( "ajax/test.html", function(response) {
    $(".result").html(response);
});

//korzystając z nowych metod
$.post("example.php", {
    name: "Johny",
    surname: "Bravo"
}).done(function(response) {
    console.log("Zapisano pozytywnie: ", response);
});

$.getJSON()

Funkcja $.getJSON() to skrócony zapis konstrukcji:


$.ajax({
    dataType: "json",
    url: url,
    data: data,
    success: function(result) { ... },
});

i służy do pobierania danych typu json. Przykładowe użycie tej funkcji może mieć postać:


$.getJSON("test.json", function(res) {
  res.forEach(el => console.log(el) );
});

Podobnie do poprzednich funkcji możemy tutaj wysyłać dodatkowe dane i używać nowych funkcji zwrotnych:


$.getJSON("test.json", { id : 100})
.done(function(resp) {
    console.log(resp);
})
.fail(function() {
    alert("Wystąpił błąd w połączeniu");
});

$.getScript()

Funkcja $.getSCRIPT() to skrócony zapis kodu:


$.ajax({
    url: url,
    dataType: "script",
    success: function(response) { ... },
});

i służy do wczytania i wykonania skryptu JavaScript. Jej przykładowe użycie może mieć postać:


$.getScript("test.js"); //wczytanie i wykonanie skryptu

I znowu - podobnie jak przy innych funkcjach możemy tutaj wysyłać dodatkowe dane i używać nowych funkcji zwrotnych:


$.getScript("test.js")
.done(function( data, textStatus ) {
    console.log( data ); //zwrócone dane
    console.log( textStatus ); //status wczytania - np. success
})
.fail(function() {
    alert("Wystąpił błąd w połączeniu");
});

$element.load()

Ostatnią z omawianych funkcji jest $element.load(), która jest mniej więcej odpowiednikiem kodu $.get(url, data, success) i służy do wczytywania treści z serwera i umieszczenia jej w jakimś elemencie.

Jej przykładowe użycie może mieć postać:


//wczytuję plik article.html i umieszczam go w div #result
$("#result").load( "article.html" );

//wczytuję plik article.html ale tylko zawartość diva #content
$("#result").load( "article.html #content" );

//wczytuje treść artykułu przekazując dodatkowe dane na serwer - np. id wczytywanego artykułu
$("#result").load( "article.php", { id: 100 } );

//wczytuję dane przekazując dodatkowy parametr
//dodatkowo po wczytaniu danych odpalam funkcję, która pokaże div#result
$("#result").load("feeds.php", { limit: 25 }, function() {
    //funkcja zwrotna odpalana po wczytaniu
    $("#result").slideDown();
});

Wiele połączeń

Bardzo często zdarza się sytuacja, że musimy pobrać dane z wielu miejsc. Przykładowo mamy użytkownika, który ma swoje dane, ale ma też zbiór filmów itp.

Dzięki obiektowi $.Deferred możemy korzystać z dodatkowej metody $.when(deferreds), która odpalana jest w momencie, gdy wszystkie przekazane do niej obietnice zostaną wykonane.


const apiUrl = "http://localhost:5000";
$.when(
    $.ajax(apiUrl + "/userData"),
    $.ajax(apiUrl + "/userMovies"),
    $.ajax(apiUrl + "/userPets")
).done(function(resp1, resp2) {
    //resp1 i resp2 to tablice ze strukturą: [ data, statusText, jqXHR ]
    console.log(res1[0], resp2[0]);
});

function load(endPoint) {
    return $.ajax({
        url : "http://localhost:5000" + endPoint,
        dataType : "json"
    });
}

$.when(load("posts"), load("users"), load("todos"))
    .done(function(response1, response2, response3) {
        console.log(response1); //odpowiedź z 1 ajaxa
        console.log(response2); //odpowiedź z 2 ajaxa
        console.log(response3); //odpowiedź z 3 ajaxa
    });

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem. Aha - i ta strona korzysta z ciasteczek.

Menu