Obiekt Request PDF Drukuj
  • Wysyłanie zapytań
  • Obsługa odpowiedzi
  • Dodawanie parametrów
  • Wysyłanie formularzy
  • Grupowanie zapytań
  • Ponawianie wysyłania zapytań
  • Wykonywanie skryptów w odpowiedzi
  • Wspólne ustawienia wielu zapytań
  • Odpowiedź w formacie XML
  • Odpowiedź w formacie JSON

Wysyłanie zapytań

Obiekt Request znacznie rozszerza możliwości obiektu XMLHttpRequest, ułatwiając i usprawniając asynchroniczną komunikację z serwerem przy użyciu zapytań AJAX. Przed wysłaniem zapytania musimy utworzyć nowy obiekt Request wywołując funkcję mint.Request. Następnie wykorzystujemy funkcję Send przekazując jako pierwszy parametr adres strony, która ma zostać wywołana na serwerze oraz opcjonalnie jako drugi parametr identyfikator elementu lub element, gdzie wstawiona zostanie odpowiedź. Zasadę działania najlepiej przedstawić na przykładzie - poniższy kod wywołuje po stronie serwera plik o nazwie request.html, a następnie wstawia odebraną odpowiedź (zawartość pliku request.html) do elementu o identyfikatorze response:

function SendRequest() {
    var req = mint.Request();
    req.Send("request.html", "response");
}

Jeśli serwer wymaga uwierzytelnienia, przed wysłaniem zapytania ustaw atrybuty username oraz password.
 
<div id="response"></div>
<button onclick="SendRequest()">Wyślij zapytanie</button>

Możliwe jest wywołanie funkcji mint.Request z czterema argumentami opcjonalnymi: adresem strony, elementem gdzie wstawiona ma zostać odpowiedź oraz dwoma funkcjami zdarzeniowymi, OnSuccess i OnError. W przypadku przekazania tych parametrów, funkcja od razu wyśle zapytanie. Poprzedni przykład z wykorzystaniem tej możliwości będzie wyglądał następująco:

function SendRequest() {
    mint.Request("request.html", "response");

Obsługa odpowiedzi

W przypadku, gdy otrzymaną odpowiedź chcemy w jakiś sposób zmodyfikować przed wstawieniem do elementu lub wykorzystać w zupełnie innym celu bez wstawiania, z pomocą przychodzi funkcja zdarzeniowa OnSuccess wywoływana po pomyślnym odebraniu odpowiedzi. W poniższym przykładzie zamieniamy wszystkie litery w odebranej odpowiedzi (znajdującej się w atrybucie responseText) na duże, zanim zostanie ona wstawiona do odpowiedniego elementu:

function SendRequest() {
    var req = mint.Request();
    
    req.OnSuccess = function() {
        $("response").innerHTML = this.responseText.toUpperCase();
    }
    
    req.Send("request.html");
}

<div id="response"></div>
<button onclick="SendRequest()">Wyślij zapytanie</button>

     

Podobnie jak w poprzednim przykładzie, tutaj również możemy trochę skrócić zapis wykorzystując możliwość przekazania do funkcji mint.Request odpowiednich parametrów:

function OnSuccess() {
     $("response").innerHTML = this.responseText.toLowerCase();
}

function SendRequest() {
    mint.Request("request.html", null, OnSuccess);
}

Dodawanie parametrów

W poprzednich przykładach odbieraliśmy dane z serwera nie wysyłając przy tym żadnych informacji ze strony klienta. Do dodawania parametrów wysyłanych wraz z zapytaniem służy funkcja AddParam, przyjmująca dwa argumenty: nazwę parametru oraz jego wartość. Do obsługi wysłanych parametrów po stronie serwera będziemy potrzebowali jakiegoś języka skryptowego, tutaj wykorzystamy język PHP. W kolejnym przykładzie wysyłamy zawartość pola tekstowego msg, po stronie serwera zamieniamy wszystkie litery na duże, a następnie otrzymany w odpowiedzi zmodyfikowany tekst wstawiamy do elementu response:

function SendRequest() {
    var req = mint.Request();
    req.AddParam("msg", $("msg").value);
    req.Send("request.php", "response");
}

<div id="response"></div>
<input id="msg" type="text" />
<button onclick="SendRequest()">Wyślij informacje</button>

<?php
    echo htmlentities(strtoupper($_GET['msg']));
?>

 

Dzięki temu, że funkcja AddParam zwraca obiekt Request, powyższy zapis można skrócić tworząc "łańcuszek" wywołań funkcji składowych w następujący sposób:

function SendRequest() {
    mint.Request().AddParam("msg", $("msg").value).Send("request.php", "response");
}

W przypadku chęci zmiany pewnych atrybutów w obiekcie Request bez przerywania "łańcucha", możemy wykorzystać funkcję Set wywoływaną z jednym parametrem będącym obiektem zawierającym pary "atrybut: wartość" (możliwe jest również wywołanie funkcji Set z dwoma parametrami, gdzie pierwszy to nazwa atrybutu a drugi to wartość).

Powiedzmy że w poprzednim przykładzie chcemy dodatkowo ustawić atrybuty username oraz password potrzebne do uwierzytelnienia po stronie serwera - kod w tym przypadku zmieni się następująco:

function SendRequest() {
    mint.Request().Set({username: "lorem", password: "ipsum"}).AddParam("msg", $("msg").value).Send("request.php", "response");
}

Wraz z dodatkowymi funkcjami kod staje się mniej czytelny, dlatego metoda tworzenia "łańcuchów" sprawdza się w przypadku prostych zapytań. Przy bardziej rozbudowanych zapytaniach, gdzie ustawiamy kilka atrybutów lub dodajemy kilka parametrów, proponuję "klasyczny" zapis z wykorzystaniem zmiennej na obiekt Request.

Wysyłanie formularzy

W poprzednim przykładzie wysyłaliśmy informację wprowadzoną przez użytkownika dodając ją jako parametr w adresie. Pole było jedno więc musieliśmy dodać tylko jeden parametr, co jednak jeśli pól formularza będzie znacznie więcej? Z pomocą przychodzi funkcja SendForm wysyłająca automatycznie wartości wszystkich pól formularza przekazanego jako pierwszy argument. Drugim argumentem jest adres gdzie wysłane ma zostać zapytanie, w przypadku braku tego argumentu wykorzystany zostanie adres ustawiony jako atrybut action w elemencie formularza. Jako trzeci argument możemy zaznaczyć metodę wysłania formularza, jeśli pominiemy ten parametr formularz zostanie wysłany zgodnie z metodą ustawioną w atrybucie method w elemencie <form> lub "POST" w przypadku jego braku.

Domyślnie pola formularza po wysłaniu nie są resetowane, możemy zmienić to zachowanie ustawiając atrybut resetForm na true. Ponadto pola formularza podczas wysyłania zapytania są domyślnie blokowane, to zachowanie możemy również zmienić ustawiając atrybut disableForm na false.

function SendRequest() {
    var req = mint.Request();
               
    req.OnSuccess = function() {
        $("response").innerHTML = this.responseText;
    }
               
    req.SendForm("form");
}

<form id="form" method="POST" action="form_post.php">
    Pole tekstowe:
        <input name="text" type="text" /><br />
    Checkbox:
        <input name="checkbox" type="checkbox" /><br />
    Radio:
        <input name="radio" type="radio" value="Lorem" checked /> Lorem
        <input name="radio" type="radio" value="Ipsum" /> Ipsum
</form>

<div id="response"></div>
<button onclick="SendRequest()">Wyślij formularz</button>

<?php

    echo"<b>Pole tekstowe: </b>{$_POST['text']}<br />";
    echo"<b>Checkbox: </b>";
   
    if(isset($_POST['checkbox']))
        echo "zaznaczono";
    else
        echo "niezaznaczono";
       
    echo"<br />";
    echo"<b>Radio: </b>{$_POST['radio']}";

?>

Grupowanie połączeń

Wysyłając kilka zapytań jednocześnie nie mam kontroli nad tym, w jakiej kolejności się one zakończą. W sytuacji, gdy chcemy wykonać pewne operacje dopiero po zakończeniu wszystkich wysłanych zapytań, powinniśmy skorzystać z grupowania połączeń. Do tworzenia grup połączeń służy funkcja mint.RequestGroup zwracająca obiekt RequestGroup. Obiekt ten zawiera jedną funkcję składową Add, wywoływaną z jednym parametrem jakim jest obiekt Request który chcemy dodać do grupy, oraz dwie funkcje zdarzeniowe OnStart oraz OnDone. Pierwsza z tych funkcji wywoływana jest po wysłaniu pierwszego zapytania należącego do grupy, natomiast druga funkcja wywoływana jest po odebraniu odpowiedzi od wszystkich wysłanych zapytań należących do grupy.

function Activate(id) {
    $(id).className = "reqDone";
}

function SendGroup() {
    var group = mint.RequestGroup();
    
    var req1 = mint.Request().Set("OnSuccess", function() {Activate("req1_status")});
    var req2 = mint.Request().Set("OnSuccess", function() {Activate("req2_status")});
    var req3 = mint.Request().Set("OnSuccess", function() {Activate("req3_status")});
   
    group.Add(req1, req2, req3);
   
    group.OnDone = function() {
        $("group_status").className = "groupDone";
    }
   
    setTimeout(function() {req1.Send("request.php")}, 1000);
    setTimeout(function() {req2.Send("request.php")}, 2000);
    setTimeout(function() {req3.Send("request.php")}, 3000);

<div id="req1_status">Status pierwszego połączenia</div>
<div id="req2_status">Status drugiego połączenia</div>
<div id="req3_status">Status trzeciego połączenia</div>

<div id="group_status">Status grupy</div>

<button onclick="SendGroup()">Wyślij zapytania</button>

Ponawianie wysyłania zapytań

Czasami, szczególnie gdy serwer jest obciążony, zapytanie może nie dotrzeć do swego celu - w takim przypadku najlepiej spróbować ponownie wysłać zapytanie. Obiekt Request zawiera mechanizm automatycznego ponawiania wysłania zapytania podczas zbyt długiego oczekiwania na odpowiedź. Związane są z tym dwa atrybuty w obiekcie Request: retryNum określający ilość prób, po przekroczeniu której przerwane zostaną dalsze próby wysłania zapytania, oraz timeout określający ilość czasu, który musi minąć aby ponowić próbę. Domyślnie ustawione są 3 próby po 5 sekund. Możemy również wykonać pewne operacje (np. poinformować użytkownika o problemie z połączeniem) wykorzystując funkcje zdarzeniowie OnTimeout, OnRetry oraz OnAbort. Pierwsza z nich wywoływana jest po upłynięciu określonego czasu oczekiwania na odpowiedź, druga podczas kolejnej próby a ostatnia po wykorzystaniu wszystkich prób.

function SendRequest() {
    var req = mint.Request();
    
    req.OnAbort =  function() {
        alert("Serwer ma problemy z odebraniem zapytania. Spróbuj ponownie późnej.");
    }
    
    req.Send("request.php");
}

W przypadku wysłania zapytania na nieistniejący adres, wykonana zostanie funkcja OnError zamiast OnAbort z tego względu, że problem tkwi w wysyłanym zapytaniu, a nie po stronie serwera.

Wykonywanie skryptów w odpowiedzi

Obiekt Request umożliwia również wykonywanie skryptów znajdujących się w odebranej odpowiedzi, domyślnie możliwość ta jest wyłączona - aby ją włączyć wystarczy ustawić atrybut evalScripts na true. Wykonywane będą wtedy zarówno skrypty znajdujące się pomiędzy znacznikami <script></script> jak i te ładowane z zewnętrznych plików, w poniższym przykładzie wykonane zostaną skrypty znajdujące się w pliku script.js jak i funkcja alert wyświetlająca komunikat.

<script type="text/javascript src="script.js"></script>
<script type="text/javascript">
    alert("Skrypt załadowany dynamicznie.");
</script> 

Jeśli zamierzamy natomiast załadować skrypt bezpośrednio z pliku .js (przykładowo wysyłamy zapytanie do pliku "script.js") należy ustawić atrybut evalResponse na true aby załadowany skrypt został wykonany.

Wspólne ustawienia dla wielu zapytań

Dzięki funkcji Set możliwe jest wykorzystanie tych samych ustawień w wielu obiektach Request, wystarczy utworzyć obiekt zawierający pary "atrybut: wartość" a następnie przekazać utworzony obiekt do funkcji Set każdego zapytania, w którym te ustawienia zamierzamy wykorzystać.

function OnLoad() {
    var config = {
        username: "user",
        password: "pass",
        encoding: "iso-8859-2",
        getJSON: true
    }
    
    mint.Request().Set(config).Send("first_request.php");
    mint.Request().Set(config).Send("second_request.php");
}

Odpowiedź w formacie XML

W sytuacji gdy odpowiedź wysyłana jest w formacie XML, atrybut responseXML zawiera sparsowany dokument przesłany w odpowiedzi. Poniższy przykład pokazuje w jaki sposób obsłużyć taką odpowiedź:

function SendRequest() {
    var req = mint.Request();

    req.OnSuccess = function() {
        var items = this.responseXML.getElementsByTagName("item");
        
        for(var i = 0; i < items.length; ++i) {
            $("response").innerHTML += items[i].firstChild.data + "<br />";
        }
    }
    
    req.Send("request.xml");
}

<div id="response"></div>
<button onclick="SendRequest()">Wyślij zapytanie</button>

<doc>
    <item>Lorem</item>
    <item>Ipsum</item>
    <item>Dolor</item>
    <item>Sit Amet</item>
</doc> 

 



Odpowiedź w formacie JSON

W celu odebrania odpowiedzi w formacie JSON należy ustawić atrybut getJSON na true, obiekt zawierający odebrane dane znajdować będzie się w atrybucie responseJSON. W przykładzie poniżej odbieramy zestaw danych w formacie JSON a następnie umieszczamy je w tabeli "grid":

[
    {
        name: "Lorem",
        mail: "lorem@mail.com"
    },
    {
        name: "Ipsum",
        mail: "ipsum@mail.com"
    },
    {
        name: "Dolor",
        mail: "dolor@mail.com"
    },
    {
        name: "Sit Amet",
        mail: "sitAmet@mail.com"
    }
]

var grid;

function GetUsers() {
    var req = mint.Request();
   
    req.OnSuccess = function() {
        for(var i = 0; i < this.responseJSON.length; ++i) {
            grid.InsertRow(this.responseJSON[i].name, this.responseJSON[i].mail);
        }
    }
   
    req.getJSON = true;
    req.Send("users.txt");
}

function OnLoad() {
    grid = mint.gui.CreateGridWidget("grid");
}

<button onclick="GetUsers()">Pobierz listę użytkowników</button>
<table id="grid"></table>


 
« poprzedni artykuł   następny artykuł »