niedziela, 7 czerwca 2015

[AJAX] Praca z AJAX-em w jQuery

TRUE
172202579730833435
Biblioteka jQuery posiada pełen zestaw metod służących do kompletnej pracy z żądaniami ajaxowymi. Umożliwia wysyłanie i odbieranie żądań zarówno GET jak i POST, automatyzując przy tym bardzo wiele procesów. Korzystanie z AJAX-a w jQuery jest proste i przyjemne - całość sprowadza się do poznania wszystkich metod, jakie dla AJAX-a ten framework oferuje. Metod tych jest dość dużo i poznamy je tutaj za chwilę wraz z odpowiednimi przykładami ich zastosowania. Artykuł nie jest przeznaczony dla początkujących w jQuery, więc aby go w pełni zrozumieć wymagana jest znajomość choćby podstaw frameworka. Ogólny wstęp do mechanizmów AJAX-owych wraz z opisem obiektu XMLHttpRequest znajduje się w poprzednim artykule, który przeczytać można tutaj.

Wczytanie danych do selektora - $.load()

Obsługa AJAX-a za pomocą jQuery jest o tyle łatwiejsza, że jQuery zamyka wszystko w pojedyńczych metodach, które wywołuje się szybciej, aniżeli podczas pisania dłuższego kodu dla obiektu XMLHttpRequest. JQuery ponadto bierze na siebie całą obsługę, w związku z czym programista nie musi się martwić o implementację w wiekowych wersjach przeglądarek. Przyjrzyjmy się małemu porównaniu. Chcąc wczytać AJAX-em za pomocą zwykłego Javascriptu plik ajax.txt do DIV-a o nazwie response, zrobimy to tak:
[code]
<div id="response"></div>
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
  if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
  {
     document.getElementById("response").innerHTML = xmlhttp.responseText;
  }
};
xmlhttp.open("GET", "ajax.txt", true);
xmlhttp.send();
</script>
[/code]
Za pomocą jQuery natomiast zamkniemy powyższe w jednej linijce kodu:
[code]<div id="response"></div>
<script>$("#response").load("ajax.txt");</script>[/code]




Metoda load() z biblioteki jQuery przyjmuje 3 parametry:
[code]$(selektor).load(url, data, callback);[/code]
gdzie:

  • url - adres, z którym chcemy się połączyć
  • data - [opcjonalnie] dodatkowe parametry w żadaniu, np.:

[code]
{
  zmienna1 = "wartość1",
  zmienna2 = "wartość2"
}
[/code]

  • callback - [opcjonalnie] funkcja zwrotna, która zostanie wywołana po wykonaniu metody load()

Wczytanie danych z określonego selektora

Ciekawą możliwością metody load() jest wczytanie danych z określonego selektora.
Przykładowo - poprzednio wczytany został plik ajax.txt, którego zawartość wyglądała tak:
[code]Hello World![/code]
Zmieniając teraz zawartość pliku ajax.txt na następującą:
[code]Hello <p>World!</p>[/code]
A metodę load() wykonując w następujący sposób:
[code]$("#response").load("ajax.txt p");[/code]
Otrzymamy:



Jak widzimy, z pliku ajax.txt wczytana zostaje jedynie zawartość selektora p.
Oczywiście zamiast ogólnego selektora p, podać możemy #identyfikator lub klasę CSS:
[code]
$("#response").load("ajax.txt #div");
$("#response").load("ajax.txt .klasa");
[/code]
Możemy równiez tworzyć zagnieżdżone konstrukcje:
[code]$("#response").load("ajax.txt #div p");[/code]

Funkcja callback dla metody load()
Jako opcjonalny argument dla load() podać możemy funkcję typu callback. Funkcja ta wykona się zawsze po zakończeniu działania metody load().
Funkcja zwrotna przyjmuje 3 parametry:

  • responseTxt - zwróconą za pomocą AJAX-a zawartość
  • statusTxt - informację o statusie żądania, możliwe wartości:
    success
    notmodified
    error
    timeout
    parsererror
  • xhr - zawiera obiekt XMLHttpRequest wykorzystany do wygenerowania żądania


