W dzisiejszym postem zakończymy omawianie zagadnień związanych z dostępem i zabezpieczaniem danych. Zgodnie z tytułem tego wpisu przedstawię na czym polega serializacja danych JavaScript: omówię więc binarny format danych (JSON i XML omówiłem już w poprzednim wpisie); przyjrzymy się metodzie ‘serialize’ dostępnej w ramach biblioteki jQuery, a także dowiemy się jak wysłać formularz z poziomu języka JavaScript; spojrzymy także jeszcze raz na obiekt ‘XMLHttpRequest’, tym razem w kontekście wysyłania danych, a także omówimy sposób na kodowanie adresów URI oraz danych formularzy. A więc do dzieła!

Binarny format danych w JavaScript

W przeszłości język JavaScript operowanie na danych binarnych, można było jedynie symulować traktując dane jako string i używając metody ‘charCodeAt’ do czytania bajtów z bufora danych. Niestety był to proces powolny z powodu potrzeby wykonywania wielu konwersji danych. Dopiero wprowadzenie do języka JavaScript typowanych tablic (ang. typed arrays) pozwoliło na dostęp do danych binarnych w o wiele bardziej wydajny sposób.

Omawiany mechanizm, wprowadza dwa nowe rodzaje obiektów: bufor czyli klasa ‘ArrayBuffer’ oraz widoku (ang. view - spotkałem się też z tłumaczeniem perspektywa) czyli klasa ‘ArrayBufferView’ i jej pochodne, pozwalające definiować tablice wartości konkretnego typu. Oprócz tego mamy jeszcze możliwość stosowania klasy ‘DataView’ pozwalającej na dostęp dowolny do danych.

Znając teorię, przejdźmy do przykładu użycia nowego rodzaju tablic:

// bufor na 32 bajty
var buffer = new ArrayBuffer(32);
// deklaracja tablicy liczb całkowitych w obrebie bufora
var view = new Int32Array(buffer);

// wypelnienie tablicy
for(var i = 0; i < view.length; i++ ) {
    view[i] = i;
}

Widać od razu zasadę działania opisywanego mechanizmu - definiowany jest bufor pamięci przeznaczony na dane. Następnie tworzony jest obiekt widoku/tablicy, dzięki któremu mamy dostęp do uprzednio zdefiniowanego bufora. W naszym przypadku zdefiniwany został bufor 32 bajtów, dzięki czemu uzyskaliśmy tablicę ośmiu liczb całkowitych. Widzimy też, że klasa widoku posiada interfejs, dzięki któremy możemy po nim iterować jak po normalnej tablicy (właściwość ‘length’ oraz odwołania do poszczegółnych wartości widoku za pomocą operatora indexera []).

To co jest ciekawe w przypadku bufora danych, jest to, że może on zawierać całe struktury danych różnego typu. Dostęp do nich odbywa się za pomocą różnych widoków - w ich konstruktorze, oprócz bufora podaje się bajt początkowy oraz ilość bajtów do odczytania. Spójrzmy na przykład:

var buffer = new ArrayBuffer(24);

// ... zapis danych do bufora ...

var id = new Uint32Array(buffer, 0, 1);
var userName = new Uint8Array(buffer, 4, 16);
var amount = new Float32Array(buffer, 20, 1);

To wszystko pokazuje, że mechanizm ten może być rzeczywiście przydatne do przesyłania danych pomiędzy klientem a WebService’ami itp. (opis klasy ‘DataView’ pomijam celowo, ponieważ z tego co wiem, można z niego korzystać jedynie w przeglądarce Firefox).

Metoda ‘serialize’ biblioteki jQuery oraz form.submit()

Opisywana funkcja, pozwala na odczyt wartości formularza, i przekonwertowanie go na “query string” (czyli na tekst, doklejany do adresu URL, stanowiący parametry wywołania danego adresu). Przejdźmy najlepiej do przykładu i spójrzmy na poniższy formularz:

<form id="someForm">
  <div><input type="text" name="name" value="Bartek" /></div>
  <div><input type="hidden" name="id" value="3" /></div>
  <div>
    <input type="checkbox" name="checked" />
  </div>
  <div>
    <input type="button" name="button" value="Zatwierdz" />
  </div>
</form>
<div id="container"></div>

Następujący kod JavaScript, z wykorzystaniem jQuery, pokazuje jaka jest zasada działania metody ‘serialize’:

$('input[type=button]').click(function() {
    var queryString = $('form').serialize();

    $('#container').text(queryString);
});

