[Wstecz] <-- [Indeks] --> [Dalej]
Wykorzystanie możliwości drzemiących w technologii cookies nie jest rzecz jasna możliwe w przypadku prezentowania witryny w sposób statyczny, tzn. użytkownik pobiera z serwera dokumenty html o na sztywno ustalonej treści. Dopiero współtworzenie obrazu witryny poprzez wykonywalne skrypty, czy to po stronie serwera (CGI, PHP, Perl, ASP, JSP i inne), czy też po stronie klienta (JavaScript) pozwoli na realne wykorzystanie tej usługi gromadzenia informacji.
Oczywiście, trudno oczekiwać, by dostęp do realizacji żądań umieszczenia pliku cookies na dysku użytkownika, czy też odczytywanie przesyłanych zeń informacji wymagało ścisłej znajomości protokołu HTTP, parsowania danych itd. Praktycznie wszystkie języki programowania przeznaczone do aplikacji webowych są wyposażane w biblioteki uwalniające programistę od tego typu czynności.
W niniejszym opracowaniu postaramy się przedstawić skrótowo te rozwiązania. Dla najpopularniejszego obecnie języka: PHP oraz JavaScriptu, przygotowaliśmy również proste przykłady demonstrujące działanie funkcji obsługi cookies.
JavaScript jest językiem skryptowym działającym po stronie klienta. Kod skryptu jest umieszczany bezpośrednio w kodzie HTML strony, lub też dołączany z oddzielnego pliku poprzez stosowne żądanie w nagłówku dokumentu HTML.
Należy podkreślić, że cechą odróżniającą JavaScript od skryptów wykonywanych na serwerze jest możliwość zakładania bądź modyfikacji "ciasteczka" już po załadowaniu strony, np. jako efekt wyboru opcji przez użytkownika (bez konieczności przeładowania strony). W technologiach "server-side" zapis cookies jest możliwy wyłącznie przed przesłaniem obrazu strony (w nagłówku HTTP), a podany wyżej przykład wymagałby procedury: użytkownik wybiera opcję formularza, dane są wysyłane do serwera, serwer generuje nową stronę z jednoczesnym zapisem cookies.
Wszystkie informacje zawarte w ciasteczkach są dostępne poprzez obiekt document.cookie, będący ciągiem zawierającym wszystkie ciasteczka danej strony. Wymaga się, aby ciągi przechowywanych informacji nie zawierały spacji i kropek. Jeżeli nie można wykluczyć obecności tych znaków, muszą one zostać przed lub po odwołaniu się do obiektu document.cookie zakodowane funkcjami escape() oraz unescape().
Przykładowa funkcja, która będzie zapisywała informacje do ciasteczek (wysyłała cookie), wygląda następująco:
function setCookie(name, value, expire)
{
document.cookie = name + "=" + escape(value)
+ ((expire == null) ? "" :
("; expires=" + expire.toGMTString()));
}
Przy odwołaniu do funkcji podajemy nazwę ciasteczka, jego wartość i czas ważności w odpowiedniej formie (trochę dalej poruszymy ten problem).
Poniższa przykładowa funkcja pobiera wartość ciasteczka na podstawie jego nazwy.
function getCookie(Name)
{
var search = Name + "=";
// jeżeli są jakiekolwiek ciasteczka
if (document.cookie.length > 0)
{
// określenie początku ciasteczka o zadanej nazwie
offset = document.cookie.indexOf(search);
// jeżeli ciasteczko istnieje
if (offset != -1)
{
//określenie początku wartości ciasteczka
offset += search.length;
//określenie końca ciasteczka
end = document.cookie.indexOf(";", offset)
if (end == -1) end = document.cookie.length
//zwrócenie wartości ciasteczka
return
unescape(document.cookie.substring(offset, end))
}
}
}
Korzystając z funkcji opisanych wcześniej możemy stworzyć skrypt umożliwiający zapamiętanie preferencji danego użytkownika. W naszym przykładzie będzie to tylko zapamiętanie imienia odwiedzającej osoby na czas jednego roku.
Dopisujemy do nagłówka jeszcze jedną definicję funkcji służącą rejestracji użytkownika. Jest to funkcja wykonywana podczas wciśnięcia przycisku REJESTRUJ w formularzu.
Widzimy na niej czas ważności ciasteczka o którym była mowa wcześniej. Czas jest wyrażony w milisekundach od daty 1.01.1970 godziny 00:00:00. W przykładzie funkcja .getTime() zwraca czas w milisekundach do daty obecnej (teraz), dlatego jeszcze należy dodać do tej wartości czas ważności ciasteczka, w wyniku czego otrzymamy czas, do kiedy ciasteczko będzie ważne (w milisekundach).
function register(name)
{
var today = new Date()
var expires = new Date()
expires.setTime(today.getTime() + 1000*60*60*24*365)
setCookie("KatedraTelekomunikacji", name, expires)
}
W tej części przedstawiamy zawartość między tagami <BODY> strony. Jest to prosty formularz, który odwołuje się do wcześniej utworzonej funkcji.
<BODY>
<H1>Zarejestruj swoje imię!!!</H1>
<P>
<SCRIPT>
var yourname = getCookie("KatedraTelekomunikacji")
if (yourname != null)
document.write("<P>Witaj ponownie.
Twoje imię to: ", yourname, ".")
else
document.write("<P>W ciągu ostatniego roku
nie odwiedzałeś tej strony!")
</SCRIPT>
<P> Podaj swoje imię. Kiedy wrócisz na tę stronę,
będziesz witany swoim imieniem.
<BR>
<FORM onSubmit="return false">
Podaj swoje imię: <INPUT TYPE="text" NAME="username"
SIZE=10><BR><BR>
<INPUT TYPE="button" value="REJESTRUJ"
onClick="register(this.form.username.value); history.go(0)">
</FORM>
</BODY>
Sprawdź działanie skryptu.
Język skryptowy ASP (Active Server Pages) dostarczany jest przez firmę Microsoft jako narzędzie generowania dynamicznych witryn WWW w serwerach IIS (Internet Information Server) oraz PWS (Personal Web Server). Technologia ta jest obiektowym ujęciem rozwijanego od czasów DOS-u języka Basic (później Visual Basic).
ASP posiada sześć wbudowanych obiektów służących do zarządzania aplikacjami internetowymi:
| Application | przechowuje informacje o stanie aplikacji |
| Session | przechowuje informacje dotyczące jednego użytkownika, jest magazynem informacji każdego użytkownika odwiedzającego stronę |
| Request |
zawiera wszystkie informacje, które są wysyłane z przeglądarki
do serwera, zawiera dane, które zostały wysłane przy użyciu formularza |
| Response | wysyła HTML i różne informacje, łącznie z cookies i nagłówkami, z powrotem do przeglądarki (klienta). |
| Server | zwiększa funkcjonalność Active Server Pages |
| Context | pozwala np. przerwać transakcję, która jest zarządzana przez Transaction Server |
Wyżej wymienione obiekty mogą być użyte w każdym miejscu strony ASP. Cookies należą do obiektu Response.
ASP może się posługiwać dwoma rodzajami cookies:
cookie sesji - działają tylko w czasie, gdy okno przeglądarki
jest otwarte i przechowywane są w obiekcie Session,
stałe cookie - są przechowywane na dysku twardym klienta (użytkownika)
i są aktywne do czasu upływu ich daty ważności.
Poniżej znajduje się przykład umieszczenia ciasteczka o nazwie "AGH" i wartości "KT":
Response.Cookies("AGH") = "KT"
Używając powyższej składni można stworzyć wiele ciasteczek, których wartości można dowolnie zmieniać. Dane przechowywane w stałych cookie nie wygasają po zamknięciu przeglądarki. Posiadają one jednak datę upływu ważności. Przykład, który pokaże sposób określenia daty upływu ważności ciasteczka po upływie jednego miesiąca:
<%
Response.Cookies("Produkt")
= "Telewizor";
Response.Cookies("Produkt").Expires =
DateAdd("m", 1, Now());
%>
W ciasteczku można przechowywać więcej niż jedną wartość. Zrobić to można w następujący sposób:
<%
Response.Cookies("book")("autor") =
"Mickiewicz"
Response.Cookies("book")("tytul") =
"Pan Tadeusz"
Response.Cookies("book").Domain =
"ksiegarnia.com"
Response.Cookies("book").Path =
"/klasyka/"
Response.Cookies("book").Secure =
"False"
%>
Linia 2 i 3 przypisują dwie wartości do ciasteczka o nazwie "book". Linia 4 określa nazwę domeny, dla której ciasteczko będzie aktywne. Znaczenie własności "Domain", "Path" i "Secure" jest oczywiście analogiczne do opisanego w rozdziale czwartym niniejszego opracowania.
Pobranie wartości cookies realizuje się w następujący sposób:
<% = Request.Cookies("book")("autor") %>
Komenda odczytuje wartość i wysyła ją do przeglądarki klienta.
W powyższym przykładzie wyświetlona została tylko jedna wartość danego klucza cookies. Jak można wyświetlić pozostałe? Otóż rozwiązaniem jest właściwość HasKeys grupy Cookies. Poniżej został przedstawiony bardziej rozbudowany przykład wykorzystujący tę właściwość i prezentujący na ekranie przeglądarki zawartość wszystkich dostępnych plików cookies:
<% @LANGUAGE = VBScript %>
<% Option Explicit %>
<HTML><BODY>
<%
Dim cookie, klucz
For Each cookie In Request.Cookies
If Not Request.Cookies(cookies).HasKeys Then
Response.Write cookie & " = " &
Request.Cookies(cookie) & "<BR>"
Else
For Each klucz In Request.Cookies(cookie)
Response.Write cookie
Response.Write
"(" & klucz & ")"
Response.Write " = "
Response.Write Request.Cookies(cookie)(klucz)
Response.Write "<BR>" & VbCrLf
Next
End If
Next
%>
</BODY></HTML>
Wynikiem wykonania powyższego skryptu będzie pojawienie się na stronie tekstu:
book(AUTOR) = Mickiewicz
book(TYTUL) = Pan Tadeusz
Jedynym nowym elementem w powyższym przykładzie jest linia:
If Not Request.Cookies(cookies).HasKeys Then
Sprawdza ona czy "cookie" o nazwie cookies posiada większą ilość wartości niż 1.
Jako że PHP jest językiem skryptowym po stronie serwera, obowiązuje nas pewne ograniczenie, mianowicie ciasteczko musi zostać wysłane zanim wydrukujemy jakikolwiek tekst do przeglądarki, w przeciwnym wypadku otrzymamy komunikat "header already sent". I to była zła wiadomość...
Dobra wiadomość jest taka, że nie musimy ręcznie obsługiwać ciasteczek, mamy do dyspozycji funkcję setcookie(), dla której argumentami są: nazwa, wartość, data ważności, ścieżka, domena i parametr secure, przy czym dowolną ilość argumentów od końca możemy opuścić (wystarczy pozostawić samą nazwę ciasteczka, które w takim przypadku zostanie skasowane).
Ciekawą sprawą jest obsługa wielokrotnych wywołań funkcji setcookie w jednym skrypcie przez PHP 3. Wywołania obsługiwane są mianowicie w odwrotnej kolejności, niż są wpisane. Powoduje to, iż jeśli chcemy najpierw skasować stare ciasteczko, a następnie na jego miejscu wstawić nowe, musimy odpowiednie polecenia setcookie() wpisać w odwrotnej kolejności, gdyż w przeciwnym wypadku skasujemy dopiero co ustawione ciasteczko! Poniżej przykład, jak nie należy postępować pisząc skrypt w PHP 3. W PHP 4 kolejność jest już prawidłowa.
setcookie("nazwa");
setcookie("nazwa", "wartość");
Funkcja setcookie() automatycznie koduje wartość ciasteczka do formatu URL, która jest później także automatycznie odkodowywana i przypisywana zmiennej o nazwie takiej jak nazwa ciasteczka, co powoduje znaczne uproszczenie odczytywania ciasteczek. Do ciasteczka o nazwie name można więc odwołać się przez $name, ale także przez $HTTP_COOKIE_VARS["name"], przy czym nadpisywanie dowolnej z tych zmiennych nie powoduje automatycznego nadpisania ciasteczka ani też zmienne te nie są ustawiane w momencie ustawienia ciasteczka, ale dopiero w momencie jego odczytania (np. po przeładowaniu strony).
Charakterystyczną dla języka PHP jest możliwość umieszczenia w cookies również zawartości całej tablicy. Odbywa się to poprzez nazwanie elementów pliku cookies ciągiem "nazwa" + indeks w nawiasach kwadratowych np.:
setcookie ("agh[1]", "cookiethree");
setcookie ("agh[2]", "cookietwo");
setcookie ("agh[3]", "cookieone");
Informacje przesłane w ten sposób zostaną automatycznie przypisane komórkom tablicy $agh. Poniższy kod wypisze te wartości.
if (isset ($agh))
for ($i = reset($agh); $i = each($agh);)
print($i[0] . " == " . $i[1] .
"<br>\n");
Przedstawiony przykład, jest rozbudowanym skryptem licznika odwiedzin strony, wspierającym rzecz jasna cookies. Aby licznik był odporny na przeładowania, powinien wiedzieć, że dany użytkownik w tej sesji już był na tej stronie i że jest to cały czas ta sama sesja. Można to zrealizować na kilka sposobów, jednym z nich są właśnie ciasteczka. Nasza wersja licznika rozpoznaje ponadto, ile razy użytkownik odwiedził daną stronę. Zapamiętywanie odwiedzin może być rozwiązywane poprzez zapamiętywanie w pliku po stronie serwera numeru IP użytkownika oraz liczby jego odwiedzin, jednak sposób ten nie jest w stanie zliczać odwiedzin użytkowników posiadających dynamiczny numer IP. Rozwiązanie używające cookies przechowuje dane dotyczące ilości odwiedzin właśnie w ciasteczku po stronie klienta, co pozwala jednoznacznie określić dany komputer w sieci.
Licznik składa się z plików: licznik1.php i licznik2.php, a użycie go jest bardzo proste. Wystarczy umieścić komendę: <? include("licznik1.php"); ?> przed tagami <HTML> w kodzie strony oraz komendę: <? include("licznik2.php"); ?> wewnątrz tagów <BODY>, w miejscu gdzie chcemy mieć widoczny licznik. Dodatkowo należy utworzyć plik "licznik.data", w którym będą przechowywane ilości odwiedzin i nadać mu atrybuty zapisu dla użytkownika, z prawami którego wykonywane są skrypty WWW na serwerze. Wszystkie powyższe pliki powinny znajdować się w katalogu głównym strony.
Sprawdź działanie licznika.
Perl jest popularnym, zwłaszcza wśród użytkowników systemów UNIX, językiem skryptowym. Obsługa cookies została w nim zaimplementowana w dołączanych zewnętrznych bibliotekach.
Podane poniżej przykłady użycia tychże bibliotek ilustrują możliwości manipulacji cookies z poziomu Perla.
Odczyt pojedynczej wartości ("name") cookies i przypisanie jej do zmiennej "x":
use CGI::Cookie;
my $zmienna;
my %cookies = fetch CGI::Cookie;
if (defined($cookies{'name'})) # jeśli jest o tej nazwie
$x = $cookies{'name'}->value; # sprawdź wartość
Programista ma również dostęp do ciągu zawierającego wszystkie wartości cookies w postaci par "nazwa"="wartość" rozdzielonych średnikami.
$cookie = $ENV{'HTTP_COOKIE'};
Drugi przykład demonstruje sposób tworzenia lub modyfikacji pliku cookies. Oczywiście, poniższy fragment kodu musi być wykonany przed rozpoczęciem wysyłania strony.
use CGI qw/:standard/;
use CGI::Cookie;
$ciastko1 = new CGI::Cookie(-name => 'Liczba',-value => '2');
$ciastko2 = new CGI::Cookie(-name => 'Uczelnia',-value => 'AGH');
print header(-cookie => [$ciastko1,$ciastko2]);