Przykład użycia, który wyświetli nam w DIV-ie o id callback wszystkie dane pobrane przez funkcję zwrotną:
[code]
<div id="response"></div>
<div id="callback"></div>
<input id="button" type="button" value="load" />

<script>
$(document).ready(function() {
  $("#button").click(function() {
    $("#response").load("ajax.txt", function(responseText, statusTxt, xhr) {
      $("#callback").html(
      "<i>responseText:</i> " + responseText + "<hr />" +
      "<i>statusTxt:</i> " + statusTxt + "<hr />" +
      "<i>xhr:</i> " + xhr + "<hr />" +
      "<i>xhr.readyState:</i> " + xhr.readyState + "<hr />" +
      "<i>xhr.status:</i> " + xhr.status);    
    });
  });
});
</script>
[/code]

Wynik:


Żądanie metodą GET - $.get()

O ile metoda load() służy do szybkiego wczytania danej zawartości do określonego elementu jak np. DIV, tak w praktyce wykorzystuje się ją rzadko, a dane przesyła za pomocą metod $.get() i $.post().
Uwaga: dane przesyłane metodą GET mogą być cache'owane przez przeglądarkę, co za tym idzie - czasem po zmianie treści pliku z jakim się łączymy w cache'u może znajdować się wciąż poprzednia wersja pliku.
Metoda $.get() wysyła i odbiera dane z serwera za pomocą żądania HTTP GET, a jej użycie wygląda następująco:
[code]$.get(url, data, callback(data, status, xhr), dataType);[/code]
gdzie:

  • url - adres, z którym chcemy się połączyć
  • data - [opcjonalnie] dodatkowe parametry w żadaniu, np.:

[code]
{
  zmienna1 = "wartość1",
  zmienna2 = "wartość2"
}
[/code]

  • callback - [opcjonalnie] funkcja zwrotna, która zostanie wywołana po wykonaniu metody $.get()
  • dataType - [opcjonalnie] określa typ danych jakich oczekuje się w odpowiedzi od serwera


Skrócone użycie metody $.get() wyglądać może najprościej tak:
[code]$.get(url, callback)[/code]

Funkcja callback przyjmuje tutaj 3 parametry:

  • data - zwrócona przez serwer zawartosc
  • status - informacja o statusie żądania, możliwe wartości:
    success
    notmodified
    error
    timeout
    parsererror  
  • xhr - obiekt XMLHttpRequest użyty w żądaniu


Przykład użycia metody $.get():
[code]
<div id="response"></div>
<div id="callback"></div>
<input id="button" type="button" value="load" />

<script>
$(document).ready(function() {
  $("#button").click(function() {
      $.get("ajax.txt", function(data, status) {
        $("#response").html("<i>data:</i> " + data);
        $("#callback").html("<i>status:</i> " + status);    
      });
  });
});
</script>
[/code]
Wynik :



Jeśli nie podamy parametru dataType to jQuery automatycznie zgaduje jakich danych oczekujemy.
Jeśli jednak chcemy podać ten parametr ręcznie, to poniżej lista wartości jakie można dla dataType podać:

  • xml - dokument XML
  • html - HTML jako plain text
  • text - plain text
  • script - Wykonuje treść odpowiedzi jako kod Javascript, zwraca rezultat jako plain text
  • json - Odbiera żądanie jako JSON, zwracając obiekt Javascriptu

Żądanie metodą POST - $.post()

Wysłanie żądania metodą POST przydaje się podczas przesyłania większych ilości danych i danych z formularzy. Dodatkową funkcjonalnością jest fakt, iż dane przesyłane za pomocą POST nie są cache'owane, tak jak w przypadku GET.
Użycie metody $.post() wygląda następująco:
[code]$.post(url, data, callback(data, status, xhr), dataType);[/code]
gdzie:

  • url - adres, z którym chcemy się połączyć
  • data - [opcjonalnie] dodatkowe parametry w żadaniu, np.:

[code]
{
  zmienna1 = "wartość1",
  zmienna2 = "wartość2"
}
[/code]

  • callback - [opcjonalnie] funkcja zwrotna, która zostanie wywołana się po wykonaniu metody $.post()
  • dataType - [opcjonalnie] określa typ danych jakich oczekuje się w odpowiedzi od serwera


Przykład użycia:
[code]
<div id="response"></div>
<div id="callback"></div>
<input id="button" type="button" value="load" />

<script>
$(document).ready(function() {
  $("#button").click(function() {
      $.post("ajax.php",
      {
        imie = "Jan",
        nazwisko = "Kowalski"
      },
      function(data, status) {
        $("#response").html("<i>data:</i> " + data);
        $("#callback").html("<i>status:</i> " + status);    
      });
  });
});
</script>
[/code]
W powyższym przykładzie zmienne imie i nazwisko zostaną przesłane do pliku ajax.php metodą POST i dostępne po jego stronie jako $_POST['imie'] i $_POST['nazwisko']

Niestandardowe żądanie - $.ajax()

Oba powyższe rodzaje żądań, czyli $.get() i $.post() są tak naprawdę wykonywane za pomocą metody $.ajax(). Czasem jednak zachodzi potrzeba przygotowania niestandardowego żądania, do którego nie wystarczą nam predefiniowane metody $.get() i $.post(). W przypadku wystąpienia takiej konieczności możemy użyć metody $.ajax z własną listą parametrów.
Użycie metody $.ajax() wygląda następująco:
[code]$.ajax({parametr1:wartość1, parametr2:wartość2, ... })[/code]

Lista możliwych do określenia parametrów:

  • async - true lub false, określa czy żądanie ma wykonać się asynchronicznie, domyślnie: true
  • beforeSend(xhr) - funkcja, która wykona się tóż przed wysłaniem żądania do serwera
  • cache - true lub false, określa, czy przeglądarka może cache'ować odpowiedzi z serwera, domyślnie: true
  • complete(xhr, status) - funkcja, która wykona się po pełnym wykonaniu żądania
  • contentType - nagłówek określający rodzaj wysyłanych do serwera danych. Domyślnie: application/x-www-form-urlencoded
  • context - określa zmienną this dla funkcji callback
  • data - określa dane jakie mają być wysłane do serwera
  • dataFilter(data, type) - funkcja operująca na nieprzetworzonej (surowej) odpowiedzi od serwera uzyskanej z obiektu XMLHttpRequest
  • dataType - określa typ oczekiwanych w odpowiedzi danych
  • error(xhr, status, error) - funkcja, która wykona się po wystąpieniu błędu
  • global - true lub false, określa czy używać globalnych zdarzeń dla żądań AJAX-a. Domyślnie: true
  • ifModifiedtrue lub false, określa, czy status success ma być ustawiany jedynie podczas różnicy w otrzymanych od ostatniego żądania danych. Domyślnie: false
  • jsonp - nadpisuje funkcję callback dla żądania JSONP
  • jsonpCallback - funkcja callback dla żądania JSONP
  • password - definiuje hasło używane podczas łączenia z użyciem uwierzytelniania przez HTTP
  • processData - true lub false, określa, czy dane przesyłane w żądaniu mają być dołączane do adresu, domyślnie: true
  • scriptCharset - określa kodowanie znaków dla żądania
  • success(result, status, xhr) - funkcja wywoływana podczas przetworzenia żądania zakończonego sukcesem
  • timeout - określa timeout - w milisekundach dla żądania
  • traditional - true lub false, określa, czy używać standardowej serializacji parametrów
  • type - określa metodę wykonania żądania - GET lub POST
  • url - określa adres do pliku, do którego wysyłamy żądanie
  • username - definiuje nazwę użytkownika używaną podczas łączenia z użyciem uwierzytelniania przez HTTP
  • xhr - funkcja używana podczas tworzenia obiektu XMLHttpRequest

Przykład użycia metody $.ajax może wyglądać następująco:
[code]
<div id="response"></div>
<input id="button" type="button" value="load" />

