ABC skryptów CGI

Wstecz Dalej

CGI i "ciastka"

Jako ostatnie zagadnienie w tym opracowaniu omówimy technikę używania skryptów CGI w połączeniu z "ciastkami" (cookies). Technika "ciastek" została stworzona w celu umożliwienia powiązania między sobą kolejnych odwołań do stron przez oprogramowanie serwera.

Z punktu widzenia użytkownika korzystającego z serwisu WWW kolejne odwiedzane przez niego strony układają się w pewien logiczny ciąg; tymczasem serwer traktuje każde odwołanie do strony całkowicie niezależnie od pozostałych i nie istnieją dla niego żadne związki między poszczególnymi odwołaniami - mówimy, że protokół HTTP jest bezstanowy. Rzecz jasna potężnie utrudnia to, jeżeli nie wręcz uniemożliwia, realizację jakichkolwiek prawdziwie interaktywnych serwisów WWW - takich jak chociażby sklepy internetowe - gdzie użytkownik odwołuje się kolejno do szeregu stron, a wyświetlane na nich dane zależą od czynności, które wykonywał poprzednio.

Z pomocą przychodzą właśnie "ciastka". Są to niewielkie, z reguły kilku-kilkudziesięciobajtowe porcje informacji przechowywane w pamięci operacyjnej lub na dysku komputera klienta i wysyłane do serwera przy wszystkich kolejnych odwołaniach do określonych stron. Pozwala to oprogramowaniu serwera na powiązanie tych odwołań ze sobą.

Mechanizm działania "ciastek" jest następujący: odwiedzany przez nas serwer WWW może wysłać do przeglądarki porcję informacji - "ciastko", które zostanie zapamiętane przez przeglądarkę i będzie następnie odsyłane serwerowi przy każdym kolejnym odwołaniu do tych samych stron. Istnieją dwa zasadnicze typy "ciastek" - nietrwałe, które pamiętane są jedynie w bieżacej sesji, tzn. do momentu wyjścia z przeglądarki, oraz trwałe, które zapamiętywane są na dysku naszego komputera i mogą zostać odesłane do serwera w dowolnym późniejszym momencie przy ponownych odwiedzinach na tej samej stronie.

Serwer wysyła do przeglądarki "ciastko", umieszczając w nagłówku HTTP wysyłanej strony pole postaci:

     Set-Cookie: NAZWA=WARTOŚĆ; expires=data; domain=domena; path=ścieżka
Tylko fragment "NAZWA=WARTOŚĆ" jest obowiązkowy; pozostałe mogą zostać pominięte. Parametr "expires=" określa datę, do której przeglądarka ma przechowywać ciastko na dysku; w razie jego braku ciastko jest traktowane jako nietrwałe i nie jest zapamiętywane. Parametr "domain=" określa domenę (lub konkretny serwer) dla której obowiązuje ustawione ciastko, a parametr "path=" analogicznie - ścieżkę dostępu do strony lub stron, której ciastko dotyczy. W braku jednego lub drugiego parametru przyjmowany jest adres tego samego serwera lub strony, która wysłała ciastko.

Z kolei przeglądarka odsyłając "ciastko" serwerowi używa nagłówka o postaci:

     Cookie: NAZWA1=WARTOŚĆ1; NAZWA2=WARTOŚĆ2; ...
gdzie poszczególne pary "NAZWA1=WARTOŚĆ1" itd. odpowiadają wszystkim zapamiętanym ciastkom, które pasują do danego serwera i ścieżki dostępu.

Przykładowo jeżeli serwer wyśle nagłówek:

     Set-Cookie: USERID=982AF46; expires=Mon, 1-Jan-2001 00:00:00 GMT;
           domain=microsoft.com; path=/download
oznacza to, że aż do dnia 1 stycznia 2001 czasu GMT (w "ciastkach" obowiązuje podawanie czasu uniwersalnego) przy każdym następnym połączeniu z jakąkolwiek stroną o ścieżce dostępu zaczynającej się od "/download" na jakimkolwiek serwerze z domeny microsoft.com, przeglądarka powinna wysłać do serwera nagłówek postaci:

     Cookie: USERID=982AF46