A więc tak: najpierw do zdarzenia ‘click’ przycisku formularza, przypisujemy funkcję obsługującą je. Wewnątrz, na rzecz elementu ‘form’ wywołujemy metodę ‘serialize’, a następnie wyświetlamy ją wewnątrz kontenera o identyfikatorze ‘container’. W zależności od tego jak wypełnione zostałyby poszczególne pola formularza, wyświetlona wartość mogłaby być następująca:

name=Bartek&id=3&checked=on

Metoda ‘serialize’ może przydać się, do odczytywania wartości formularza i zatwierdzania formularzy na przykład asynchronicznie. Powyższy działający przykład, można poklikać na jsfiddle.net, natomiast dokładny opis metody ‘serialize’ znaleźć można na stronach jQuery.

Kolejna kwestia, którą chcę omówić w tym paragrafie, to zatwierdzanie formularza za pomocą języka JavaScript. Jest to sprawa bardzo prosta. Dla kodu HTML, z poprzedniego przykładu, do zatwierdzenia formularza wystarczyłby taki kod:

var form = document.getElementById('someForm');
form.submit();

XMLHttpRequest - wysyłanie danych

Jako, że z obiektu ‘XMLHttpRequest’ korzystaliśmy już w poprzednim moim wpisie, dziś przyjrzymy się tylko dokładniej metodzie ‘send’, służącej do wysyłania danych za pomocą tego obiektu.

Opisywana metoda, pozwala na wysyłanie danych kilku typów (dane do przesłania podajemy jako parametr wywołania metody ‘send’). Poniżej lista typów danych jakie możemy przesyłać za pomocą obiektu XMLHttpRequest:

  • ArrayBuffer - opisywany powyżej typ, stanowiący bufor danych w pamięci
  • ArrayBufferView - również opisany w tym artykule, widok na bufor danych
  • Blob - typ danych binarnych, zwykle wykorzystywany do przesyłania plików
  • Document - obiekt dokumentu DOM
  • FormData - obiekt reprezentujący dane formularza; do przesyłania danych używany jest dokładnie ten sam format co w przypadku użycia metody ‘submit’ formularza
  • String - dane przesyłane jako zwykły tekst

Oczywiście, wywołanie metody ‘send’, zgodnie z tym co pokazywałem w poprzednim poście, musi zostać poprzedzone wywołaniem metody ‘open’, gdzie podajemy typ wywołania (GET lub POST), adres URL wywołania oraz informację czy wywołanie ma być asynchroniczne czy też nie.

Kodowanie adresów URL w formularzach

Ostatnią poruszaną dziś kwestią jest kodowanie adresów URI. Jest to przydatne, na przykład w przypadku, gdy nasz formularz zawiera pole, w którym użytkownik wprowadzić ma jakiś adres URL, nie daj boże zawierający jeszcze parametry “query string”. Aby możliwe było prawidłowe przesłanie takiej informacji z formularza, musi ona zostać przed wysłaniem odpowiednio zakodowana, to znaczy wszystkie jej znaki specjalne muszą zostać zamienione na odpowiednie kody.

Do kodowania adresów URI służy metoda ‘encodeURI’, która koduje wszystkie znaki specjalne poza , / ? : @ & = + $ #. Spójrzmy na przykład:

var uri = 'my test.html?name=Bartek&amp;id=1234';
$('p').text(encodeURI(uri));

Powyższy kod, przypisuje do znacznika <p> wartość “my%20test.html?name=Bartek&id=1234”, a więc zamieniona została tylko spacja. Do dekodowania tej wartości użyć należy funkcji ‘decodeURI’.

Jeśli chcielibyśmy zakodować cały adres URL, należy użyć metod encodeURIcomponent:

var uri = 'my test.html?name=Bartek&amp;id=1234';
$('p').text(encodeURIComponent(uri));

W tym przypadku, do znacznika <p> przypisana zostanie wartość “my%20test.html%3Fname%3DBartek%26id%3D1234”. I tutaj również analogicznie, do zdekodowania tak zakodowanej informacji użyć należy funkcji ‘decodeURIComponent’.

Serializacja danych JavaScript - podsumowanie

Wpisem dzisiejszym zakończyłem omawianie zagadnień związanych z dostępem i zabezpieczaniem danych. Myślę, że serializacja danych JavaScript nie ma już dla Ciebie tajemnic. Kolejne posty dotyczyć już będą CSS3. Oczywiście zapraszam ponownie!