<script>
$(document).ready(function() {
  $("#button").click(function() {  
      $.ajax({url: "ajax.txt", async: true, type: "GET", success: function(data){
          $("#response").html("<i>data:</i> " + data);
      }});
  });
});
</script>
[/code]

Wynik:


Wartości domyślne - $.ajaxSetup

Warto wiedzieć, że dla wszystkich wyżej wymienionych parametrów możemy ustawić wartości domyślne, które będą używane dla wszystkich wykonywanych żądań.
Służy do tego metoda:
[code]$.ajaxSetup({parametr1:wartość1, parametr2:wartość2, ... })[/code]
Użycie zatem identyczne jak przy metodzie $.ajax().

Funkcje wykonywane dla określonych stanów - Complete, Error, Send, Start, Stop, Success

W jQuery istnieje możliwość zdefiniowania własnych funkcji, które będą wywoływane podczas określonego stanu związanego z żądaniem.
Możemy np. określić tutaj animację, która będzie wyświetlana podczas ładowania żądania, lub komunikaty o stanie żądania.

Metoda ajaxComplete()

Za jej pomocą definiujemy własną funkcję, która wykona się w momencie zakończenia przetwarzania żądania.
[code]$(document).ajaxComplete(function(event,xhr,options))[/code]
gdzie:

  • event- przechowuje obiekt zdarzenia
  • xhr - przechowuje obiekt XMlHttpRequest użyty w żądaniu
  • options - przechowuje wartości parametrów użytych w żądaniu

Przykład użycia:
[code]
<div id = "status"></div>
<script>
$(document).ajaxComplete(function() {
    $("#status").html("Wykonywanie żądania zostało zakończone!");
});
</script>
[/code]

Metoda ajaxError()

Za jej pomocą definiujemy własną funkcję, która wykona się w momencie wystąpienia błędu.
[code]$(document).ajaxError(function(event,xhr,options, exception))[/code]
gdzie:

  • event- przechowuje obiekt zdarzenia
  • xhr - przechowuje obiekt XMlHttpRequest użyty w żądaniu
  • options - przechowuje wartości parametrów użytych w żądaniu
  • exception - przechowuje wyjątek, który wyrzucił Javascript

Przykład użycia:
[code]
<div id = "status"></div>
<script>
$(document).ajaxError(function() {
    $("#status").html("Wystapił błąd!");
});
</script>
[/code]

Metoda ajaxSend()

Za jej pomocą definiujemy własną funkcję, która wykona się tóż przed wysłaniem żądania.
[code]$(document).ajaxSend(function(event, xhr, options))[/code]
gdzie:

  • event- przechowuje obiekt zdarzenia
  • xhr - przechowuje obiekt XMlHttpRequest użyty w żądaniu
  • options - przechowuje wartości parametrów użytych w żądaniu

Przykład użycia:
[code]
<div id = "status"></div>
<script>
$(document).ajaxSend(function(event, xhr, options) {
    $("#status").html("Właśnie wysyłam żądanie do: " + options.url);
});
</script>
[/code]

Metoda ajaxStart()

Za jej pomocą definiujemy własną funkcję, która wykona się podczas rozpoczęcia przetwarzania żądania.
[code]$(document).ajaxStart(function())[/code]
Przykład użycia:
[code]
<div id = "status"></div>
<script>
$(document).ajaxStart(function() {
    $("#status").html("Ładowanie...czekaj...");
});
</script>
[/code]

Metoda ajaxStop()

Za jej pomocą definiujemy własną funkcję, która wykona się po zakończeniu wykonania WSZYSTKICH żądań.
[code]$(document).ajaxStop(function())[/code]
Przykład użycia:
[code]
<div id = "status"></div>
<script>
$(document).ajaxStop(function() {
    $("#status").html("Wszystkie żądania zostały wykonane!");
});
</script>
[/code]

Metoda ajaxSuccess()