Poniższy skrypt jest bardzo prostym przykładem zastosowania "ciastek". Gdy odwołujemy się do niego po raz pierwszy, skrypt wykrywa, że nasza przeglądarka nie wysłała mu żadnego "ciastka", w związku z czym prosi nas o podanie imienia (rys.12). Gdy to zrobimy, skrypt odczytawszy dane z formularza wysyła w odpowiedzi do naszej przeglądarki dwa "ciastka" z bardzo odległą datą ważności (1 stycznia 2030 r.): w jednym z nich zapamiętane jest podane imię, a w drugim - liczba dotychczasowych odwiedzin tej strony, czyli 1.

Gdy kiedykolwiek później zajrzymy na tę samą stronę (oczywiście z tego samego komputera i tą samą przeglądarką), skrypt - dzięki "ciastkom" wysłanym przez przeglądarkę - przywita nas już naszym imieniem i informacją, który raz już tu jesteśmy (równocześnie aktualizując "ciastko" przechowujące informację o liczbie odwiedzin) - rys.13.

Dokładną analizę skryptu pozostawiam dociekliwości Czytelników. Oto jego treść: *

     #!/usr/bin/perl
     use CGI;
     
     print "Content-type: text/html; charset=iso-8859-2\n";

     # jeżeli zostało wprowadzone imię z formularza

     if ($ENV{'CONTENT_LENGTH'}) {

        CGI::ReadParse(*form);
        print "Set-Cookie: IMIE=$form{'imie'}; expires=Tue, 1-Jan-2030 00:00:00 GMT\n";
        print "Set-Cookie: RAZY=1; expires=Tue, 1-Jan-2030 00:00:00 GMT\n\n";
        print <<"EOF";
     <html>
     <head><title>Witaj!</title></head>
     <body>
     <h1 align="center">Dziękuję!</h1>
     Zapraszam na nasze strony w przyszłości!
     EOF
     
     } else {

        # w przeciwnym razie najpierw sprawdzamy, czy jest ciastko     

        if ($ENV{'HTTP_COOKIE'}) {
           @cookies = split /\;\s*/, $ENV{'HTTP_COOKIE'};
           # rozdziela nagłówek Cookie: na poszczególne ciastka
           foreach (@cookies) {
              split /=/;
              # rozdziela w ciastku nazwę od wartości
              if ($_[0] eq "IMIE") {
                 $imie = $_[1];
              }
              if ($_[0] eq "RAZY") {
                 $razy = $_[1];
              }
           }
        }

        if ($razy) {
           $razy = $razy + 1;
           print "Set-Cookie: RAZY=$razy; expires=Tue, 1-Jan-2030 00:00:00 GMT\n";
        }
        print "\n";
  
        print <<"EOF";
     <html>
     <head><title>Witaj!</title></head>
     <body>
     EOF
     
        if ($imie) {
           print "<h1 align=\"center\">Witaj $imie!</h1>\n";
           print "Miło Cię widzieć znowu na naszej stronie!<p>\n";
           print "Jesteś tu już $razy raz!\n";
        } else {
           print <<"EOF";
     <h1 align="center">Witaj!</h1>
     Jesteś na tej stronie pierwszy raz.<p>
     <form method="post" action="http://$ENV{'SERVER_NAME'}$ENV{'SCRIPT_NAME'}">
     Proszę, podaj swoje imię: <input type="text" name="imie">
     <input type="submit" value="OK">
     </form>
     EOF
        }
     
     }
     
     print "</body>\n</html>\n";

Wstecz Dalej

* Z uwagi na zmianę sposobu działania funkcji split w nowszych wersjach Perla, przedstawiony w artykule kod skryptu wymaga modyfikacji - zmodyfikowaną wersję można znaleźć tutaj.


Jarosław Rafa 2000. Tekst udostępniony na licencji Creative Commons (uznanie autorstwa - użycie niekomercyjne - bez utworów zależnych). Kliknij tutaj, aby dowiedzieć się, co to oznacza i co możesz z tym tekstem zrobić. W razie jakichkolwiek wątpliwości licencyjnych bądź w celu uzyskania zgody na rozpowszechnianie wykraczające poza warunki licencji proszę o kontakt e-mailem: raj@ap.krakow.pl.

Wersja HTML opracowana 11.10.2000, uzupełnienie 3.10.2014.


Powrót do spisu treści Statystyka