Za jej pomocą definiujemy własną funkcję, która wykona się po zakończeniu przetwarzania żądania zakończonego sukcesem.
[code]$(document).ajaxSuccess(function())[/code]
Przykład użycia:
[code]
<div id = "status"></div>
<script>
$(document).ajaxSuccess(function() {
    $("#status").html("Żądanie wykonane z sukcesem!");
});
</script>
[/code]

Serializacja parametrów w żądaniu - $.param()

Jeśli chcemy przesłać w adresie żądania np. obiekt Javascripu lub tablicę, musimy taki typ zserializować.
Dopiero po serializacji możemy dołączyć go do adresu URL.
Przykład użycia:
[code]
<div id="result"></div>

<script>
$(document).ready(function() {
  bookObj = new Object();
  bookObj.title = "Hobbit";
  bookObj.author = "Tolkien";
  var book_serialized = $.param(bookObj);
  var url = "ajax.php?" + book_serialized;
  $("#result").text(url); //Wynik: ajax.php?title=Hobbit&author=Tolkien
});
</script>
[/code]

Serializacja formularza - $.serialize()

Jeśli chcemy przesłać dane z formularza, to musimy dokonać serializacji jego pól (np. wartości wszystkich inputów, textarea itd.) Służy do tego metoda $.serialize(). Tworzy ona zserializowany ciąg tekstowy zawierający wartości pól formularza.
Jako selektor możemy podać cały formularz, lub tylko określone pole/pola.

Przykład użycia:
[code]
<form action="">
  Book Title: <input type="text" name="title" value="Hobbit"><br>
  Book Author: <input type="text" name="author" value="Tolkien"><br>
</form>
<input id="button" type="button" value="serialize" />
<div id="result"></div>

<script>
$(document).ready(function() {
  $("#button").click(function() {
    var form_serialized = $("form").serialize();
    $("#result").text(form_serialized);
   });
});
</script>
[/code]

Wynik:


Serializacja formularza do tablicy - $.serializeArray()

Za pomocą jQuery możemy zserializować formularz (lub określone jego pola) do postaci tablicy.
Służy do tego metoda $.serializeArray(). Tworzy ona zserializowaną tablicę zawierającą wartości pól formularza. Do wartości takich odwołujemy się poprzez: pole.name i pole.value.

Przykład użycia:
[code]
<form action="">
  Book Title: <input type="text" name="title" value="Hobbit"><br>
  Book Author: <input type="text" name="author" value="Tolkien"><br>
</form>
<input id="button" type="button" value="serializeArray" />
<div id="result"></div>

<script>
$(document).ready(function() {
  $("#button").click(function() {
    var form_to_array = $("form").serializeArray();
    $.each(form_to_array, function(i, pole){
        $("#result").append(pole.name + ": " + pole.value + " ");
    });      
   });
});
</script>
[/code]

Wynik:


Pobieranie danych JSON - $.getJSON()

Do pobierania przez AJAX danych zwracanych w formacie JSON służy metoda $.getJSON().
Ogromnym atutem jest fakt, iż dane pobierane za pomocą tej metody lądują bezpośrednio w javascriptowym obiekcie.
Użycie metody $.getJSON() wygląda następująco:
[code]$(selektor).getJSON(url, data, success(data, status, xhr))[/code]
gdzie:

  • url - adres, z którym chcemy się połączyć
  • data - [opcjonalnie] dodatkowe parametry w żadaniu, np.:

[code]
{
  zmienna1 = "wartość1",
  zmienna2 = "wartość2"
}
[/code]

  • success - [opcjonalnie] funkcja zwrotna, która zostanie wywołana po prawidłowym przetworzeniu JSON-a.

Pozostałe stany obsłużyć możemy następująco (łącząc je łańcuchowo):
[code]
$.getJSON("ajax.json", function() {
  alert("success");
})
.done(function() { alert("done!"); })
.success(function() { alert("success!"); })
.error(function() { alert("error!"); })
.fail(function() { alert("fail!"); })
.complete(function() { alert("complete!"); });
[/code]

plik ajax.json:
[code]
{
  "books": [
 
    { "title" : "Hobbit", "author" : "Tolkien" },
    { "title" : "Potop", "author" : "Sienkiewicz" },
    { "title" : "Solaris", "author" : "Lem" }
  ]
}
[/code]

Przykład użycia #1:
[code]
<input id="button" type="button" value="loadJSON" />
<div id="result"></div>
<script>
$(document).ready(function() {
  $("#button").click(function() {  
      var i, c;    
      $.getJSON("ajax.json").done(function(json) {
        c = json.books.length;  
        for(i = 0; i < c; i++)
        {    
          $("#result").append(i + ") " + json.books[i].title + " <br />");
        }
      });
   });
});
</script>
[/code]

Wynik:



Przykład użycia #2:
[code]
<input id="button" type="button" value="loadJSON" />
<div id="result"></div>
<script>
$(document).ready(function() {
  $("#button").click(function() {  
    $.getJSON("ajax.json", function(result) {          
        $.each(result, function(key, field){
          var i, c;
          $("#result").append("<b>" + key + ":</b> <br /> ");
          c = field.length;
          for(i = 0; i < c; i++)
          {
             $("#result").append(i + ") " + field[i].title + " | " + field[i].author + "<br /> ");
          }        
        });
    });
  });
});
</script>
[/code]

Wynik:


Pobieranie danych z Javascriptu - $.getScript()

Bardzo ciekawą metodą jest metoda $.getScript(). Pobiera ona w odpowiedzi kod Javascript, wykonuje go, a następnie zwraca jego wynik w postaci stringu.
Użycie metody wygląda tak:
[code]$(selektor).getScript(url, success(response, status))[/code]
gdzie:

  • url - adres do pliku .js, z którym chcemy się połączyć
  • success - [opcjonalnie] funkcja zwrotna, która zostanie wywołana po prawidłowym przetworzeniu JSON-a.

Argumenty funkcji zwrotnej success:

  • response - przechowuje odpowiedź zwróconą do żądania
  • status - informacja o statusie żądania, możliwe wartości:
    success
    notmodified
    error
    timeout
    parsererror  
Zobaczmy na przykładach:

plik ajax.js:
[code]
var a, b, c;

a = 2;
b = 9;
c = a + b;

alert(a + "+" + b + "=" + c);

function testJS(a, b)
{
 var c = a + b;
 alert(a + "+" + b + "=" + c);
}
[/code]

Przykład #1:
plik z wywołaniem żądania AJAX
[code]
<input id="button" type="button" value="loadJSON" />
<script>
$(document).ready(function() {
  $("#button").click(function() {    
    $.getScript("ajax.js");
  });
});
</script>
[/code]

Wynik:



Przykład #2:
plik z wywołaniem żądania AJAX
[code]
<input id="button" type="button" value="loadJSON" />
<script>
$(document).ready(function() {
  $("#button").click(function() {    
    $.getScript("ajax.js", function() {    
      testJS(12, 7);
    });
  });
});
</script>
[/code]

Wynik:



Jak widać, wykonała się funkcja testJS() pobrana za pomocą AJAX-a z zewnętrznego pliku i dołączona do naszego dokumentu.

Podsumowanie

Przeanalizowaliśmy sobie tutaj większość metod jakich używa się podczas pracy z AJAX-em w jQuery. Jak widać na przykładach, jQuery automatyzuje nam wiele czynności, przez co kod staje się krótszy, niż podczas wykorzystywania "surowego" obiektu XMLHttpRequest. W następnych artykułach wykorzystamy zdobytą wiedzę w nieco bardziej praktycznych zastosowaniach.

1 komentarz:

  1. To moje pierwsze podejście do zrozumienia Ajaxa. Super czytelne przykłady, które zastępują tysiące słów. Dziękuję.

    OdpowiedzUsuń

Masz sugestię? Znalazłeś błąd? Napisz komentarz! :)

webmaester.pl - profesjonalne projektowanie WWW i webaplikacji
webmaester.pl - profesjonalne projektowanie WWW i webaplikacji