ROZDZIAŁ 6
Projektowanie aplikacji internetowych
Wprowadzenie standardów dotyczących Internetu oraz jego ogromna popularność, spowodowały zmianę architektury rozproszonych aplikacji. Wielowarstwowy Internet jest idealnym środowiskiem do projektowania aplikacji opartych na komponentach. Są one szybkie do opracowania i dostrojenia, mogąc dostarczać zaawansowanych usług systemowych, takich jak dostęp do baz danych i przetwarzanie transakcji. Zasobami systemu można zarządzać i administrować zdalnie. Co więcej, nowe aplikacje są dostępne natychmiast – użytkownik nie potrzebuje niczego oprócz przeglądarki.
W niniejszym rozdziale omówione są możliwości projektowania rozproszonych aplikacji opartych na Internecie i sposoby wykorzystania Internet Information Services (IIS) 5.0 do projektowania wielowarstwowych aplikacji internetowych, które będą powszechne w przyszłości. Opisane są także technologie klienckie i serwerowe opracowane przez Microsoft w celu realizacji tego nowego pokolenia aplikacji internetowych. Zakłada się, że czytelnik zna pojęcia związane z projektowaniem oprogramowania.
W rozdziale:
Rozwój aplikacji klient/serwer
Technologie po stronie klienta
Metody projektowania aplikacji internetowych
Usuwanie błędów z aplikacji i komponentów
Rozwój aplikacji klient/serwer
Analitycy rynku zauważyli tendencję do projektowania aplikacji wielowarstwowych dystrybuowanych poprzez sieci o standardach internetowych. Przewidują szybki wzrost popularności podobnych systemów rozproszonych w przyszłych latach. Niektórzy szacują, że do roku 2005 znana architektura klient/serwer zostanie zastąpiona „super-zestawami” połączonych komponentów, funkcjonującymi w ramach ogólnie dostępnych systemów rozproszonych. Innymi słowy, aplikacje będą budowane z bloków wielokrotnego użytku, przy użyciu różnych rodzajów współpracujących podsystemów.
Przed zapoznaniem się ze szczegółowymi informacjami o budowaniu aplikacji internetowych, przydatne jest zapoznanie się z architekturą Internetu z historycznego punktu widzenia, zaczynając od tradycyjnej architektury klient/serwer.
Klient/serwer po raz drugi
Współpracujące i komunikujące aplikacje tradycyjnie zostały określone jako aplikacje klienckie lub serwerowe. Aplikacja kliencka żąda usług za pomocą Microsoft Distributed Component Object Model (DCOM) lub wywołań zdalnych procedur (RPC), podczas gdy aplikacja serwerowa odpowiada na żądania klienta. W tradycyjnej interakcji klient/serwer, przedstawionej na rysunku 6.1, centralną rolę często odgrywają dane, a większość (lub całość) logiki przetwarzania jest umieszczona razem z interfejsem użytkownika w aplikacji klienckiej. Zadanie serwera jest ograniczone do przetworzenia żądań przechowania i pobrania danych.

Rysunek 6.1 Diagram funkcyjny aplikacji klient/serwer (dwuwarstwowej)
Aplikacje klient/serwer (dwuwarstwowe) zwykle wykonywały wiele takich samych funkcji co samodzielne systemy: pokazywanie interfejsu użytkownika, zbieranie i przetwarzanie danych wprowadzonych przez użytkownika, wykonywanie żądanych zadań i zwracanie informacji o statusie żądania. Ponieważ serwery tylko umożliwiają dostęp do danych, przetwarzanie danych musi odbywać się na komputerze klienckim. Z konieczności, aplikacja klienta wie, gdzie dane się znajdują i w jaki sposób są one ułożone w bazie. Po przekazaniu danych przez serwer, za ich formatowanie i dostarczenie użytkownikowi odpowiada klient.
Główną zaletą aplikacji dwuwarstwowych w porównaniu z monolitowymi aplikacjami jednowarstwowymi jest to, że jednocześnie dostęp do tych samych danych może uzyskać wielu użytkowników, co umożliwia pewnego rodzaju komunikację międzyprocesową. Aktualizacje na jednym komputerze są natychmiast dostępne dla wszystkich komputerów łączących się z serwerem.
Serwer musi jednak mieć zaufanie do klientów modyfikujących dane — nie ma ochrony przed błędami w kodzie klienckim, chyba że stosuje się reguły integralności danych. Dodatkowo, połączenia pomiędzy klientem a serwerem są trudne do zarządzania — serwer musi otworzyć nowe połączenie dla każdego klienta. Ponieważ logika użytkowa jest podzielona pomiędzy różne aplikacje klienckie, zmiany w procedurach handlowych często wymuszają dokonanie kosztownych i czasochłonnych modyfikacji w kodzie źródłowym.
Układ dwuwarstwowy jest wciąż używany w wielu aplikacjach handlowych na małą skalę, jednakże rosnący popyt na szybki i niezawodny dostęp do danych oraz potrzeba szybszego projektowania przekonały projektantów, że pora poszukać nowego układu aplikacji rozproszonych.
Układ wielowarstwowy
Przy nowym układzie zadania są podzielone logicznie pomiędzy komponenty aplikacji. Z funkcjonalnego punktu widzenia większość aplikacji wykonuje trzy następujące zadania: zbieranie informacji od użytkownika, przechowywanie ich jako danych oraz przetwarzanie danych zgodnie z określonymi procedurami operacyjnymi. Zadania te mogą być zgrupowane w trzy lub więcej warstw, dlatego nowy układ systemu wspiera aplikacje wielowarstwowe. Warstwy aplikacji, przedstawione na rysunku 6.2, są następujące:
Warstwa kliencka Interfejs użytkownika lub warstwa prezentacji. Ta górna warstwa pozwala użytkownikowi na wprowadzenie danych, oglądanie wyników i interakcję z systemem bazowym. W aplikacjach internetowych rolę interfejsu użytkownika odgrywa przeglądarka. W innych aplikacjach warstwa ta składa się z samodzielnej, skompilowanej aplikacji klienckiej.
Warstwa środkowa Komponenty realizujące logikę użytkową danej organizacji.
Reguły przetwarzania przypominają codzienne zadania wykonywane w przedsiębiorstwie. Mogą one być związane z pojedynczym zadaniem lub z bardziej złożoną serią zadań. W aplikacji internetowej, warstwa środkowa może zawierać komponenty
Microsoft® Component Object Model (COM) zarejestrowane jako część aplikacji transakcyjnej lub uruchamiane przez skrypt na stronach Active Server Pages (ASP).
Warstwa trzecia System zarządzania bazą danych (DBMS), którym może być baza danych Microsoft SQL Server™, niestrukturalna przechowalnia danych, taka jak
Microsoft Exchange lub mechanizm przetwarzania transakcji, taki jak Transaction
Services lub Message Queuing. Jedna aplikacja może korzystać z usług jednego lub kilku dostawców danych.

Rysunek 6.2 Trzywarstwowa architektura internetowa
Warstwy aplikacji nie zawsze odpowiadają fizycznym punktom w sieci. Na przykład, warstwa środkowa i trzecia mogą istnieć na tym samym serwerze posiadającym IIS 5.0 i SQL Server, ale mogą znajdować się także w osobnych miejscach. Warstwa środkowa może obejmować kilka komputerów, a czasami serwer jest też klientem.
Podzielenie aplikacji na warstwy izoluje każdy główny zakres funkcji. Prezentacja jest oddzielona od logiki użytkowej, która z kolei jest oddzielona od danych. Ten sposób projektowania aplikacji związany jest z pewnymi kosztami (na początku wymaga większej ilości pracy przy analizie i projektowaniu), ale w efekcie zmniejsza w znacznym stopniu koszty konserwacji i zwiększa elastyczność funkcyjną.
Gwałtowny wzrost Internetu stanowi dobrą motywacją dla przedsiębiorstw i organizacji do rozważenia zastosowania architektur wielowarstwowych. Pozostają jednak pewne kwestie. W jaki sposób można wprowadzić nowe technologie i jednocześnie korzystać dalej z istniejących zasobów – personelu, aplikacji, danych? W jaki sposób można zbudować nowoczesne, skalowalne rozwiązania, które są dynamiczne i łatwe do zmiany? W jaki sposób można zmniejszyć ogólne koszty usług komputerowych i jednocześnie zrealizować złożone środowiska komputerowe? Jednym z rozwiązań jest Microsoft Windows Distributed interNet Applications (DNA).
Windows DNA
Architektura Windows DNA jest metodą dostarczoną przez Microsoft do budowania nowego pokolenia wielowarstwowych rozwiązań komputerowych. Windows DNA jest systemem pomagającym tworzyć rozwiązania spełniające wszystkie wymagania przedsiębiorstw, Internetu i sieci wewnętrznych oraz globalnego handlu elektronicznego, a jednocześnie pozwalającym zmniejszyć ogólne koszty projektowania.
W sercu Windows DNA znajduje się model COM. Architektura Windows DNA wykorzystuje wspólny zestaw usług, w tym Hypertext Markup Language (HTML) i dynamiczny HTML (DHTML), kontrolki Microsoft ActiveX, komponenty COM, skrypty po stronie serwera i klienta, transakcje, usługi zabezpieczenia i katalogów, dostęp do danych i baz, zarządzanie systemami za pomocą HTML oraz środowiska opracowywania komponentów. Usługi te są udostępnione w sposób jednolity poprzez model COM, który ułatwia współpracę aplikacji i wspólny dostęp do komponentów.

Rysunek 6.3 Rodzina technologii Windows DNA
Windows DNA opiera się na usługach klienckich systemu operacyjnego Microsoft Windows i Microsoft Internet Explorer, na rozproszonej infrastrukturze Microsoft Windows 2000 Server i aplikacji należących do rodziny Microsoft BackOffice oraz na zintegrowanych narzędziach, takich jak system projektancki Microsoft Visual Studio. Ponieważ architektura Windows DNA wykorzystuje otwarte protokoły i opublikowane interfejsy, to możliwa jest integracja z produktami zewnętrznych producentów. Co więcej, wspierając otwarte podejście do projektowania internetowego, architektura Windows DNA bazuje na ważnych standardach internetowych opracowanych przez organizacje takie jak World Wide Web Consortium (W3C) i Internet Engineering Task Force (IETF).
Więcej informacji o Windows DNA znajduje się pod adresem http://www.microsoft.com/net/default.mspx.
Aplikacje internetowe w przyszłości
Klienci wymagają globalnego dostępu do potrzebnych im informacji, zarówno publicznych, jak i osobistych. Coraz częściej użytkownicy wolą uzyskać dostęp do wszystkich informacji korzystając z jednej aplikacji klienckiej, a od serwerów i sieci oczekują rozmaitych usług. Użytkownicy przyzwyczają się do takich aplikacji i będą chcieli, aby były uniwersalnie dostępne, a nawet zastąpiły lokalne aplikacje na pulpitach.
W konsekwencji można spodziewać się gwałtownego wzrostu liczby aplikacji serwerowych opartych na HTML służących potężnym, uniwersalnie dostępnym, internetowym aplikacjom klienckim. Aplikacje będą składać się z komponentów klienckich (wymagających małej ilości oprogramowania poza standardową przeglądarką) oraz środkowej warstwy komponentów serwerowych nie posiadających interfejsu użytkownika, dostarczających usług na lokalnym pulpicie lub poprzez Internet.
W poniższych częściach omówione są role odgrywane przez warstwę kliencką i środkową w rozproszonych sieciowych i internetowych aplikacjach. Trzecia warstwa jest omówiona w rozdziale „Dostęp do danych i transakcji”.
Technologie po stronie klienta
W części tej przedstawiono technologie, z których składa się warstwa kliencka dzisiejszych aplikacji internetowych. Omówiono cele technologii, ich funkcje jako części aplikacji i sposoby ich użycia. Nie opisujemy tu sposobów projektowania aplikacji opartych na tych technologiach.
Tekst i HTML
HTML jest podstawowym językiem formatowania stron internetowych. Podobnie jak strona wydrukowana, tekst na stronie internetowej może zawierać różne czcionki, kolory, wielkości i atrybuty, style spacjowania oraz kolumny. Dodatkowo, strony internetowe mogą zawierać tabele, ramki i formularze HTML. Aplikacje internetowe w dużym stopniu wykorzystują tabele i formularze, do wyświetlenia danych, organizacji elementów aplikacji i pobrania informacji od użytkowników.
HTML spełnia standardy, które umożliwiają jego stosowanie w całym Internecie oraz w sieciach wewnętrznych. Więcej informacji o standardach HTML znajduje się na stronie domowej W3C pod adresem http://www.w3.org lub w materiałach informacyjnych o HTML. Informacje o najnowszych rozszerzeniach HTML znajdują się dalej w tym rozdziale pod hasłem „Dynamiczny HTML”.
Grafika i multimedia
Zawartość graficzna i multimedialna, gdy jest skutecznie wykorzystana, może znacznie poprawić wygląd aplikacji i zwiększyć wrażenie wywierane na użytkowniku. Może ona zwracać uwagę na ważne części ekranu oraz pomóc w przekazie informacji.
Zawartość multimedialna w sieci wewnętrznej jest narzędziem bardzo potężnym. Na przykład, strumienie dźwiękowe/wideo, dostępne między innymi przez Microsoft NetShow, pozwalają na transmisję ważnych wydarzeń na żywo lub na wykorzystanie wcześniej nagranych filmów do szkolenia pracowników w zakresie skomplikowanych technicznych operacji.
Ze względu na szybkość modemów używanych do większości połączeń internetowych, wykorzystywanie zawartości graficznej i multimedialnej w Internecie należy ograniczyć. Grafika o niskiej rozdzielczości, dobrze zaprojektowana, jest szybsza do ściągania i na większości monitorów wygląda nawet lepiej niż grafika o dużej rozdzielczości.
Hiperłącza
Hiperłącza łączą części aplikacji, służą jako „menu” aplikacji i umożliwiają wykonanie czynności po stronie serwera i klienta. Na przykład, kliknięcie hiperłącza może spowodować załadowanie na stronę kolejnej ramki lub uruchomienie skryptu klienckiego zmieniającego układ strony.
Zazwyczaj hiperłącza są bezpośrednio wbudowane w stronę jako tekst lub obrazki, które użytkownik może oglądać i kliknąć. Mogą one również ulec aktywizacji po wysłaniu formularza, alternatywnie mogą zostać utworzone i wybrane przez skrypt kliencki.
Istnieje wiele sposobów prezentacji hiperłącz użytkownikowi. W przypadku dużej ilości hiperłącz można uprościć ich układ grupując związane z sobą opcje, korzystając z jednolitego stylu prezentacji lub ukrywając i wyświetlając hiperłącza w odpowiednim momencie. Na przykład, można wyświetlać hiperłącza dynamicznie w oparciu o poziom uprawnień użytkownika. Hiperłącza wykonujące zaawansowane lub administracyjne czynności byłyby widoczne tylko dla użytkowników posiadających odpowiednie uprawnienia.
Skrypty po stronie klienta
Skrypty klienckie działają wewnątrz przeglądarki użytkownika, wykorzystując moc procesora komputera klienckiego. Skrypty mogą być napisane w każdym języku wspieranym przez przeglądarkę – najpopularniejszym językiem jest JavaScript, wspierany przez większość przeglądarek. Niektóre przeglądarki, na przykład Internet Explorer, wspierają także Microsoft Visual Basic Scripting Edition (VBScript). Skrypty po stronie klienta pozwalają wykorzystać strony internetowe na różne niestandardowe sposoby. Na przykład, skrypty mogą wykonać edycję pól i obliczeń, manipulować oknem klienta lub zatwierdzić dane na formularzach. Skrypty zwykle pojawiają się bezpośrednio na stronie, której dotyczą, ale mogą manipulować także zawartością stron w innym panelu lub oknie przeglądarki. Więcej informacji o wsparciu przeglądarek dla technologii klienckich znajduje się w tabeli 6.1.
Kontrolki ActiveX
Kontrolki ActiveX służą do dostosowania interfejsu użytkownika albo jako aplikacje dołączone (takie jak kontrolka animacyjna Macromedia Shockwave i odtwarzacz strumieni dźwiękowych/wideo RealNetworks). Kontrolki ActiveX wykonują różne zadania, od nawigacji internetowej po interaktywne handlowanie akcjami. Mogą one być napisane w każdym języku wspierającym automatyzację COM, na przykład Microsoft Visual Basic, C++, Java lub nawet COBOL.
Kontrolki ActiveX mogą być wbudowane w stronę HTML za pomocą znacznika HTML <OBJECT>. Jeśli kontrolka nie istnieje w systemie danego użytkownika, to można ją ściągnąć z URL określonego w atrybucie CODEBASE (patrz poniższy przykład). Znacznik <OBJECT> wspiera także aktualizację wersji komponentów. Po instalacji kontrolki, przeglądarka będzie jej używać, dopóki na serwerze nie zostanie udostępniona zaktualizowana wersja. Poniższy przykład ilustruje użycie atrybutu CODEBASE:
<OBJECT ID=”BoomButton” WIDTH=225 HEIGHT=35 CLASSID=”clsid:56F1BF40-B2D0-11d0-A6D6-00AA00A70FC2” CODEBASE=”http://domain.microsoft.com/AControl.cab#Version=1,0,0,1”> </OBJECT>
Kontrolka ActiveX mogłaby wykonać niszczycielskie czynności na komputerze użytkownika, takie jak usunięcie danych z dysku twardego. Aby pomóc użytkownikom ustalić, które kontrolki są bezpieczne, Microsoft opracował wytyczne dla producentów wydających kontrolki. Kontrolka powinna zawierać podpis cyfrowy swojego twórcy, przyznany przez renomowaną organizację zabezpieczenia, taką jak VeriSign. Technologia podpisywania kodu Microsoft Authenticode zapewnia odpowiedzialność i autentyczność komponentów oprogramowania dostępnych w Internecie. Podpisana kontrolka może zostać zmodyfikowana tylko przez właściciela, nie przez nieupoważnione strony trzecie. Więcej informacji o Authenticode i podpisywaniu kodu znajduje się pod adresem http://www.microsoft.com/security/default.mspx.
W momencie wydania tej książki, rodzime wsparcie ActiveX jest zapewnione tylko przez Microsoft Internet Explorer 3.0 i późniejsze wersje. Zatem kontrolki ActiveX są prawdopodobnie najprzydatniejsze w witrynach sieci wewnętrznych lub witrynach specjalnie przeznaczonych dla użytkowników Internet Explorer.
Cascading Style Sheet
Standard zwany Cascading Style Sheet (CSS) zapewnia autorom więcej możliwości zastosowania czcionek, rozmiarów znaków, dwuwymiarowego nakładania i dokładnego pozycjonowania glifów (używanych do pisma i czcionek różnych języków, na przykład wietnamskich znaków diakrytycznych lub pisma kaligraficznego Urdu). CSS oddziela również informacje o formatowaniu od zawartości stron, dzięki czemu projektowanie i przerabianie stron są dużo łatwiejsze.
Kartki CSS regulują wygląd znaczników HTML, ale nie zastępują ich. Umożliwiają dołączenie informacji stylistycznych do jednego lub więcej dokumentów HTML oraz do zawartych w nich znaczników, co daje o wiele więcej możliwości określania wyglądu i struktury każdej strony. Informacje o formatowaniu można zastosować do niestandardowych znaczników wspieranych przez daną przeglądarkę oraz do standardowych znaczników HTML.
Informacje CSS można udostępnić poprzez odsyłacze wbudować w dokument lub umieścić w dokumencie jako modyfikator stylów. W tym samym dokumencie HTML można zastosować dowolną kombinację tych trzech metod. Najpopularniejsze są odsyłacze, ponieważ dają podstawę dla pozostałych typów modyfikacji. Poniższy kod ilustruje przykład odsyłacza do kartki CSS:
<LINK REL=STYLESHEET TYPE=”text/css” HREF=”./myCustom.css”>
Uwaga: Z powodu zmian standardów CSS zatwierdzonych niedawno przez W3C, wsparcie CSS w Internet Explorer 3.0 nie jest w pełni kompatybilne z Microsoft Internet Explorer 4.0, który wspiera nową wersję standardu. Szczegółowy opis aktualnego standardu CSS 2.0 znajduje się pod adresem http://www.w3.org/Style/.
Prawdziwa historia aplikacji internetowej
Niedawno Microsoft wprowadził nową metodę obsługi zwrotu kosztów pracowniczych. Według starego systemu pracownik musiał wypełnić formularze, dołączyć rachunki i przekazać je menedżerowi, który sprawdzał formularz i przekazywał go działowi księgowości. Często występowały błędy i w wielu przypadkach formularze wymagały ponownego wypełnienia. Po zakończeniu tego procesu informacje z raportów zostawały starannie wprowadzone do bazy danych. W celu rozwiązania niektórych problemów związanych z istniejącym systemem, dział księgowości wprowadził aplikację internetową obsługującą proces zwracania kosztów pracowniczych. Aplikacja pozwala pracownikom wysłać arkusz Microsoft Excel odpowiadający staremu formularzowi. Po załadowaniu arkusza do przeglądarki użytkownika zawarte w nim dane są sprawdzane automatycznie, co umożliwia natychmiastowe wykrycie większości błędów. Gdy dokumenty są gotowe, elektroniczny formularz zostaje wysłany do menedżera poprzez e-mail. Po jego zatwierdzeniu przez menedżera, kopia formularza zostaje przekazana działowi księgowości i zawiadomienie o zatwierdzeniu zostaje zwrócone pracownikowi. Końcowa praca w dziale księgowości jest wykonywana bez papieru, co pozwala zaoszczędzić czas i wysiłek. Nowy system skutecznie:
ulepszył nadzór. Kontrola była tematem, który często pojawiał się podczas projektowania aplikacji. Arkusz i witryna zostały zaprojektowane tak, aby pracownicy i menedżerowie dobrze rozumieli swoje obowiązki. Dzięki użyciu formularza elektronicznego, raporty płynące przez system mogą być śledzone, a kontrola kosztów na serwerze jest szybsza i bardziej rzetelna.
zmniejszył ilość pracy. Eliminacja formularzy papierowych pozwoliła przedsiębiorstwu uzyskać lepszą kontrolę, a jednocześnie zmniejszyć ilość pracy przy
obsłudze i nadzorze raportów o wydatkach.
zmniejszył zużycie papieru. Jednym z celów było zmniejszenie ilości zużywanego papieru. Elektroniczny system wymaga mniejszej ilości papierowych formularzy, a więc wyczerpuje mniej zasobów.
przyspieszył zwrot kosztów. W starym systemie pracownicy otrzymywali zwrot kosztów 8-10 dni po ich zatwierdzeniu, na które czasami musieli czekać tygodnie. W nowym systemie zwrot kosztów jest dokonywany o wiele szybciej, w większości przypadków w ciągu paru dni od momentu zatwierdzenia. Tego rodzaju korzyści są typowe dla aplikacji internetowych. Dobrze zaprojektowana aplikacja zwiększa efektywność pracy i jest dostępna wszędzie, gdzie jest przeglądarka.
Dynamiczny HTML
Dynamiczny HTML (DHTML) jest nowym standardem, wspieranym przez Microsoft Internet Explorer 5, który jest czymś więcej niż prostym rozszerzeniem standardowego HTML. DHTML umożliwia dodanie zaawansowanych funkcji, które poprzednio były dostępne tylko za pomocą kontrol klienckich. W DHTML można, na przykład:
Ukrywać tekst i obrazki w dokumencie przez pewien czas lub dopóki użytkownik nie zażąda ich wyświetlenia.
Zastosować animację tekstu i obrazków w dokumencie. Każdy element może przesunąć się z jednego punktu do drugiego, drogą określoną w kodzie lub przez użytkownika.
Ustawić automatyczną aktualizację wiadomości, cen akcji i innych danych.
Utworzyć formularz i natychmiast odczytać, przetworzyć i odpowiedzieć na dane wprowadzone do formularza przez użytkownika.
Internet Explorer 5 wspiera te funkcje bez potrzeby stosowania dodatkowych apletów Java lub wbudowanych kontrolek. Format i wygląd strony DHTML są aktualizowane dynamicznie bez potrzeby ponownego ładowania dokumentu i bez tworzenia nowej zawartości przez serwer. Wszystkie zmiany są obliczane i realizowane przez komputer kliencki.
Dokumenty DHTML w dużym stopniu wykorzystują style i skrypty do przetwarzania danych wprowadzonych przez użytkowników i do bezpośredniej manipulacji zawartymi w dokumencie znacznikami HTML, atrybutami i tekstem. W modelu obiektowym Internet Explorer 5 można ustawić każdą właściwość każdego znacznika HTML w celu dokładnego określenia układu, wyglądu i funkcji strony.
Uwaga: Nie wszystkie cechy DHTML są kompatybilne z wszystkimi przeglądarkami. W przypadku stron przeznaczonych dla przeglądarek innych niż Internet Explorer 5, należy sprawdzić ich kompatybilność z tymi przeglądarkami.
Więcej informacji o DHTML znajduje się pod adresem http://msdn.microsoft.com.
Wiązanie danych
W DHTML wyniki zapytań do baz danych można „wiązać” z elementami HTML, takimi jak wiersze tabeli. Do wiązania danych można użyć także kontrolek ActiveX, takich jak Advanced Data Connector (ADC) zawarty we wcześniejszych wersjach Internet Explorer. Wiązanie danych umożliwia zdalne oglądanie i modyfikację wyników zapytań, w przeglądarce. Jest to funkcja Remote Data Services (RDS), części rodziny komponentów dostępu do danych Microsoft ActiveX Data Objects (ADO).
Uwaga: Wiązanie danych jest wspierane przez Microsoft Internet Explorer 4.0 i późniejsze wersje.
Więcej informacji o RDS i ADO znajduje się w rozdziale „Dostęp do danych i tran- sakcji” oraz w dokumentacji online IIS 5.0. Więcej informacji o wiązaniu danych znajduje się pod adresem http://msdn.microsoft.com.
Wsparcie przeglądarek
Witryny w sieciach wewnętrznych, w których używany jest zwykle tylko jeden rodzaj przeglądarki, mogą bez problemu zawierać technologie specyficzne dla danej przeglądarki (na wszelki wypadek można umieścić na stronie domowej komunikat dotyczący zalecanego typu przeglądarki).
Nie można jednak zakładać, że wszyscy użytkownicy w Internecie posiadają najnowszą przeglądarkę. Nawet wśród nowych przeglądarek istnieją różne typy – przeglądarki Microsoft, Netscape i Sun Microsystems wspierają ActiveX, Java, skrypty i HTML w różnym stopniu. Funkcje, które mogą być wykonywane na kliencie, zależą od rodzajów i możliwości wspieranych przeglądarek.
Jedną z metod jest umieszczenie na stronach tylko takich funkcji, które mogą być obsłużone przez najprostsze przeglądarki. Zawartość będzie można oglądać w całości w każdej przeglądarce, ale użytkownicy mogą być rozczarowani ograniczoną ilością funkcji.
Niektóre witryny zawierają tekstowe wersje swoich stron lub obszary bez ramek odpowiadające możliwościom prostszych przeglądarek. W ten sposób wszyscy użytkownicy mają dostęp do tych samych informacji, ale konieczne jest projektowanie, testowanie i konserwacja kilku wersji zawartości witryny. Często praca projektantów skupia się na wersji pełnofunkcyjnej, a uproszczone wersje pozostają nierozwinięte.
Najlepszą metodą może być opracowanie stron za pomocą podstawowej technologii, takiej jak HTML i JavaScript i dodanie specyficznych cech po ustaleniu typu przeglądarki. Jest to często dobry kompromis, ponieważ wszystkie strony są opracowane przy użyciu jednego zbioru elementów projektanckich i zawartości. Zaawansowane cechy witryny, takie jak wiązanie danych, są udostępniane tylko przeglądarkom, które je wspierają.
Komponent Browser Capabilities zawarty w środowisku skryptowania ASP zapewnia sposób wykrycia typu przeglądarki i przystosowania zwróconego dokumentu do jej możliwości. Więcej informacji o tym komponencie znajduje się w dokumentacji online IIS 5.0.
Tabela 6.1 zawiera informacje o wsparciu przeglądarek dla różnych technologii klienckich.
Tabela 6.1 Wsparcie przeglądarek dla technologii klienckich
| Technologia | Powszechnie wspierana | Internet Explorer 3.0x | Internet Explorer 4.0 i 5 |
| HTML | X | X | X |
| Zawartość graficzna i multimedialna | X | X | X |
| Hiperłącza | X | X | X |
| JavaScript | X | X | X |
| VBScript | X | X | |
| Kontrolka ActiveX | X | X | |
| CSS | X | X | |
| Dynamiczny HTML | X | ||
Ograniczenia technologii klienckich
Aplikacje oparte wyłącznie na technologiach klienckich są możliwe do utworzenia, ale podobnie jak w przypadku architektury klient/serwer ich możliwości są nieco ograniczone. Istnieje kilka powodów, dla których architektura klient/serwer jest nieodpowiednia dla aplikacji internetowych na dużą skalę:
Kontrolki ActiveX lub skrypty po stronie klienta nie są wspierane przez wszystkie przeglądarki. Internetowa aplikacja handlowa powinna współdziałać z maksymalną ilością przeglądarek, w tym z przeglądarkami nie wspierającymi tabel HTML, ramek, apletów Java, skryptów klienckich i kontrol ActiveX.
Gdy logika użytkowa jest zakodowana jako skrypt kliencki, to kod źródłowy jest dostępny wszystkim. Bezpieczniejsze są aplety Java i kontrolki ActiveX, ale połączenie logiki użytkowej z interfejsem użytkownika oznacza, że trudniej będzie wspierać
aplikację i usuwać błędy. Dodatkową wadą jest to, że ponowne użycie takich komponentów do innych aplikacji jest mniej praktyczne.
Aplikacje oparte wyłącznie na kliencie nie wykorzystują pełnych możliwości trzywarstwowego modelu programowania. Niektóre zadania, takie jak zarządzanie zasobami i manipulacja danymi, są wykonywane skuteczniej po stronie serwera.
Warstwa środkowa
W części tej omówiona jest chyba najważniejsza warstwa programów internetowych, warstwa środkowa, gdzie logika użytkowa przetwarza dane wprowadzone przez użytkowników i wykonuje zadania umożliwiające osiągnięcie celów witryny.
Warstwa środkowa nie musi być pojedynczą warstwą logiki. Może składać się z wielu związanych z sobą technologii połączonych tak, aby wyglądały jak jednolita, wielofunkcyjna warstwa. Na przykład, żądania klienta mogą być wstępnie przetwarzane przez filtr Internet Server Application Programming Interface (ISAPI), po czym może być wykonany skrypt, który uruchamia niestandardowy komponent manipulujący bazą danych za pomocą ADO. Zintegrowane z sobą technologie i warstwy dają przykład prawdziwej architektury wielowarstwowej.
Do omówionych w tej części technologii warstwy środkowej należą aplikacje CGI (Common Gateway Interface), rozszerzenia i filtry ISAPI, ASP, izolacja procesów, odtworzenie po awarii i inne.
Aplikacje CGI
Tradycyjne programowanie dla serwera internetowego opierało się na opracowywaniu skryptów lub programów CGI.
Aplikacje CGI są najczęściej używane w systemach UNIX do tworzenia programów działających na serwerze internetowym. Większość programów CGI jest napisana w języku C, ale można zastosować także języki interpretowane, takie jak Perl. Zdalni użytkownicy mogą uruchomić umieszczone na serwerze aplikacje CGI podając URL zawierający nazwę żądanej aplikacji. Parametry występujące po znaku zapytania w URL zostają przekazane do aplikacji CGI w postaci łańcuchów środowiskowych. Produkt aplikacji CGI różni się w niewielkim stopniu od produktu aplikacji pulpitowej – nagłówki HTTP i HTML są generowane za pomocą podstawowych funkcji wyjściowych danego języka (na przykład printf w C).
Aplikacje CGI są łatwe do napisania, ale cechują się niskim poziomem skalowalności w systemie operacyjnym Windows. Ponieważ każde żądanie klienta wymaga otwarcia nowego procesu, setki klientów utworzą setki egzemplarzy programu CGI, a każdy egzemplarz potrzebuje własnego obszaru pamięci i zasobów systemowych. W systemie UNIX nie stwarza to większych problemów, ponieważ jest on zaprojektowany tak, aby skutecznie obsługiwać duże ilości procesów. Natomiast Microsoft Windows 2000 jest skonfigurowany tak, aby optymalnie zarządzać wątkami wewnątrz procesu, dlatego w systemie tym tworzenie i usuwanie egzemplarzy aplikacji wyczerpuje więcej zasobów systemowych. Z tego też powodu zaprojektowano ISAPI, jako alternatywę dla CGI działającą z dużą wydajnością na platformie Windows i IIS 5.0.
Rozszerzenia i filtry ISAPI
Rozszerzenie ISAPI to run-time DLL, zwykle załadowany w tym samym obszarze pamięci co IIS 5.0. Ponieważ rozszerzenie ISAPI stanowi DLL, to ładuje się jednocześnie tylko jeden jego egzemplarz. Rozszerzenie ISAPI musi bezpiecznie obsługiwać wątki, tak że wiele żądań klientów może zostać odebranych jednocześnie.
Rozszerzenia ISAPI są bardziej złożone niż aplikacje CGI, jednakże ISAPI korzysta ze stosunkowo prostego interfejsu programowania aplikacji (API). Po otrzymaniu każdego żądania, serwer wywołuje procedurę ISAPI HttpExtensionProc i przekazuje wskaźnik do Extension Control Block (ECB) ISAPI zawierający informacje o żądaniu. DLL ISAPI może skorzystać z funkcji zwrotnych do uzyskania z serwera informacji, takich jak zmienne serwerowe. ECB ISAPI daje projektantowi dostęp do ogólnych funkcji pomocniczych, takich jak przeadresowanie URL, zarządzanie sesjami i nagłówki odpowiedzi, które są niedostępne aplikacjom CGI.
Pomimo oczywistych zalet rozszerzeń ISAPI w stosunku do CGI, istnieją jednak pewne problemy związane z konserwacją. Na przykład, nawet drobna modyfikacja HTML zwróconego przez rozszerzenie ISAPI wymaga ponownej kompilacji i konsolidacji. W dodatku, jeśli DLL ISAPI nie został dokładnie przetestowany i zatwierdzony przed wdrożeniem i uruchomieniem w procesie serwerowym, to może spowodować zawieszenie się serwera.
Można wybrać, które rozszerzenia ISAPI są ładowane wewnątrz procesu IIS 5.0, a które w osobnym procesie. Rozszerzenia ISAPI działające w osobnym procesie można zatrzymać i zrestartować niezależnie od procesu serwerowego, na przykład w przypadku awarii. Rozszerzenia zewnątrzprocesowe są wolniejsze od wewnątrzprocesowych, jednakże wygodnie jest mieć możliwość izolacji i ponownego załadowania projektowanych jeszcze aplikacji. Więcej informacji o rozszerzeniach zewnątrzprocesowych znajduje się w rozdziale „Dostęp do danych i transakcje”.
ISAPI służy także do tworzenia filtrów. Filtry rozszerzające serwery internetowe są stosunkowo nową koncepcją — nie istnieje ich odpowiednik w CGI. Filtry ISAPI przechwytują określone zdarzenia serwerowe, zanim sam serwer je obsłuży. Konwencja wywoływania filtrów jest bardzo podobna do konwencji wywoływania rozszerzeń. Po załadowaniu filtra (zwykle przy uruchomieniu usługi internetowej) dostarcza on informacji dotyczących rodzajów obsługiwanych przez niego zdarzeń. W przypadku nastąpienia takich zdarzeń filtr może je obsłużyć sam, przekazać innym filtrom lub przekazać serwerowi. W ten sposób można użyć filtrów ISAPI do realizacji niestandardowych procedur identyfikacji użytkowników lub do automatycznego przeadresowania żądań opartych na nagłówkach HTTP, takich jak Accept-Language.
Filtry mogą wywierać negatywny wpływ na wydajność, o ile nie są starannie napisane. W IIS 5.0 filtry ISAPI mogą być zastosowane do całego serwera lub do poszczególnych witryn. Niemożliwe jednak jest ich uruchomienie na zewnątrz procesu.
Active Server Pages
Środowisko skryptowania ASP znacznie upraszcza programowanie po stronie serwera i ułatwia tworzenie zawartości dynamicznej i potężnych aplikacji serwerowych.
Skrypty na stronach ASP wykonują podobne zadania jak aplikacje CGI i ISAPI, ale są o wiele łatwiejsze do napisania i modyfikacji. ASP zapewnia wyższy poziom interakcji zarządzając statusami aplikacji i sesji na serwerze, co pozwala zmniejszyć ilość informacji przekazywanych pomiędzy serwerami a klientem. ASP ułatwia pracę z informacjami podanymi w formularzach HTML lub w URL jako parametrami. Możliwe jest także wykorzystanie zaawansowanych cech HTTP, takich jak “cookies” i certyfikaty zabezpieczenia po stronie klienta. Więcej informacji o zaawansowanych cechach znajduje się w dokumentacji online IIS 5.0.
W sercu ASP leży rozszerzenie ISAPI (Asp.dll) kompilujące i buforujące pliki .asp w pamięci, po uruchomieniu za pomocą interpretera skryptów. Dzięki mapie skryptów IIS 5.0 rozszerzenie .asp jest kojarzone z plikiem Asp.dll. Ponieważ przed wykonaniem skrypty wymagają interpretacji i kompilacji, złożone skrypty mogą być około 4 razy wolniejsze od prostego HTML i 2-3 razy wolniejsze od ISAPI, przy pierwszym żądaniu. Później, skompilowana wersja strony pozostaje w buforze w pamięci serwera, dlatego kolejne żądania są obsługiwane o wiele szybciej, co w przypadku tysięcy żądań tej samej strony niewątpliwie rekompensuje początkowe koszty kompilacji.
ASP zaprojektowano tak, aby było łatwe w obsłudze i aby umożliwić łatwe i szybkie projektowanie. Wydajnością jednak nie dorównuje zawartości statycznej ani dobrze skonstruowanym niestandardowym rozszerzeniom ISAPI napisanym w C++. Tylko dobrze zaprojektowane aplikacje ASP w kombinacji z komponentami serwerowymi mogą działać z szybkością i wydajnością porównywalną z aplikacjami ISAPI. Informacje o projektowaniu stron ASP znajdują się w dokumentacji online IIS 5.0 pod hasłem „Building ASP Pages”.
Skrypty ASP po stronie serwera
Możliwe jest utworzenie stron zawierających wiele interaktywnych elementów, które nie są zależne od rodzaju przeglądarki używanej do ich oglądania. W przeciwieństwie do skryptów klienckich, ASP pozwala „ukryć” skrypty na serwerze w celu ochrony oryginalnych pomysłów projektantów i własności intelektualnej.
Środowisko skryptowania ASP nie jest ograniczone do jednego języka. Skrypty na stronach ASP mogą być napisane w VBScript, Microsoft JScript lub w każdym języku, dla którego dostępny jest aparat skryptowy ActiveX (PerlScript, REXX, Python, itp.).
Polecenia skryptów ASP i HTML występują razem (możliwe jest utworzenie strony ASP po prostu poprzez zmianę rozszerzenia pliku HTML na .asp). Aby rozróżnić HTML od skryptu serwerowego, ASP wykorzystuje specjalne znaczniki, nazywane serwerowymi ogranicznikami skryptowymi, do zaznaczenia skryptu serwerowego: <%i %>. Polecenia występujące pomiędzy tymi ogranicznikami są wykonywane na serwerze w ciągu przetwarzania strony. Specjalna forma ograniczników, <%= wyrażenie %>,może służyć jako skrótowa metoda zwrócenia wartości ze skryptu.
Poniższa linia kodu serwerowego VBScript zwróci dzisiejszą datę:
Today is <%= Date %>.
Wynik wygląda następująco (w zależności od daty):
Today is 7/4/99.
Uwaga: Do umieszczenia na stronie tekstu i wartości wyrażenia można użyć także metody Write obiektu ASP Response.
Poniższy przykład ASP jest bardziej złożony i korzysta z warunkowych elementów języka skryptowania połączonych z HTML:
<% If Hour(Now) < 12 Then %> <FONT COLOR=YELLOW>Good Morning!</FONT> <% ElseIf Hour(Now) < 18 Then %> <FONT COLOR=LIME>Good Afternoon!</FONT> <% Else %> <FONT COLOR=ORANGE>Good Evening!</FONT> <% End If %>
Każda strona posiada główny język skryptowy, jednakże można użyć na tej samej stronie ASP więcej niż jednego języka. Główny język skryptowy aplikacji można ustawić w Menedżerze usług internetowych. Aby określić główny język skryptowy dla strony należy zastosować deklaracje (zwane także @-dyrektywami). Więcej informacji o deklarowaniu języków skryptowych znajduje się w dokumentacji online IIS 5.0.
Podprocedury i funkcje ASP mogą być napisane w dowolnym języku skryptowym. Natomiast jeśli są one zdefiniowane online w skrypcie głównym, to muszą być ograniczone do głównego języka skryptowania. Aby zmienić język skryptowania podprocedury, należy zastosować znaczniki HTML <SCRIPT>. Konieczne jest także dodanie atrybutu RUNAT=SERVER określającego, że skrypt jest przeznaczony dla serwera, a nie dla klienta.
Poniższy przykład ilustruje połączenie różnych języków skryptowych i stylów deklaracji podprocedur w pojedynczy plik ASP:
<%@ LANGUAGE=”VBScript” %> <HTML> <HEAD> <% Sub InlineSub %> This text won’t be displayed until this subroutine is called.<br> <% End Sub %> <SCRIPT LANGUAGE=”VBScript” RUNAT=SERVER> ‘Immediate script (outside a function). Response.Write “This text is displayed last” </SCRIPT> <SCRIPT LANGUAGE=”JavaScript” RUNAT=SERVER> function TestJavaScript(str) { Response.Write(str); } </SCRIPT> <SCRIPT LANGUAGE=”PerlScript” RUNAT=SERVER> sub TestPerlScript { $Response->Write($_[0]); } </SCRIPT> </HEAD> <BODY BGCOLOR=#FFFFFF> <% Response.Write “This is VBScript<br>” TestJavaScript “This is JavaScript<br>” TestPerlScript “This is PerlScript<br>” InlineSub %> </BODY> </HTML>
Uwaga: Znaczniki <SCRIPT> mogą zawierać także główny skrypt serwerowy, ale skrypt ten zostanie uruchomiony dopiero po zakończeniu przetwarzania całej strony. We wcześniejszych wersjach ASP używano znaczniki <SCRIPT> w miejscach, gdzie obecnie używane są nowsze ograniczniki <% %>. Teraz użycie znaczników <SCRIPT> jest zalecane tylko do określenia funkcji i podprocedur.
Wykonywanie skryptów na stronach ASP
Aplikacje ASP muszą działać w środowisku IIS 5.0 i HTTP. Projektanci nie znający dobrze tej architektury często nie rozumieją dziwnych błędów wynikających z wykonania pozornie prostego kodu.
Rozważmy proces przedstawiony na rysunku 6.4.

Rysunek 6.4 Żądanie pliku .asp od IIS 5.0
Gdy przeglądarka klienta żąda strony ASP, mają miejsce następujące zdarzenia:
1.
2.
3.
4.
5.
Proces ten wydaje się prosty, ale należy pamiętać, że komputer kliencki i serwer mogą być oddalone od siebie o setki lub tysiące kilometrów. Dlatego pierwszym etapem rozwiązywania problemów jest ustalenie ich źródła – czy problem dotyczy klienta, czy serwera. Ważne jest także zrozumienie kiedy poszczególne operacje są wykonywane. Po zakończeniu przetwarzania ASP w etapie 3 i wysłaniu odpowiedzi w etapie 4, serwer przechodzi do innych zadań i innych klientów. Aby znów skierować na siebie uwagę serwera, klient musi zażądać kolejnej strony poprzez protokół HTTP. Innymi słowy, nie ma stałego połączenia pomiędzy klientem i serwerem. Jest to bardzo istotny fakt.
Niekiedy projektanci próbują uzyskać dostęp z klienta do obiektów i skryptów serwerowych, albo z serwera do obiektów i skryptów klienckich. Na przykład, rozważmy kod po stronie klienta próbujący uzyskać dostęp do któregoś wbudowanego obiektu ASP, takiego jak obiekt Session. Jest to niemożliwe, ponieważ kod działający na kliencie nie ma żadnego dostępu do obiektu umieszczonego na serwerze. Może pojawić się komunikat błędu, na przykład:
VBS Script Error: Object Required: Session
Teraz rozważmy przykład skryptu serwerowego próbującego manipulować obiektem klienckim. Załóżmy, że programista chce wykorzystać skrypt serwerowy do wypełnienia wartości kontroli klienckiej o nazwie ListBox1, za pomocą następującego polecenia:
<% ListBox1.AddItem Value1 %>
Problem polega na tym, że w momencie wykonania kodu serwerowego strona HTML, a także kontrolka ListBox1, jeszcze nie istnieją. Z tego powodu powyższe polecenie spowoduje błąd.
Z drugiej strony można wykorzystać kod serwerowy do generowania kodu klienckiego, który wykonałby powyższą operację. Na przykład, można utworzyć zdarzenie Window_OnLoad, które zostałoby wykonane przez przeglądarkę po utworzeniu okna i jego kontrol potomnych. W poniższym przykładzie skrypt serwerowy jest używany do dostarczenia metody AddItem z wartościami zawartymi w zmiennych Value1, Value2 i Value3.
<SCRIPT LANGUAGE=”VBScript”> <!-- Sub Window_OnLoad() ListBox1.AddItem “<%= Value1 %>” ListBox1.AddItem “<%= Value2 %>” ListBox1.AddItem “<%= Value3 %>” End Sub --> </SCRIPT>
Uwaga: Gdyby był używany znacznik HTML <SELECT> zamiast kontrolki ActiveX, to procedura byłaby nieco bardziej bezpośrednia. Ponieważ pole listy utworzone za pomocą znacznika <SELECT> jest oparte na kodzie HTML, znaczniki <OPTION> można wygenerować przy użyciu skryptu serwerowego. HTML jest samowystarczający, dlatego zdarzenie Window_OnLoad nie musi zawierać dodatkowego kodu.
Obiekty i komponenty wbudowane po stronie serwera
Pisanie skryptu klienckiego bardzo często wymaga wykorzystania wbudowanych w przeglądarkę obiektów, takich jak document, form i window. Obiekty te są dostarczone jako część modelu obiektów przeglądarki i znacznie upraszczają interakcję z przeglądarką. Podobnie ASP ma zdefiniowany własny model obiektów.
Wyżej wymieniony obiekt Response jest aktualnie jednym z sześciu wbudowanych obiektów: Server, Application, Session, Request, Response, ObjectContext. Obiekty te znacznie upraszczają interakcję pomiędzy serwerem a klientem. Dalej w tej części rozdziału znajduje się opis wszystkich wbudowanych obiektów ASP.
Ponadto można utworzyć i manipulować różnymi niestandardowymi komponentami po stronie serwera. Łącząc aktywne skryptowanie z serwerowymi komponentami COM, zwanymi także obiektami serwerowymi, można rozszerzyć funkcje ASP o potężne, łatwe w obsłudze pakiety. Można utworzyć egzemplarze komponentów serwerowych posługując się metodą CreateObject obiektu Server, przekazując jej wartość ProgID odpowiadającą żądanemu komponentowi. Po utworzeniu egzemplarza komponentu można uzyskać dostęp do jego właściwości lub metody. Na przykład, poniższy skrypt tworzy egzemplarz obiektu serwerowego przy użyciu Server.CreateObject i przechowuje odsyłacz do niego w zmiennej objAdRotator:
<% Set objAdRotator = Server.CreateObject(“MSWC.AdRotator”) %>
Domyślna instalacja ASP zawiera kilka przydatnych komponentów dla początkujących między innymi MyInfo, Ad Rotator i Browser Capabilities. Po instalacji komponentów Microsoft Data Access Components (MDAC), załączonych do IIS 5.0, możliwe będzie, za pomocą ADO, uzyskanie dostępu do danych przechowywanych w SQL Server, Oracle, Microsoft Access lub innej bazie danych
Dlaczego komponenty?
Można spędzić dużo czasu na pisaniu skryptów na stronach ASP wykonujących te same funkcje co komponenty, ale nie jest to zalecane z kilku powodów:
Skrypty działają o wiele wolniej niż skompilowany obiekt i często nie są w stanie
obsługiwać dużych ilości użytkowników.
W skryptach prezentacja nie jest oddzielona od funkcji. Gdy logika użytkowa jest rozsypana po różnych częściach aplikacji, usuwanie błędów jest trudniejsze, a koszty utrzymywania są większe.
W przeciwieństwie do skryptów, komponenty nadają się do wielokrotnego użycia. Komponenty mogą zostać wykorzystane przez inne aplikacje, na przykład aplikacje napisane w Visual Basic lub C++.
Podczas projektowania zadanie powinno brzmieć: im mniej skryptu, tym lepiej. Aby uzyskać aplikacje o wysokiej wydajności i skalowalności, należy zrealizować większość logiki użytkowej za pomocą komponentów.
Co to jest dobry obiekt serwerowy? Generalnie, wszystko, co rozszerza możliwości serwera i języka skryptowego kwalifikuje się jako obiekt serwerowy. Niektóre obiekty serwerowe generuje HTML trudny do utworzenia przy użyciu samego ASP. Inne wykonują typowe dla serwera funkcje, takie jak uzyskanie dostępu do rejestru, wysłanie poczty lub administracja zasobu.
Obiekty serwerowe nie powinny zajmować zbyt dużej ilości pamięci, powinny działać szybko i powinny być dostępne dla wielu współbieżnych użytkowników. Stabilność jest również bardzo ważna. Przecieki pamięci wpłyną na inne aplikacje działające na serwerze i źle działające komponenty mogą spowodować awarię IIS 5.0.
Ponieważ obiekty komponentów ASP znajdują się na serwerze, nie powinny opierać się na elementach interfejsu użytkownika, takich jak okna dialogowe. Komponenty należy skonfigurować tak, aby wysyłały błędy do dziennika zdarzeń Windows 2000 Server lub zwracały szczegółowe informacje o błędach w obiekcie Err, co umożliwia zawiadomienie użytkowników o problemach za pomocą skryptu.
Użyć ponownie, zakupić czy zbudować
Przy wyborze komponentów dla aplikacji, najbardziej korzystną opcją jest ponowne użycie istniejących obiektów. Jeśli brak odpowiednich gotowych komponentów, to należy rozważyć zakup komponentów od renomowanego producenta.
Jeśli brak odpowiedniego komponentu na rynku, to konieczna będzie budowa komponentu niestandardowego. Do zbudowania komponentów serwerowych można użyć każdego narzędzia projektanckiego wspierającego tworzenie serwerów automatyzacji COM, takiego jak Visual Basic, Microsoft Visual J++ lub Microsoft Visual C++. Podobnie jak w przypadku skryptów, należy wybrać język najlepiej odpowiadający potrzebom. Microsoft Visual Basic 6.0 tworzy komponenty wątkowe „Apartment”, które mogą być stosowane do indywidualnych stron. Jeśli dla aplikacji ważne są: szybkość przetwarzania i wsparcie wielu użytkowników, komponent należy zaprojektować za pomocą Visual C lub Visual C++ z Active Template Library (ATL) 2.0. Visual C i Visual C++ tworzą komponenty „obuwątkowe” odpowiednie dla zakresu aplikacji i sesji. Więcej informacji o kwestiach dotyczących wątków znajduje się dalej w tym rozdziale pod hasłem „Wybór zakresu obiektów”.
Więcej informacji o tworzeniu komponentów serwerowych znajduje się w dokumentacji online IIS 5.0, w części „Active Server Pages Guide”, pod hasłem „ASP Tutorial”.
Budowa komponentów skryptowych Windows
Podczas projektowania aplikacji internetowych, zwłaszcza przy użyciu ASP, często okazuje się, że skrypty rosną bardziej niż planowano. Jest to naturalny proces ewolucji typowy dla aplikacji wielowarstwowych. Dodatkowo można zaprojektować komponenty COM wykonujące logikę środkowej warstwy aplikacji.
ASP wspiera komponenty skryptowe Microsoft Windows Script Components, technologię umożliwiającą projektowanie komponentów COM przy użyciu języków skryptowych, takich jak VBScript, Microsoft JScript 2.0, JavaScript 1.1, PERLScript i innych kompatybilnych ze specyfikacją ECMA 262. Komponenty skryptowe Windows są używane w sposób podobny jak inne komponenty COM i przynoszą wiele korzyści:
Umożliwiają realizację zadań skryptowych w formie komponentów COM wielokrotnego użycia.
Umożliwiają łatwe projektowanie prototypów komponentów COM, które po przetestowaniu i zatwierdzeniu zostaną przekształcone przy użyciu odpowiedniego języka programowego.
Podobnie jak inne komponenty COM, udostępniają szeroki asortyment usług systemowych.
Są małe i skuteczne.
Są łatwe do utworzenia, wdrożenia i utrzymywania.
Są wspierane przez Component Services, środowisko działania komponentów COM.
Technologia komponentów skryptów Windows składa się z następujących elementów:
Run-time komponentu (Scrobj.dll).
Programy obsługi interfejsu rozszerzającego run-time. Są to skompilowane komponenty realizujące określone interfejsy COM. Wraz z run-time instalowany jest program obsługi interfejsu Automation, który umożliwia wywołanie komponentu skryptowego z pliku .asp.
Plik komponentu skryptowego (o rozszerzeniu .sct) w którym określa się odpowiedni program obsługi interfejsu i metody dostępne z pliku .asp.
Wbudowane obiekty ASP.
Dostarcza wbudowanych obiektów ułatwiających pobranie informacji zawartych w żądaniu przeglądarki, wysłanie odpowiedzi do przeglądarki i przechowywanie informacji o użytkownikach.
Obiekt Server
Służy do uzyskania dostępu do metod i właściwości na serwerze. Najczęściej używana metoda (Server.CreateObject) tworzy egzemplarz komponentu COM. Inne metody stosują do łańcuchów kodowanie URL lub HTML, mapują ścieżki wirtualne do ścieżek fizycznych i ustawiają limit czasu skryptu.
Obiekt Application
Służy do przechowywania globalnych ustawień aplikacji i udostępniania informacji wszystkim użytkownikom danej aplikacji ASP.
ObiektSession
Służy do przechowywania informacji o danej sesji użytkownika. Wartości zmiennych pozostają w obiekcie Session tak długo, jak użytkownik korzysta z różnych stron tej samej aplikacji. Metody zawarte w obiekcie Session służą także do zamknięcia sesji i ustawienia limitu czasu nieczynnej sesji.
ObiektRequest
Służy do uzyskania dostępu do informacji przekazanych wraz z żądaniem HTTP. Obejmuje to pary nazwa/wartość przekazane z formularza HTML za pomocą metody POST lub GET, “cookies” i certyfikaty klienckie. Obiekt Request daje także dostęp do danych binarnych przekazanych do serwera, takich jak załadowane pliki.
ObiektResponse
Służy do określenia informacji zwracanych do użytkownika. Obejmuje to przesyłanie informacji do przeglądarki, kierowanie przeglądarki do drugiego URL lub ustawianie wartości „cookies”.
Obiekt Context
Służy do zatwierdzenia lub anulowania transakcji uruchomionej przez skrypt na stronie ASP. Więcej informacji znajduje się w rozdziale „Dostęp do danych i transformacji”. Dodatkowo ten obiekt daje dostęp ze środka komponentu do innych wbudowanych obiektów ASP.
Aplikacje ASP
Jak dotąd, w niniejszym rozdziale zaprezentowano kilka przykładów skryptów na stronach ASP dynamicznie tworzących HTML. Jednak strony samodzielne to dopiero początek możliwości ASP. W tej części omówione są sposoby wykorzystania obiektów ASP Session i Application do utworzenia zwartej aplikacji ze zbioru niezależnych plików ASP. Opisane są także różne elementy aplikacji ASP oraz konfiguracja za pomocą Menedżera usług internetowych.
Zarządzanie sesjami w ASP
Ponieważ protokół HTTP nie zachowuje informacji o statusie, serwer internetowy nie pamięta przeszłych wydarzeń, lecz traktuje każde żądanie przeglądarki jako pojedyncze zdarzenie. Cecha ta oznacza, że projektantom trudno jest zapewnić poziom interakcji aplikacji oczekiwany przez większość użytkowników. Trwałe informacje o stanie aplikacji mogą być utrzymywane w bazie danych lub plikach, jednakże takie rozwiązania często są trudne do realizacji, wymagają dużej ilości pamięci i zmniejszają wydajność. ASP rozwiązuje te problemy oferując własny system zarządzania sesjami.
Projektanci mogą wykorzystać wbudowany obiekt ASP Session do przechowywania jakichkolwiek danych, w tym informacji o utworzonych egzemplarzach obiektów. Obiekt Session jest odpowiednikiem tablicy asocjacyjnej, w którym wartości są przechowywane i pobierane za pomocą łańcucha (lub słowa kluczowego) służącego za indeks.
Na przykład, poniższe polecenie przypisuje łańcuch „John Doe” wpisowi tablicy MyName:
<% Session(“MyName”) = “John Doe” %>
Wartość „John Doe” można pobrać z obiektu Session za pomocą słowa kluczowego MyName :
My name is: <%= Session(“MyName”) %>
Obiekt Session jest utrzymywany w pamięci na serwerze podczas trwania sesji internetowej użytkownika. Obiekt ten można wyłączyć na poszczególnych stronach za pomocą deklaracji <%@ EnableSessionState=False %>. Wyłączenie obiektu Session nie zmienia wcześniej przechowanych w nim wartości, ale może przyspieszyć przetwarzanie stron nie korzystających z obiektu Session. Co więcej, strony ASP w zbiorze ramek HTML korzystające z danych o stanie sesji często zostają wykonane seryjnie – wyłączenie obiektu Session w ramkach potomnych, które go nie potrzebują umożliwi równoległe wykonywanie żądań ramek.
Obiekt Application jest używany w podobny sposób, do przechowywania wartości na czas działania aplikacji ASP i do udostępniania wartości wszystkim sesjom użytkowników. Wartości przechowywane w obiektach Session i Application są utrzymywane niezależnie od ilości różnych żądań stron i mogą być pobrane w dowolnym momencie za pomocą przypisanego im słowa kluczowego.
Sesje ASP są oparte na cookies
ASP używa cookies HTTP do przypisania sesjom użytkowników unikalnych kluczy sesji. Po rozpoczęciu sesji ASP, ASP odpowiada na żądanie użytkownika wysyłając nagłówek HTTP Set-Cookie. Od tego momentu każde żądanie przeglądarki będzie zaznaczone odpowiednim identyfikacyjnym cookie.
Klastry internetowe i status sesji ASP
Informacje o sesjach ASP są przechowywane w pamięci na serwerze internetowym, co może stworzyć problemy w przypadku witryn korzystających z ASP w środowisku klastra internetowego. W klastrach żądania użytkowników zostają rozdzielone pomiędzy kilka serwerów internetowych. Obsługa obiektu ASP Session wymaga, aby wszystkie żądania wysłane przez użytkownika w ciągu sesji były obsługiwane przez ten sam serwer. Większość schematów równoważenia obciążenia nie zapewnia takiej możliwości. Jeśli ASP ma być używany w klastrze internetowym, istnieje kilka rozwiązań:
Napisanie niestandardowej logiki zarządzania sesjami i zastąpienie logiki ASP.
Informacje o sesjach należy utrzymywać w centralnym miejscu, na przykład w bazie danych.
Zastosowanie rozwiązania zewnętrznego producenta. Na przykład, Cisco Systems oferuje LocalDirector, który może zrównoważyć obciążenie w taki sposób, aby klient podłączający się wielokrotnie zawsze był obsługiwany przez ten sam serwer.
Zastosowanie trybu równoważenia obciążenia obejmującego tylko nowe żądania, w którym późniejsze żądania tej samej sesji zostają przesłane do tego samego serwera. Metoda ta nazywa się równoważeniem obciążenia ASP z uwzględnieniem sesji.
Równoważenie obciążenia ASP z uwzględnieniem sesji
W tym scenariuszu, wszystkie nowe żądania przesłane do URL witryny zostają rozdzielone przez istniejące mechanizmy równoważenia obciążenia, takie jak cykliczny Domain Name System (DNS). Następnie, gdy nastąpi zdarzenie Session_OnStart, skrypt na stronie ASP korzysta z obiektu Response do skierowania przeglądarki na stronę domową aplikacji za pomocą adresu Internet Protocol (IP) lub unikalnej nazwy komputera, na przykład:
Response.Redirect(“http://w10.microsoft.com/Webapp/firstpage.asp”)
Aby zmusić przeglądarkę do ograniczenia żądań do tego samego serwera, wszystkie odsyłacze aplikacji muszą być relatywnymi URL. Relatywne URL określają ścieżkę względną opartą na bieżącym adresie, na przykład:
<A HREF=”MyAsp.Asp”>...</A>
<FORM METHOD=POST ACTION=”./SubDir/FormAction.asp”>...</FORM>
Po wyborze takiego odsyłacza przeglądarka zbuduje pełną ścieżkę URL za pomocą bieżącego adresu (określonego w skierowaniu) i URL relatywnego. W ten sposób przeglądarka znajdzie właściwy komputer obsługujący sesję użytkownika. W przypadku niektórych aplikacji internetowych metoda ta może być nieodpowiednia. Dodatkowo, jeśli użytkownicy zachowują adresy URL w przeglądarkach za pomocą Ulubionych lub zakładek, to zawsze wrócą do określonego komputera, co mija się z celem stosowanego rodzaju równoważenia obciążenia.
Poniższy przykład ilustruje cookie ASP identyfikujące sesję:
Set-Cookie: ASPSESSIONIDGGGGGJZB=EFENHLNDIIEHJGJOAGICNPEK; path=/
We wcześniejszych wersjach ASP ścieżka cookie zostałaby ustawiona na wirtualny katalog aplikacji ASP. W IIS 5.0, jedno cookie wystarcza dla wszystkich aplikacji na serwerze. Po otrzymaniu cookie każde żądanie przeglądarki będzie zawierać ten sam nagłówek HTTP:
Cookie: ASPSESSIONIDGGGGGJZB=EFENHLNDIIEHJGJOAGICNPEK
ASP wykorzystuje tę wartość do pobrania odpowiedniego obiektu Session dla połączenia klienta. Wszystkie żądania przesłane do katalogu aplikacji zawierają cookie identyfikacyjne sesji, nawet żądania statycznej zawartości HTML umieszczonej w podkatalogach aplikacji ASP. W przykładzie, cookie nie określa terminu ważności, dlatego zachowuje ważność tak długo, jak sesja pozostaje otwarta. Gdy użytkownik zamknie przeglądarkę, cookie przestanie obowiązywać.
Uwaga: Jeśli użytkownik nie zaakceptował cookie ASP (lub przeglądarka nie zwróci go w późniejszych żądaniach), to aplikacja nie będzie mapować żądania do istniejącego obiektu Session – musi utworzyć nowy obiekt.
Możliwa jest sytuacja, w której kilka egzemplarzy przeglądarki używa tego samego cookie (czyli różne okna przeglądarki mogą korzystać jednocześnie z różnych części aplikacji) i modyfikują ten sam obiekt Session. Sytuacja taka jest szczególnie niefortunna w przypadku aplikacji korzystających w dużym stopniu z informacji o stanie sesji. Jest to kolejna przyczyna, dla której należy ograniczyć do minimum korzystanie z informacji o stanie sesji.
Identyfikatory sesji ASP są mapowane do obiektu Session umieszczonego w pamięci na serwerze. Jest to skuteczne rozwiązanie w przypadku, gdy sesją użytkownika zarządza pojedynczy serwer. W przypadku klastra serwerów żądanie użytkownika może być obsługiwane przez więcej niż jeden serwer. Więcej informacji o zarządzaniu identyfikatorami sesji w klastrze znajduje się wcześniej w tym rozdziale pod hasłem „Klastry internetowe i status sesji ASP”.
Identyfikatory sesji ASP nie są unikalne
Aplikacje wymagające unikalnego identyfikatora użytkownika nie powinny używać identyfikatorów sesji ASP, które są unikalne tylko w okresie działania bieżącej aplikacji. Po restarcie aplikacji serwer może przypisać ten sam identyfikator drugiemu użytkownikowi. W środowisku zawierającym wiele serwerów, takim jak klaster internetowy, prawdopodobieństwo powtórzenia się identyfikatorów jest większe. Dlatego nie zaleca się używania identyfikatora sesji ASP jako unikalnego klucza tabel, ani jako stałej metody identyfikowania użytkowników.
Aby utworzyć identyfikatory unikalne na wszystkich serwerach i dla wszystkich sesji, należy wykorzystać inny mechanizm. Component Services zawiera komponent TakeANumber, który generuje unikalne numery seryjne do identyfikowania użytkowników. Więcej informacji znajduje się poniżej pod hasłem „TakeANumber: przykład komponentu należącego do Component Services”.
TakeANumber: przykład komponentu należącego do Component Services
Component Services zawiera komponent TakeANumber generujący seryjne numery identyfikacyjne. Ponieważ przyrost numeru jest częścią transakcji, to jest gwarancja, że identyfikator zachowa swoją unikalność na innych serwerach i sesjach. Komponent TakeANumber zostaje zainstalowany wraz z Component Services, ale przed uruchomieniem wymaga pewnych przygotowań. Przede wszystkim należy zdefiniować tabelę SQL Server do przechowywania bieżącego numeru. Tabela musi nosić nazwę „TakeANumber” i zawierać dwie kolumny o nazwach „NextNumber” (typu liczby całkowitej) i „PropertyGroupName” (typu łańcucha). Kolumna PropertyGroupName określa używany licznik — tabela może zawierać wiele liczników. Po przygotowaniu tabeli należy wpisać pierwszy numer serii. Aby to wykonać, należy wysłać polecenie SQL, na przykład:
INSERT INTO TakeANumber VALUES (1234, ‘MyProp’)
Na końcu należy utworzyć dla pliku nazwę źródła danych (DSN), za pomocą której komponent może uzyskać dostęp do nowej tabeli. Plikowy DSN można utworzyć przy użyciu aplikacji Źródła danych (ODBC) pod Narzędziami administracyjnymi w Panelu sterowania. Dokładne instrukcje znajdują się w rozdziale „Dostęp do danych i transakcji”.
Komponent jest już gotowy do uruchomienia. Kolejny numer pobiera się z serii MyProp za pomocą następujących poleceń:
<%@ LANGUAGE=VBScript EnableSessionState=False %> <HTML> <HEAD><TITLE>Take A Number</TITLE></HEAD> <BODY BGCOLOR=#FFFFFF> <% Set tn = Server.CreateObject (“MTS_TakeANumber.TakeANumber”) %> Next Number: <%= tn.GetANumber (“TakeANumber.dsn”, “MyProp”) %> </BODY> </HTML>
Unikalność identyfikatora jest zagwarantowana, pod warunkiem korzystania przez wszystkie serwery z jednej bazy danych TakeANumber.
Identyfikatory sesji ASP i zabezpieczenie sesji
Zastosowanie w zarządzaniu sesji metody opartej na cookies może spowodować problemy związane z zabezpieczaniem. Gdyby nieupoważniona osoba znalazła lub odgadła identyfikator używany przez aktywną sesję, to osoba ta mogłaby wysłać żądania zawierające to cookie i w ten sposób wykonać czynności w imieniu użytkownika sesji. Na przykład, gdyby skrypt ASP przechował w obiekcie Session informacje o karcie kredytowej użytkownika, to nieupoważniona osoba mogłaby dokonać zakupów na jego rachunek. Z tego powodu, przy generowaniu identyfikatorów sesji ASP stosowane są następujące zabezpieczenia:
Identyfikatory sesji są 32-bitowymi liczbami całkowitymi.
Po każdym restarcie serwera internetowego wartość początkowa identyfikatorów
zostaje wybrana losowo.
Utworzenie każdej nowej sesji ASP powoduje przyrost bieżącej wartości używanej
do identyfikatorów.
Identyfikator 32-bitowy zostaje zmieszany z danymi losowymi i zaszyfrowany, dając cookie stanowiące łańcuch 16 znaków. Po otrzymaniu cookie łańcuch zostaje rozszyfrowany w celu odnalezienia identyfikatora sesji.
Klucz szyfrowy zostaje wybrany losowo po każdym restarcie serwera.
Identyfikatory sesji ASP są wybierane spośród ogromnej ilości potencjalnych wartości i podlegają szyfrowaniu, dlatego przechwycenie ważnego cookie jest bardzo trudne. Co więcej, odgadnięcie wartości jednego cookie nie umożliwia przewidzenia wartości drugiego.
Jeśli algorytm stosowany przez ASP do produkcji cookies nie spełnia wymagań danej witryny co do zabezpieczenia, można dodatkowo użyć identyfikacji użytkowników i certyfikatów klienckich. Więcej informacji na ten temat znajduje się w rozdziale „Zabezpieczenia”.
Budowanie aplikacji ASP
W najprostszej formie, aplikacja ASP składa się ze wszystkich plików HTML i skryptów przechowywanych w obrębie aplikacji. Przed utworzeniem jakichkolwiek sesji aplikacja zostaje zainicjowana, tworzy egzemplarze odpowiednich komponentów i importuje deklaracje bibliotek typów. Od tego momentu każdy użytkownik posiada odrębną sesję zawierającą własne wartości i egzemplarze komponentów. W tej części omówione są sposoby zarządzania aplikacjami i sesjami.
Granice aplikacji
Aplikacja ASP składa się ze wszystkich plików znajdujących się w głównym katalogu wirtualnym i w ewentualnych podkatalogach. Aplikacja definiuje przestrzeń nazwy (zwaną także korzeniem aplikacji) zaczynającą od katalogu głównego i obejmującą wszystkie zawarte w nim pliki, katalogi i katalogi wirtualne, z wyjątkiem tych, które same są korzeniami innych aplikacji lub należą do korzeni innych aplikacji. Na przykład, jeśli katalog wirtualny „Applications” i podkatalog „Isolated Applications” są korzeniami aplikacji, to adresy URL zawierające tylko „/Application” będą należeć do jednej aplikacji, a URL zawierające „/Application/Isolated Application” do drugiej. Rysunek 6.5 przedstawia zastosowanie tej zasady w Menedżerze usług internetowych.

Rysunek 6.5 Korzenie aplikacji i katalogi wirtualne
Na rysunku 6.5 katalogi wirtualne — ASP i ISAPI — są zawarte w przestrzeni nazwy Applications. Katalogi wirtualne Isolated ASPs i Isolated ISAPIs należą do drugiej aplikacji.
Projektanci aplikacji mogą narzucić logiczny podział na aplikacje posiadające osobne korzenie. Wszystkie zmienne typu Application i Session utworzone w przestrzeni nazwy aplikacji są oddzielone od zmiennych Application i Session, należących do innych aplikacji działających na serwerze. Aktualnie nie ma sposobu uzyskania dostępu do wartości należących do innych aplikacji.
Global.asa
Plik Global.asa służy do przechowywania informacji używanych globalnie przez aplikację. Plik ten nie generuje zawartości wyświetlanej użytkownikom. Plik Global.asa musi być przechowywany w punkcie wyjściowym aplikacji (zazwyczaj w katalogu głównym). Aplikacja może posiadać tylko jeden plik Global.asa.
Pliki Global.asa zawierają tylko: zdarzenia Application, zdarzenia Session, deklaracje obiektów i deklaracje bibliotek typów. Jeśli plik zawiera tekst nie umieszczony pomiędzy znacznikami <SCRIPT> lub definiuje obiekt o zakresie innym niż zakres sesji lub aplikacji, to serwer zwróci komunikat błędu. Skrypt nie wykorzystany przez zdarzenia aplikacji i sesji jest ignorowany przez serwer, podobnie jak ewentualny HTML występujący w pliku.
Zdarzenia Application i Session
Z każdą aplikacją są związane dwa zdarzenia: Application_OnStart oraz Application_OnEnd. Skrypt dotyczący tych zdarzeń jest zdefiniowany za pomocą znaczników <SCRIPT> po stronie serwera, w pliku Global.asa. Skrypt ten może być napisany w każdym języku wspieranym przez serwer. Zdarzenie Application_OnStart zostaje wywołane raz dla każdej aplikacji, gdy pierwszy klient zażąda strony zawartej w granicach aplikacji. Procedura zdarzenia Application_OnStart jest dobrym miejscem na ustawienie globalnych zmiennych i ewentualnie na utworzenie obiektów, które mają być dostępne wszystkim użytkownikom aplikacji.
Po zdarzeniu Application_OnStart otwarcie każdej nowej sesji spowoduje zdarzenie Session_OnStart. W tym momencie aplikacja ASP powinna wykonać ewentualne zadania związane z inicjacją sesji. Istnieje obiekt Session oraz obiekt Request. Obiekt Session zawiera unikalny identyfikator sesji. Obiekt Request zawiera rozłożone zbiory wartości przekazane przez przeglądarkę oraz serwerowe zmienne środowiskowe.
Procedura zdarzenia Session_OnStart jest dobrym miejscem na skierowanie aplikacji do jej strony startowej. Jeśli nie zostanie to wykonane, aplikacja rozpocznie od dokumentu żądanego w URL lub któregoś dokumentu domyślnego ustawionego dla głównego wirtualnego katalogu aplikacji w Menedżerze usług internetowych.
Ponieważ podczas przetwarzania procedur zdarzeń metoda Response.Write nie jest dostępna, prawdopodobnie zwracanie ewentualnych błędów będzie niemożliwe. Aby zawiadomić użytkownika o problemach, komunikat błędu można zachować w obiekcie Session lub Application (zależnie od źródła błędu) i później dodać go do pierwszej wysłanej strony.
Sesja kończy się po przekroczeniu limitu czasu lub po wywołaniu metody Session.Abandon. Na tym etapie wywołuje się procedurę zdarzenia Session_OnEnd, w której można usunąć egzemplarze obiektów i wykonać inne zadania związane z zakończeniem sesji. Spośród wbudowanych obiektów serwerowych tylko Application, Session i Server są dostępne procedurze zdarzenia OnEnd. Ponadto nie można korzystać z metod MapPath i CreateObject obiektu Server w przetwarzaniu zdarzenia Session_OnEnd.
Zakończenie sesji ASP
Nie istnieje sposób sprawdzenia, czy użytkownik jest wciąż aktywnie podłączony do aplikacji, chyba że stosowany jest system jawnego wyrejestrowywania się. Protokół HTTP nie zachowuje informacji o statusie i nie śledzi połączeń użytkowników.
Z tej przyczyny ASP stosuje mechanizm zamykający nieczynną sesję po upływie określonego czasu. Gdy użytkownik rozpoczął sesję, ale przestał wysyłać żądania do aplikacji internetowej, ASP automatycznie włączy zdarzenie Session_OnEnd. Domyślny limit czasu wynosi 20 minut, ale można zmienić go ustawiając właściwość Timeout obiektu Session. Zmienić można także wartość domyślną.
v
1.
2.
3.
W przypadku aplikacji buforujących połączenia z bazą danych lub wyczerpujących dużą ilość zasobów serwerowych, limit czasu sesji może oznaczać czas, w którym inni użytkownicy nie mają dostępu do zasobów serwera. W takim przypadku należy rozważyć umożliwienie zakończenia sesji przez użytkownika, za pomocą przycisku Wyloguj. Kliknięcie tego przycisku spowodowałoby wywołanie metody Session.Abandon, która automatycznie włączy zdarzenie Session_OnEnd.
Cecha limitu czasu jest równie kłopotliwa w przypadku aplikacji korzystających z zasobów wymagających identyfikacji użytkownika. Jeśli użytkownik ignoruje aplikację przez zbyt długi czas, aplikacja zakończy sesję i zamknie ustanowione połączenia. Jeśli następnie użytkownik wyśle kolejne żądanie, to aplikacja może zachować się w sposób nieoczekiwany.
Problemy związane z limitem czasu można rozwiązać przy pomocy dobrego planowania. Popularna metoda wykrywania przerwanych sesji polega na przechowywaniu właściwości SessionID obiektu Session jako zmiennej Session. Za każdym razem, gdy użytkownik odwiedzi stronę wymagającą ważnego połączenia, należy porównać bieżącą wartość SessionID z identyfikatorem przechowywanym w obiekcie Session. Jeśli wartości są nierówne (lub zmienna Session jest pusta), oznacza to wykrycie przerwanej sesji i można wykonać odpowiednie czynności.
Import stałych z bibliotek typów za pomocą Global.asa
Zazwyczaj biblioteki typów komponentów COM zawierają listę nazwanych stałych, wraz z innymi informacjami o komponencie, umożliwiającymi jego automatyzację przez inne aplikacje.
Jeśli aplikacja internetowa korzysta z komponentu COM, którego biblioteka typów zawiera wyliczone typy danych, możliwy jest import typów do przestrzeni aplikacji za pomocą Global.asa. Umożliwia to wykorzystanie tych typów danych w dowolnym skrypcie znajdującym się wewnątrz granicy aplikacji. Składnia importująca bibliotekę typów wygląda następująco:
<!--METADATA TYPE=”TypeLib” NAME=”typelibraryname” FILE=”file” UUID=”typelibraryuuid” VERSION=”majorversionnumber.minorversionnumber” -->
Obowiązkowe jest podanie parametru File lub parametru UUID, ale podanie obydwu spowoduje, że aplikacja będzie bardziej mobilna. Parametr Name przyda się przy ustalaniu jednolitego systemu interpretacji stałych o identycznej nazwie, pochodzących z różnych bibliotek typów. W poniższym przykładzie importowane są stałe deklarowane w bibliotece typów ADO:
<!--METADATA TYPE=”TypeLib” NAME=”ADO” FILE=”C:\Program Files\Common Files\System\ado\msado15.dll” UUID=”00000200-0000-0010-8000-00AA006D2EA4” VERSION=”2.0” -->
Deklaracja obiektów w Global.asa
W pliku Global.asa można deklarować obiekty o zakresie sesji lub aplikacji za pomocą rozszerzonego znacznika <OBJECT>. Znacznik ten nie jest umieszczany pomiędzy znacznikami <SCRIPT>. Oprócz parametrów ID i ClassID należy ustawić SCOPE (na wartość „Session” lub „Application”) i RUNAT=SERVER. W poniższym przykładzie utworzony zostaje egzemplarz komponentu Page Counter:
<OBJECT ID=GlobalPageCounter SCOPE=Application RUNAT=Server CLASSID=”clsid:4B0BAE86-567A-11D0-9607-444553540000”> </OBJECT>
Po zdefiniowaniu obiektu GlobalPageCounter w Global.asa, można z niego skorzystać z każdego pliku ASP należącego do aplikacji bez konieczności pobierania go z obiektu Application lub Session, ani wcześniejszego wywołania Server.CreateObject:
There have been <%= GlobalPageCounter.Hits(“default”) %> hits.
Uwaga: W celu oszczędności miejsca, egzemplarze obiektów zadeklarowanych w Global.asa za pomocą znaczników <OBJECT> nie zostają utworzone, dopóki serwer nie wykona skryptu korzystającego z danego obiektu.
Wybór zakresu obiektów
Komponenty mogą istnieć i funkcjonować w zakresie aplikacji lub sesji. Utworzenie i usunięcie komponentów na poziomie strony także jest możliwe.
Obiekty przechowywane w obiekcie Application są dostępne wszystkim użytkownikom aplikacji. Obiekt Application jest dobrym miejscem do przechowywania obiektów nie związanych z poszczególnymi użytkownikami, takich jak liczniki stron. Zazwyczaj, wartości i obiekty o zakresie aplikacji zostają utworzone po uruchomieniu aplikacji i są dostępne “tylko do odczytu” użytkownikom aplikacji. Podczas modyfikacji wartości w obiekcie Application, należy zastosować metody Lock i Unlock w celu tymczasowego uniemożliwienia użytkownikom dostępu do danych.
Z reguły niewiele obiektów powinno otrzymać zakres aplikacji. Obiekty powinny wspierać model „obuwątkowy”, ponieważ obiekty oparte na modelu wątkowym „Apartment” zmuszają obiekt Application do działania w pojedynczym wątku, a komponenty o wolnych wątkach zwykle działają wolniej. Komponenty COM nie powinny otrzymać zakresu aplikacji, ponieważ zostałyby utworzone natychmiast po uruchomieniu aplikacji, pomimo że mogą być potrzebne dopiero później.
Ponieważ celem obiektu Session jest przechowywanie informacji o sesji danego użytkownika, komponenty umieszczone w tym obiekcie mogą istnieć aż do momentu zakończenia sesji. Każda wartość i każdy obiekt przechowywany w obiekcie Session oznacza większe zapotrzebowanie na pamięć serwera dla każdego użytkownika aplikacji, dlatego wartości nie powinny być przechowywane dłużej, niż są one potrzebne.
Obiekty o zakresie strony zostają utworzone po otrzymaniu każdego żądania strony. Może być stosowany dowolny model wątkowy, ale dla skalowalnych aplikacji zaleca się model „Apartment” lub obuwątkowy.
Izolacja procesów i odtworzenie po awarii
Oprócz umożliwienia użycia transakcji na zwykłych stronach internetowych, kombinacja IIS 5.0 z Component Services oferuje jeszcze jedną ważną możliwość: izolację procesów.
Aplikacje i procesy
Przy rozszerzaniu serwera internetowego zawsze konieczne były kompromisy pomiędzy wydajnością a bezpieczeństwem. We wczesnych wersjach IIS, wszystkie aplikacje ISAPI (w tym ASP) korzystały z tych samych zasobów i pamięci co proces serwera. Układ taki zapewniał maksymalną wydajność, jednakże niestabilne komponenty mogły spowodować awarię serwera, do czego nie można dopuścić w przypadku ważnych aplikacji, takich jak IIS. W dodatku rozładowanie komponentów działających wewnątrz procesu wymagało restartu serwera, dlatego przy aktualizacji istniejących komponentów wszystkie witryny musiały być zrestartowane, nawet witryny nie związane z aktualizowanym komponentem.
Uruchomienie wyizolowanych procesów w IIS 5.0 pozwala osiągnąć tę samą wydajność co model ISAPI/ASP oraz ten sam poziom bezpieczeństwa co model CGI. Umieszczenie procesów aplikacji we własnym obszarze chroni cały serwer internetowy przed niespodziewanymi błędami aplikacji. Jest to zasadniczy cel izolacji procesów.

Rysunek 6.6 Przepływ procesów aplikacji IIS 5.0 działających wewnątrz i na zewnątrz procesów
Aplikacje zewnątrzprocesowe działają we własnych procesach, oddzielnie od pozostałych części IIS 5.0. Gdy przeglądarka żąda pliku ASP, w pierwszej kolejności serwer internetowy przydziela żądaniu wątek z puli. Następnie IIS 5.0 ustala sposób obsługi żądanego pliku w zależności od wewnętrznych map Multipurpose Internet Mail Extensions (MIME) i map skryptowych. W przypadku plików ASP wywołany zostaje filtr ISAPI dla ASP.
Następnie Menedżer aplikacji internetowych (WAM) ustala, czy plik jest częścią aplikacji zaznaczonej do uruchomienia w osobnym obszarze pamięci. Jeśli tak, to żądanie zostanie obsłużone przez zewnętrzny proces Component Services. Component Services jest środowiskiem działania dla komponentów COM zawierających obiekt proxy WAM dla każdego wyizolowanego procesu. W przeciwnym przypadku żądanie zostanie obsłużone wewnątrz procesu przez IIS 5.0. WAM obsługuje wszystkie aplikacje internetowe, wewnątrzprocesowe i inne, a także zawiera kontrolki ładujące i wykorzystujące pliki DLL ISAPI. WAM także jest komponentem COM i może działać wewnątrz procesu IIS 5.0 lub w procesie wyizolowanym. Istnieją trzy główne przyczyny, dla których aplikacja może być uruchomiona w procesie wyizolowanym: projektowanie komponentów, lokalizacja błędów oraz ochrona witryn.
Projektowanie komponentów
Izolacja procesów umożliwia zatrzymanie i restart pojedynczej aplikacji bez konieczności odłączania całego serwera. Zaktualizowany komponent można dodać do aplikacji za pomocą Menedżera usług internetowych.
v
1.
2.
Po wymianie starego komponentu IIS 5.0 zrestartuje aplikację, gdy tylko otrzyma pierwsze żądanie.
Lokalizacja błędów
Dzięki izolacji procesów efekty awarii są ograniczone do pojedynczej aplikacji, która ją spowodowała. Dodatkowo aplikacja może być tak skonfigurowana, aby restartować się automatycznie. W przypadku krytycznego błędu proces aplikacji zostaje automatycznie zamknięty. Ponieważ aplikacja działa w procesie systemowym Component Services, to anulowane są wszystkie dokonywane transakcje. Informacja o błędzie zapisywana jest w dzienniku zdarzeń Windows®, a Component Services restartuje aplikację. Efekty awarii są odczuwane tylko przez klientów czekających na wyniki pochodzące z tej jednej aplikacji.
Bezpieczeństwo witryn
Izolacja procesów w Component Services umożliwia użycie nieprzetestowanych lub niestabilnych aplikacji bez ryzyka uszkodzenia całego serwera. Serwer internetowy może wówczas tolerować błędy i praca klientów innych aplikacji zostaje tylko minimalnie zakłócona. Izolacja niestabilnych aplikacji w osobnym obszarze pamięci może zapobiec awarii całej witryny.
Konfiguracja procesu wyizolowanego
Domyślnie, aplikacje IIS 5.0 działają wewnątrz procesu IIS 5.0. Aby uruchomić aplikację w osobnym procesie, należy skonfigurować ją w Menedżerze usług internetowych.
v
1.
2.
3.
Menedżer usług internetowych automatycznie utworzy pakiet Component Services dla danej aplikacji. Na przykład, gdyby skonfigurowano w wyżej omówiony sposób aplikację IIS 5.0 Help, to utworzony zostałby nowy pakiet Component Services o nazwie IIS-{Default Web Site//Root/IISHELP/}. Komponenty transakcyjne do uruchomienia w kontekście nowego procesu można zainstalować w pakiecie za pomocą Menedżera usług internetowych.
Komponenty zewnątrzprocesowe
Komponenty zewnątrzprocesowe są to komponenty COM zrealizowane jako pliki wykonywalne – są one uruchamiane w osobnym procesie na tym samym komputerze co aplikacja kliencka. Komponenty zewnątrzprocesowe, zwane także „serwerami lokalnymi” różnią się od aplikacji zewnątrzprocesowych (procesów wyizolowanych). Po uruchomieniu komponentu zewnątrzprocesowego na serwerze internetowym, IIS 5.0 staje się aplikacją kliencką.
Obiekty COM są realizowane wewnątrz serwera. W większości przypadków serwer COM jest zrealizowany jako plik DLL wykonywany w tym samym procesie co aplikacja kliencka. Czasami serwer COM jest realizowany jako plik wykonywalny działający w oddzielnym od klienta procesie. Na przykład, gdy utworzony zostaje egzemplarz serwera Active Document takiego jak Microsoft Word, uruchomiona zostaje kopia aplikacji serwerowej. Gdy egzemplarz tego typu obiektu zostaje utworzony z ASP, otwarty zostaje nowy proces na serwerze internetowym. Ponieważ serwer Active Document jest plikiem wykonywalnym, a nie DLL, to nie można ładować go do procesu IIS 5.0.
Gdy komponent zostaje uruchomiony na zewnątrz procesu na stronie ASP za pomocą Server.CreateObject, a IIS 5.0 nie jest odpowiednio skonfigurowany dla komponentów zewnątrzprocesowych, zwrócony zostanie następujący komunikat błędu:
Server object error ‘ASP 0196’ Cannot launch out of process component /myvroot/launch_exe.asp, line 16
Przyczyną tego jest mechanizm bezpieczeństwa ASP uniemożliwiający bezpośrednie uruchamianie plików wykonywalnych (ale nie DLL) z ASP.
Ten mechanizm zabezpieczający jest stosowany z kilku przyczyn. Nie wszystkie pliki wykonywalne są bezpieczne dla serwera, niektóre mogą stwarzać problemy związane z zabezpieczeniem. Po stronie serwera zaleca się użycie wewnątrzprocesowych komponentów DLL– są one szybsze i bezpieczniejsze oraz mogą być obsługiwane przez Component Services.
Komponenty zewnątrzprocesowe często tworzą osobne procesy serwerowe dla każdego egzemplarza obiektu, co oznacza zmniejszenie wydajności do poziomu aplikacji CGI. Są one po prostu mniej skalowalne niż komponenty DLL działające w procesie IIS 5.0 lub Component Services. Jeśli wydajność i skalowalność są w przypadku danej witryny ważne, nie zaleca się używania komponentów zewnątrzprocesowych. Z drugiej strony, w mniej obciążonych witrynach sieci wewnętrznych użycie komponentu zewnętrznego może nie mieć wpływu na ogólną wydajność witryny.
Używanie metabazy
Metabaza IIS 5.0 zawiera ustawienia konfiguracyjne dla IIS 5.0. Wykonuje ona częściowo te same funkcje co rejestr systemowy, ale jest bardzo często używana. Do jej administracji stosuje się Microsoft Active Directory Service Interfaces (ADSI).
Aby umożliwić użycie komponentów zewnątrzprocesowych, należy ustawić właściwość metabazy IIS 5.0 AspAllowOutOfProcComponents na wartość TRUE. Ustawienie to jest dostępne z obiektu administracyjnego IIsWebService lub IIsWebVirtualDir.
Jeśli do ustawienia AspAllowOutOfProcComponents na TRUE wykorzystano obiekt IIsWebService, to wszystkie aplikacje wewnątrzprocesowe mogą uruchomić pliki wykonywalne ze skryptu. Aplikacja wewnątrzprocesowa jest katalogiem wirtualnym zaznaczonym jako punkt początkowy aplikacji, dla którego opcja Uruchom w oddzielnym obszarze pamięci w Menedżerze usług internetowych nie jest włączona.
Jeśli do ustawienia AspAllowOutOfProcComponents na TRUE wykorzystano obiekt IisWebVirtualDir i obiekt ten zawiera aplikację z włączoną opcją Uruchom w oddzielnym obszarze pamięci jako proces wyizolowany, to tylko ta aplikacja może uruchomić pliki wykonywalne ze skryptu. Jeśli aplikacja działa wewnątrz procesu, to ustawienie nie ma żadnego skutku.
Modyfikacja metabazy IIS 5.0 wymaga odpowiednich uprawnień. Użytkownik próbujący zmodyfikować ją bez uprawnienia otrzyma komunikat błędu.
Poniższy kod ASP ilustruje ustawienie parametru AspAllowOutOfProcComponents w obiekcie administracyjnym IIsWebService. Po dokonaniu zmiany należy zrestartować usługę serwera internetowego (zatrzymując i ponownie uruchamiając usługę administracyjną IIS w Menedżerze kontroli usług).
<% ‘Get the IIsWebService Admin object. Set oWebService = GetObject(“IIS://LocalHost/W3svc”) ‘Enable AspAllowOutOfProcComponents. oWebService.Put “AspAllowOutOfProcComponents”, True ‘Save the changed value to the metabase. oWebService.SetInfo %>
Kwestie dotyczące zabezpieczeń
Aplikacje i komponenty zewnątrzprocesowe, w tym rozszerzenia ISAPI, nie mają dostępu do właściwości metabazy IIS 5.0 poprzez wbudowane w IIS 5.0 obiekty administracyjne. Celem tego ograniczenia jest uniemożliwienie nieupoważnionych zmian w metabazie. Aby udostępnić metabazę aplikacjom zewnątrzprocesowym, należy zmienić tożsamość zewnątrzprocesowego pakietu Component Services z użytkownika interaktywnego na konto określonego użytkownika i nadać temu kontu uprawnienia dostępu do metabazy. Jest to ryzykowne, ale ryzyko jest ograniczone do pojedynczego pakietu aplikacji.
Uwaga dotycząca testowania aplikacji
Testowanie wydajności, zwłaszcza przy dużej liczbie użytkowników, jest niezbędnym elementem projektowania aplikacji internetowych i musi być brane pod uwagę podczas ogólnego planowania aplikacji. Testy wydajności są o wiele ważniejsze w przypadku aplikacji serwerowych niż w przypadku aplikacji pulpitowych, ponieważ aplikacja serwerowa może być obciążona dużą liczbą równoczesnych użytkowników.
Należy pamiętać, że przechowywanie wartości w obiekcie Session wymaga większej ilości pamięci, dlatego powoduje zmniejszenie maksymalnej liczby równocześnie obsługiwanych użytkowników. Przy budowaniu aplikacji należy brać pod uwagę trzy następujące czynniki wykorzystania pamięci:
Współbieżne sesje Liczba sesji istniejących w danym momencie zależy od czasu utrzymywania obiektu Session. Jeśli wartość limitu czasu Session.Timeout wynosi 20 minut, to liczba współbieżnych sesji będzie równa liczbie połączeń obsłużonych w ciągu 20 minut.
Zmienne i obiekty należące do sesji Ile jest przechowywanych obiektów i zmiennych? Niewielka ilość ustawień dotyczących poszczególnych sesji nie spowoduje problemów, ale należy unikać długich list zmiennych o zakresie sesji (szczególnie komponentów). Gdy liczba zmiennych jest duża, to pobieranie ich wartości odbywa się wolno.
Wielkość przechowywanych zmiennych i obiektów Jeśli przechowywane są długie łańcuchy lub duże komponenty, należy je utrzymywać tylko tak długo, jak są potrzebne. Później należy zwolnić miejsce, zastępując długie łańcuchy łańcuchem pustym i nadając obiektom wartość Nothing (lub Null).
Metody projektowania aplikacji internetowych
Przy projektowaniu aplikacji internetowych może się okazać, że model używany do aplikacji w Internecie jest sprzeczny z modelem koncepcyjnym opracowanym dla innych platform. Na przykład, jeśli nie są używane klienckie kontrolki ActiveX ani aplety Java, to interfejs użytkownika będzie ograniczony do opisu HTML danych wprowadzonych na formularzach i listy odsyłaczy do innych części witryny. Pomimo dostępności DHTML i ASP, większość aplikacji internetowych składa się po prostu z serii połączonych z sobą dynamicznie produkowanych stanów statycznych. Gdy użytkownik kliknie przycisk, to coś się stanie – gdy kliknie odsyłacz, to pojawi się nowa strona.
W tej ostatniej części rozdziału omówione są sposoby projektowania aplikacji internetowych i różne metody udoskonalania aplikacji.
Rozkładanie aplikacji na elementy
Aplikacja internetowa jest hierarchią powiązanych z sobą stron, z których każda odpowiada innemu etapowi aplikacji. Aplikacje internetowe przyjmują serię zdarzeń wejściowych i za pomocą skończonej liczby elementów produkują odpowiednią serię zdarzeń wyjściowych.
Większość aplikacji internetowych korzysta (lub powinna korzystać) z następujących elementów: zawartości, hiperłączy, formularzy, komponentów, czynności serwerowych, przeadresowania i pętli.
Zawartość — informacje przedstawione w postaci tekstu, grafiki lub nawet plików muzyki i wideo — jest najbardziej powszechnym elementem większości aplikacji internetowych. Zawartość może być przedstawiona na statycznych stronach HTML lub generowana dynamicznie przez stronę ASP. Elementy zawartości zwykle posiadają jeden dobrze zdefiniowany punkt wejścia oraz odsyłacze do innych stron.
Hiperłącza – głównym celem hiperłączy jest umożliwienie przejścia do innych stron lub do innych części tej samej strony. Przykładami hiperłączy są: mapy witryn, paski narzędzi, HREF, kotwice, przyciski formularzy i kontrolki nawigacyjne. Takie elementy często pojawiają się we własnej ramce przeglądarki i sterują nawigacją po całej witrynie. Mogą być wyświetlone także w postaci osobnej strony indeksu lub spisu treści, który jest aktualizowany po wyborze odsyłacza. Hiperłącza przedstawiają użytkownikowi wybór, podobnie jak opcja menu w samodzielnej aplikacji.
Formularze służą do zbierania informacji od użytkownika. Mogą być zaprojektowane tak, aby zmieniły swoją postać w zależności od wprowadzonych przez użytkownika danych. Łącząc ciągi formularzy można utworzyć kreatory. Zazwyczaj formularze są przetwarzane przez czynności serwerowe lub klienckie.
Komponenty są jednostkami kodu dostarczającymi stosunkowo niezależnych części logiki. Komponent aplikacji można zastosować osobno lub w kombinacji z innymi komponentami. Komponenty różnią się od pozostałych elementów aplikacji skalą i zakresem odpowiedzialności. Komponenty mogą generować zawartość lub wykonywać logikę serwerową.
Czynność w tym przypadku oznacza reakcję aplikacji na czynności użytkowników. Na przykład, gdy użytkownik wysyła formularz, to aplikacja przetwarza formularz. Strony czynności wykonują zadania użytkowe, takie jak wprowadzanie danych, obliczenia lub funkcje administracyjne. Czynności (przetwarzanie) mogą odbywać się na serwerze oraz na kliencie i mogą służyć także do produkcji komunikatów potwierdzających lub komunikatów błędu.
Przeadresowanie – strona lub skrypt przeadresowania wykonuje logikę kierującą przepływem aplikacji. Stronę zawierającą zbiór ramek można również traktować jako stronę przeadresowania, mimo iż nie wykonuje samej operacji przeadresowania, jednak strona taka powoduje załadowanie innych stron. Przeadresowanie jest zwykle bardziej elastyczne wówczas, gdy realizowane jest jako osobna strona ASP.
Pętle powstają wówczas, gdy strony ASP zawierają odsyłacze do siebie w celu przedstawienia innej zawartości zależnej od danych uzyskanych od użytkownika, na przykład od rodzaju przeglądarki.
Z wyżej wymienionych elementów można utworzyć bardzo szeroki asortyment złożonych aplikacji.
Używanie formularzy wejściowych
Standardową metodą interakcji ze stronami internetowymi jest formularz HTML. Formularze mogą zawierać dowolną ilość danych, w postaci wpisanego tekstu, przycisków polecenia, guzików wyboru i pól wyboru. Formularze mogą być bardzo proste (pojedynczy guzik) lub mogą zawierać złożony układ kontrol klienckich. Strona internetowa może zawierać kilka różnych struktur formularza związanych z odpowiednią logiką przetwarzania, wykonaną po otrzymaniu formularza od użytkownika.
Załóżmy, że system identyfikacyjny ma polegać na podaniu przez użytkowników aplikacji nazwy i hasła. Aby to wykonać, należy utworzyć prostą stronę HTML zawierającą dwa pola tekstu i przycisk Prześlij w formularzu HTML.
Kod HTML tworzący formularz może wyglądać następująco:
<FORM ACTION=”./Logon.asp” METHOD=”GET”> Your name: <INPUT TYPE=”TEXT” NAME=”User”> Your password: <INPUT TYPE=”PASSWORD” NAME=”Pwd”> <INPUT TYPE=”PRZEŚLIJ” VALUE=”Log On”> </FORM>
Po wysłaniu formularza, wartości wprowadzone przez użytkownika zostają zebrane i przesłane do serwera jako żądanie. Wartości zostają przekazane jako pary nazwa/wartość do strony wymienionej w atrybucie ACTION znacznika <FORM>. Są one dołączone do żądanego URL po znaku zapytania (?) i są oddzielone od siebie znakami &. Gdyby użytkownik wprowadził nazwę użytkownika „John Doe” i hasło „Amnesia”, to kliknięcie przycisku Prześlij spowodowałoby przekaz następującego żądania URL:
http://myServer/test/Logon.asp?User=John+Doe&Pwd=Amnesia
Informacje w ten sposób dołączone do URL nazywa się informacjami zakodowanymi w URL. Kodowanie URL polega na zastąpieniu znaków zarezerwowanych, takich jak spacje i znaki &, neutralnymi znakami. Spacja w „John Doe” zostaje zastąpiona znakiem dodawania (+). Kodowaniu podlegają także znaki zapytania, procentu, dodawania i równości oraz przecinki. Te i inne specjalne znaki można reprezentować w formacie %hh, gdzie hh jest wartością szesnastkową kodu ASCII danego znaku.
ASP zawiera metodę serwerową Server.UrlEncode do kodowania i dekodowania parametrycznych URL. Gdy tworzone są hiperłącza zawierające pary nazwa/wartość, zawsze należy je zakodować w celu uniknięcia niepoprawnej składni URL. Niestety ta metoda ASP należy do obiektu serwerowego i nie może być używana na kliencie. Można napisać kliencką funkcję skryptową wykonującą to samo, ale łatwiej jest pozwolić logice przetwarzania formularzy, zawartej w przeglądarce, zrobić to automatycznie.
Różnica pomiędzy GET a POST
Gdy użytkownik wprowadził informacje do formularza i kliknął Prześlij, to informacje mogą zostać przekazane z przeglądarki do serwera na dwa sposoby: w URL lub w treści żądania HTTP.
Metoda GET zastosowana w powyższym przykładzie załącza pary nazwa/wartość do URL. Niestety długość URL jest ograniczona, dlatego ta metoda działa tylko w przypadku niewielkiej ilości parametrów. Gdyby formularz zawierał dużo parametrów lub parametry z dużą ilością danych, część URL mogłaby zostać utracona. Parametry przekazane w URL, w tym hasło użytkownika, są widoczne w polu adresu przeglądarki.
Alternatywnie można zastosować metodę POST, która załącza pary nazwa/wartość do treści żądania HTTP. W ten sposób URL jest bardziej czytelny, formularze mogą zawierać nieograniczone ilości danych i proces jest bezpieczniejszy.
Pobieranie par nazwa/wartość w ASP jest proste. Jeśli dane z formularza są przekazane w URL po znaku zapytania (?), tak jak przy użyciu metody GET, to parametry można pobrać za pomocą zbioru Request.QueryString. W przypadku metody POST dane z formularza zostają rozłożone i umieszczone w zbiorze Request.Form. Zbiory te umożliwiają określenie parametrów z formularza i URL za pomocą nazwy. Na przykład, wartość zmiennej formularzowej User można przekazać do zmiennej VBScript za pomocą jednego wiersza skryptu:
<% UserName = Request.Form(“User”) %>
Określenie zbioru (Form lub QueryString), w którym znajduje się parametr User nie jest konieczne. Poniższa wersja polecenia działa równie dobrze:
<% UserName = Request(“User”) %>
Jeśli zbiór jest nieokreślony, to obiekt Request przeszuka wszystkie swoje zbiory w celu znalezienia parametru o danej nazwie. Rozwiązanie to ma ułatwić programowanie, jednak obiekt ASP Request zawiera także zbiory ServerVariables i ClientCertificates, które zawierają poufne informacje o serwerze oraz informacje identyfikacyjne o użytkownikach. Aby uniemożliwić nieupoważniony dostęp do tych zbiorów, zaleca się zawsze określać odpowiednią nazwę zbioru przy nazwie parametru.
W poniższym skrypcie formularz i czynność (skrypt przetwarzający formularz) są połączone w jedną stronę. Przekazanie danych z formularza z powrotem do tej samej strony ASP, która formularz przedstawiła, umożliwi przetwarzanie danych przez skrypt serwerowy. Jest to wygodna metoda, zwłaszcza w przypadku prostego skryptu.
<%@ LANGUAGE=”VBScript” %> <!-- FILE: logon.asp --> <HTML> <HEAD> <TITLE>Authentication Form</TITLE> </HEAD> <BODY BGCOLOR=#FFFFFF> <% If Request.Form(“User”) = “” Then %> <P>Please enter your Name: <FORM ACTION=”./logon.asp” METHOD=”POST”> Your name: <INPUT TYPE=”TEXT” NAME=”User”> Your password: <INPUT TYPE=”PASSWORD” NAME=”Pwd”> <INPUT TYPE=”PRZEŚLIJ” VALUE=”Log On”> </FORM> <% Else ‘User verification and logon code goes here %> Welcome <%= Request.Form(“User”) %>! <% End If %> </BODY> </HTML>
Uwaga: Jeśli formularz jest przetwarzany przez osobny plik ASP, to zbiór Request.Form zostanie opróżniony po przejściu do nowej strony. Aby zachować dane z formularza, należy skopiować je do obiektu Session.
Powyższy formularz identyfikacyjny działa, jednakże prawdopodobnie nie byłby stosowany w praktyce. Informacje identyfikacyjne są poufne i powinny być chronione przed osobami nieupoważnionymi. Metoda POST włącza hasło użytkownika do treści żądania HTTP, jednakże przechwycenie i odczytanie haseł jest wciąż możliwe.
IIS 5.0 dostarcza najważniejszym aplikacjom bezpieczny system identyfikacji oparty na zintegrowanej identyfikacji Windows i certyfikatach klienckich, a także system szyfrowania danych oparty na Secure Sockets Layer (SSL). Więcej informacji o identyfikacji i szyfrowaniu znajduje się w rozdziale „Zabezpieczenia”.
Zatwierdzanie formularzy po stronie klienta
Formularze wymagają podania jakiegoś rodzaju danych wejściowych. Jeśli użytkownik nie wprowadził żadnych informacji lub wprowadził niedopuszczoną kombinację informacji, to wysłanie formularza do serwera nie będzie korzystne. Formularze przesłane bez wstępnego zatwierdzenia danych powodują zwiększenie obciążenia serwera i irytację użytkownika. W miarę możliwości należy zatwierdzić wszystkie informacje jeszcze przed ich wysłaniem.
Zatwierdzenia nie należy ograniczać do warstwy klienta. Na wypadek braku wsparcia skryptów u klienta, dane należy zatwierdzić ponownie przy ich przekazywaniu do warstwy środkowej. Najważniejsze jest zastosowanie ustalonych dla danej bazy danych reguł zatwierdzania i integralności danych – pomoże to ochronić dane przed skutkami błędów występujących w logice przetwarzania. Na dłuższą metę maksymalne wykorzystanie zatwierdzania okaże się korzystne dla użytkownika, ponieważ dane będą chronione na wszystkich poziomach aplikacji.
Aby zatwierdzić dane z formularza za pomocą skryptu klienckiego, należy zadeklarować procedurę obsługującą zdarzenie spowodowane przez wysłanie formularza. Jeśli dla formularza użyto typu wejściowego SUBMIT, to należy utworzyć procedurę zawierającą nazwę formularza razem z poleceniem _OnSubmit. Aby wysłać formularz, procedura zatwierdzająca powinna zwrócić wartość True. Zwrócenie wartości False spowoduje anulowanie wysłania i powrót do formularza.
Jeśli dla formularza użyto typu wejściowego BUTTON, to należy zdefiniować procedurę zawierającą nazwę przycisku razem z poleceniem _OnClick. Aby wysłać formularz, zamiast zwrócenia wartości True należy jawnie wywołać metodę Submit obiektu Form. Metoda ta może nie być dostępna we wszystkich przeglądarkach.
Poniższy skrypt kliencki sprawdza, czy pola formularza odpowiadające nazwie użytkownika i adresowi e-mail (oba obowiązkowe) zostały wypełnione. Następnie, gdy procedura zdarzenia OnSubmit zwraca True, formularz zostaje wysłany:
<SCRIPT LANGUAGE=”VBScript”> <!-- Function FeedbackForm_OnSubmit() ‘Disallow submit until the form fields have been validated. FeedbackForm_OnSubmit = False ‘Get a reference to the form. Set theForm = Document.FeedbackForm ‘First, check that UserName has been filled in. If Trim(theForm.UserName.Value) = “” Then MsgBox “Enter your name.”, vbCritical, “Need Input” theForm.UserName.Focus Else ‘Next, check for the e-mail name. If Trim(theForm.UserEmail.Value) = “” Then MsgBox “Enter your e-mail address.”, vbCritical, “Need Input” theForm.UserEmail.Focus Else ‘Continue with submission. FeedbackForm_OnSubmit = True End If End If End Function --></SCRIPT> <form name=FeedbackForm action=TeeFeedback.asp method=POST> <B>Tell us how to get in touch with you:</B> <PRE> Name <INPUT type=TEXT name=”UserName”> (Required) E-mail <INPUT type=TEXT name=”UserEmail”> (Required) Tel <INPUT type=TEXT name=”UserTel”> </PRE> F <INPUT type=SUBMIT value=”Submit Comments”> <INPUT type=RESET value=”Clear Form”> </FORM>
Ukryte pola formularzy
Gdy formularze zostają połączone w kreator, informacje wprowadzone na każdym formularzu muszą być przechowywane, dopóki ostatni formularz nie zostanie wypełniony. Istnieją trzy sposoby przekazywania wartości pomiędzy plikami ASP:
Zbieranie informacji w obiekcie Session.
Dołączanie informacji do końca URL i przekazywanie ich za pomocą QueryString.
Używanie w formularzu ukrytych zmiennych HTML.
Czasami wymagania aplikacji nie pozwalają nawet na tymczasowe przechowywanie danych z formularza w obiekcie Session. Dotyczy to na przykład dużej witryny posiadającej tysiące współbieżnych użytkowników, a ograniczoną ilość pamięci.
Przekazywanie wartości w URL jest skuteczne w przypadku małych ilości informacji, ale jest niemożliwe przy dużych ilościach danych.
Ukryte pola, mimo że wymagają przekazu większej ilości informacji pomiędzy warstwą klienta a środkową, umożliwiają jednak włączenie wcześniej wprowadzonych lub specyficznych dla aplikacji informacji do aktualnie wysyłanego formularza. Ukryte pole nie jest wyświetlone użytkownikowi, lecz zostaje przekazane w momencie wysłania formularza jako para nazwa/wartość.
Uwaga: Nie należy używać ukrytych pól do zwracania informacji związanych z zabezpieczeniem lub identyfikacją użytkowników. Wartości te są dostępne jako tekst w treści formularza i mogą zostać odczytane ze źródła HTML przez nieupoważnione osoby. Nawet nieszczególnie utalentowany intruz mógłby napisać krótką procedurę sprawdzającą wiele wartości w celu złamania kodu serwerowego korzystającego z ukrytej wartości.
Przeadresowanie
Czasami strona żądana przez przeglądarkę nie jest stroną odpowiednią do przesłania. Na przykład, użytkownik może zażądać strony Oldpage.htm, którą już zastąpiono stroną NewPage.asp. Standardowa składnia HTML umożliwia skierowanie (przeadresowanie) żądania do innego adresu. Na przykład:
<HEAD><META HTTP-EQUIV=”REFRESH” CONTENT=”0;URL=NewPage.asp”></HEAD>
Za pomocą ASP można skierować żądanie do innych stron w sposób zależny od logiki aplikacji. Składnia jest prosta: Response.Redirect “./NewPage.asp”
Metoda Redirect obiektu Response przesyła do klienta nagłówek odpowiedzi „302 Obiekt przeniesiony” wraz z nowym adresem pliku. Po otrzymaniu tej odpowiedzi przeglądarka użytkownika automatycznie żąda nowej strony.
Przeadresowanie jest oparte na nagłówkach HTTP, które występują na początku dokumentu, dlatego przeadresowanie jest niemożliwe po przesłaniu klientowi jakiegoś tekstu. Jeśli skrypt serwerowy spróbuje dokonać przeadresowania po wysłaniu części danych do klienta, to wystąpi następujący błąd: Header Error The HTTP headers are already written to the client browser. Any HTTP header modifications must be made before writing page content.
Jeśli na początku strony nie wiadomo, czy przeadresowanie jest konieczne, to można skorzystać z możliwości buforowania w obiekcie Response. Jeśli wartość Response.Buffer jest równa True, to produkowany HTML jest zbierany w buforze, a na końcu wszystko razem zostanie przekazane klientowi. Jeśli w którymś momencie okaże się, że konieczne jest przeadresowanie do innej strony, ASP automatycznie opróżnia bufor przy wywołaniu Response.Redirect. Aby w dowolnym momencie opróżnić bufor i rozpocząć ponownie, należy użyć Response.Clear.
Metoda ta przedstawiona jest w następującym przykładzie:
<% ‘Begin buffering the HTML. Response.Buffer = True %> <HTML> <BODY> HTML text before potential redirect. <% On Error Resume Next ‘Script generates an error here. If Err.Number > 0 Then Response.Clear Response.Redirect “./error.asp” End If %>
Po wywołaniu Response.Redirect, skrypt kończy się i nagłówki przeadresowujące zostają natychmiast przesłane. Ewentualny kod występujący po poleceniu Redirect nie zostanie wykonany, ale może być wymagany przez reguły składni.
Response.End służy do zakończenia odpowiedzi serwera i natychmiastowego przesłania bieżącego produktu do przeglądarki. Ewentualny HTML występujący po tym poleceniu nie zostanie przesłany. Poniższy skrypt wykrywa połączenie anonimowe (zmienna serwerowa LOGON_USER jest pusta) i wymusza rejestrację użytkownika zwracając komunikat „401 Dostęp odmówiony”.
<% strLogon = Request.ServerVariables(“LOGON_USER”) If IsEmpty(strLogon) Or strLogon = “” Then ‘Up to this point, no HTML has actually been sent. Response.Status = “401 Access Denied” Response.End End If %> <HTML> You are logged on as: <%= strLogon %> </HTML>
Dobra przeglądarka powinna wysłać ponownie to samo żądanie razem z informacjami identyfikacyjnymi. Gdyby polecenie Response.End nie było używane, skrypt na stronie ASP zostałby wykonany dwukrotnie, co mogłoby spowodować błędne wyniki (na przykład dwukrotne dodanie zapisów do bazy danych).
Przeadresowanie po stronie klienta
Przeadresowanie może być wykonywane także przez skrypty klienckie. Przeadresowanie po stronie klienta powoduje przejście z bieżącej strony do innej strony. Może to mieć miejsce po załadowaniu nowej strony lub dopiero po wykonaniu przez użytkownika jakiejś czynności, takiej jak kliknięcie odpowiedniego przycisku.
Model obiektów przeglądarki zawiera obiekt Location reprezentujący URL zawartości aktualnie wyświetlonej w oknie przeglądarki. W poniższym przykładzie ten obiekt jest wykorzystany do ponownego załadowania strony opartej na ramkach wewnątrz jej ramki macierzystej. Skrypt (który występuje na górze każdej strony ramkowej) wykrywa, że strona została załadowana jako ramka górna i kieruje przeglądarkę do ramki macierzystej. Aby uniknąć powielenia skryptu na wszystkich stronach, można umieścić go w pliku inkluzji.
<SCRIPT LANGUAGE=JavaScript> <!-- if(top == self) { var currURL = unescape(window.location.pathname); var newURL = “parentFrame.asp?” + currURL; var appVer = navigator.appVersion; var NScp = (navigator.appName == ‘Netscape’) && ((appVer.indexOf(‘3’) != -1) || (appVer.indexOf(‘4’) != -1)); var MSIE = (appVer.indexOf(‘MSIE 4’) != -1); if (NScp || MSIE) location.replace(newURL); else location.href = newURL; } //--> </SCRIPT>
Metoda ta wymaga przyjęcia przez ramkę macierzystą adresu ramki potomnej jako parametru URL oraz odpowiedniego postąpienia z tym parametrem. Ostatnia część procesu przeadresowania jest wykonana przez następujący skrypt:
<%@ LANGUAGE=VBScript EnableSessionState=False %> <% frmSrc = Request.QueryString ‘Get entire URL parameter. If frmSrc = “” Then frmSrc = “homepage.htm” %> <FRAMESET rows=”60,*” frameborder=0 framespacing=0> <FRAME name=”nav_fr” src=”navbar.htm” scrolling=auto noresize> <FRAME name=”page_fr” src=”<%=frmSrc%>” scrolling=auto> </FRAMESET>
Przeadresowanie podczas Session_OnStart
Przeadresowanie jest możliwe także w procedurze obsługującej zdarzenie Session_OnStart. W przypadku niektórych aplikacji jest to niezbędne (por. „Klastry internetowe i status sesji ASP” wcześniej w tym rozdziale). Oto przykład:
Sub Session_OnStart Response.Redirect “MyStartPage.asp” End Sub
Nie wszystkie metody obiektu Response są dostępne przy obsłudze zdarzenia Session_OnStart. Przede wszystkim nie można korzystać z metody Write do wyświetlania komunikatów, ponieważ klient wcale by ich nie zobaczył. Możliwe jest jednak przeadresowanie do komunikatu błędu w przypadku, gdy aplikacja nie może inicjować nowej sesji.
Usuwanie błędów z aplikacji i komponentów
Usuwanie błędów jest często najbardziej frustrującą częścią procesu projektowania aplikacji internetowych. W przeciwieństwie do aplikacji pulpitowych, aplikacje internetowe często są rozproszone po różnych systemach i obejmują różne języki programowe i technologie. Części błędów w aplikacjach można uniknąć dzięki starannemu planowaniu, jednakże inne są niespodziewanymi efektami ubocznymi złożonych interakcji między komponentami. Lokalizacja tych problemów często wymaga użycia różnych narzędzi projektanckich i narzędzi do usuwania błędów.
W tej części omówione są sposoby usuwania błędów w środowisku ASP. Przedstawione są także informacje o usuwaniu błędów z rozszerzeń ISAPI i komponentów serwerowych.
Informacje o często spotykanych komunikatach błędów i dziennikach błędów znajdują się w dokumentacji online IIS 5.0.
Usuwanie błędów ze skryptów na stronach ASP
Ponieważ na stronach ASP, HTML często miesza się ze skryptem serwerowym i z komponentami, lokalizacja problemów może być trudna. W zasadzie istnieją trzy sposoby postępowania z błędami: zapobieganie błędom, usuwanie błędów i zarządzanie skryptem.
Zapobieganie często popełnianym błędom
Badania wykazały, że programiści popełniają podobne błędy niezależnie od używanego języka programowego. Zawsze łatwiej jest unikać powstawania problemów niż później je rozwiązywać. Poniżej przedstawiamy błędy popełniane podczas programowania skryptów oraz sposoby rozwiązania problemów związanych z błędami.
Błędy ortograficzne w nazwach zmiennych
Większość błędów skryptów jest spowodowana przez niepoprawnie napisane nazwy zmiennych. VBScript automatycznie deklaruje nierozpoznane zmienne, co może spowodować ukryte błędy w kodzie. Aby uniknąć tego problemu, należy rozpocząć każdą stronę skryptu od polecenia Option Explicit. Option Explicit wymaga jawnej deklaracji zmiennych w poleceniu Dim.
W JScript nie istnieje odpowiednik polecenia Option Explicit. Nieznane zmienne zostają zadeklarowane automatycznie. Przekaz niezadeklarowanej zmiennej do niektórych metod ASP, takich jak Response.Write, spowoduje błąd skryptowy. Jeśli zmienna jest zadeklarowana, ale nie jest zdefiniowana, to zwrócona zostanie wartość „Undefined” lub „NaN” (więcej informacji na ten temat znajduje się w dokumentacji JScript).
Użycie obiektu lub zmiennej poza zakresem
Często zapomina się, które obiekty są dostępne w danym kontekście. Na przykład, błędna byłaby próba ustawienia właściwości obiektu Session w skrypcie klienckim lub użycie modelu obiektów Internet Explorer w skrypcie wykonywanym przez inną przeglądarkę.
Należy upewnić się, że wszystkie wykorzystane obiekty są dostępne w aktualnym zakresie. Obiekty takie jak wbudowane obiekty ASP nie są integralną częścią języka takiego jak VBScript, lecz należą do środowiska, w którym skrypt działa.
Niewykorzystanie serwera internetowego do oglądania stron ASP
Aby zobaczyć strony ASP w przeglądarce, należy zażądać ich od serwera internetowego przy użyciu składni HTTP. W przypadku próby bezpośredniego przejrzenia tych stron w systemie plikowym, przeglądarka spróbuje ściągnąć plik lub wyświetli skrypt bez jego wykonania. Innymi przyczynami, dla których strony ASP nie są wyświetlone poprawnie są: brak uprawnień wykonywania dla katalogu zawierającego daną stronę oraz nadawanie plikom rozszerzenia innego niż .asp.
Nieskuteczne używanie języka skryptowego
Czasami programiści nie znający dobrze danego języka skryptowego piszą kod, który nie wykorzystuje wszystkich możliwości języka i z tego powodu działa zbyt wolno. Jeśli nie rozumieją oni konwencji stosowanych w języku, to dodatkowo mogą popełnić błędy składniowe, takie jak umieszczenie łańcuchów w niewłaściwym cudzysłowie. Łatwo jest popełnić takie błędy przy jednoczesnym używaniu różnych języków, na przykład Visual Basic i SQL.
Zawsze należy zapoznać się z rodzimymi funkcjami i operatorami używanego języka skryptowego oraz ze stosowanymi w nim konwencjami.
Mieszane typy danych
Ponieważ w skryptach ASP wszystkie zmienne są wariantami (czyli mogą zawierać wartości dowolnego typu), to łatwe jest przypisanie zmiennym nieodpowiednich wartości. Na przykład, zmiennej przeznaczonej dla łańcuchów można przypisać obiekt.
Należy stosować system nazw ułatwiający kojarzenie zmiennych z typem wartości. Tabela zalecanych nazw zmiennych dla VBScript znajduje się w rozdziale „Zalecane metody pracy w ASP”.
Niepoprawne używanie znaku równości
W Visual Basic pojedynczy znak „=” jest używany do porównania dwóch argumentów. Natomiast w JScript pojedynczy znak „=” spowoduje przypisanie wartości po prawej stronie argumentowi znajdującemu się po lewej stronie (w JScript do wyrażenia równości jest stosowany podwójny znak „=”). Błędne użycie pojedynczego znaku „=” w wyrażeniu spowoduje zmianę wartości zmiennej po lewej stronie, a także przyjęcie wartości wyrażenia jako TRUE. Jeśli ma to miejsce w poleceniu If, to wewnętrzny kod zostanie wykonany, a polecenie While spowoduje nieskończoną pętlę.
Niewłaściwe użycie procedur
W każdym języku częstym problemem jest wywołanie funkcji lub procedur w niewłaściwym momencie lub wywołanie nieodpowiedniej funkcji. Dzięki dokładnemu sprawdzeniu definicji funkcji można uniknąć użycia niewłaściwych argumentów lub przekazania argumentów w nieodpowiedniej kolejności. Należy upewnić się także, że wywoływana funkcja wykonuje oczekiwane zadanie i że użyta składnia jest poprawna. Nie należy polegać na domyślnych wartościach argumentów.
Brak obsługi błędów
Zawsze należy sprawdzać, czy użytkownik podał prawidłowe dane, na przykład, czy nie podał łańcucha w miejsce liczby lub liczby spoza dopuszczonego zakresu. Należy również przewidzieć błędy występujące w programie i dobrze zrozumieć wartości zwrócone przez wykorzystywane funkcje.
Do obsługi wewnętrznych błędów programu w VBScript, należy użyć polecenia On Error Resume Next. Bez tego polecenia skrypt zostanie przerwany natychmiast po wykryciu błędu, co uniemożliwia skryptową obsługę błędów. Przy stosowaniu polecenia On Error Resume Next należy pamiętać o następujących kwestiach:
Podczas usuwania błędów zwykle zalecane jest wyłączenie obsługi błędów, ponieważ ważne jest ustalenie ich źródła. Po zakończeniu należy ponownie włączyć obsługę błędów.
Ponieważ w przypadku błędu wykonywanie programu jest kontynuowane od następnego polecenia, skrypt potencjalnie wywołujący błąd nie powinien być używany w warunku polecenia If lub pętli While. Jeśli błąd nastąpi w tym miejscu, to wewnętrzny kod polecenia If nie zostanie wykonany, a pętla While nie zostanie zakończona.
Błędy indeksów zbiorów
W VBScript nie wszystkie zbiory rozpoczynają się indeksem 1. Niektóre zbiory, na przykład zbiór ADO Fields, rozpoczynają się od elementu numer 0. Podczas przechodzenia całego zbioru przez pętlę, najbezpieczniej jest zastosować metody VBScript Lbound i Ubound do określenia odpowiednio, początkowego i końcowego indeksu. Metody te są również zdefiniowane w obiekcie JScript VBArray.
Pomijanie końcowych nawiasów, ograniczników i poleceń
Im dłuższy staje się skrypt, tym bardziej prawdopodobne jest ominięcie nawiasów końcowych, końcowego polecenia bloku kodu, takiego jak End If lub końcowego ogranicznika, takiego jak %>. Efekt jest często trudny do zrozumienia i mogą wystąpić dwuznaczne błędy skryptowe. Aby uniknąć takich problemów dobrze jest wyrobić sobie zwyczaj pisania końcowej części polecenia zaraz po napisaniu początkowej części.
Usuwanie błędów z ASP
Do czasu wprowadzenia Microsoft Script Debugger, usuwanie błędów ze skryptów na stronach ASP wymagało dużej ilości danych wyjściowych i wnikliwej wiedzy na temat wykonywania kodu w danym języku skryptowym. Script Debugger znacznie ułatwia ten proces.
Microsoft Script Debugger
Script Debugger może być zastosowany do sprawdzenia skryptów napisanych w VBScript i JScript, jak również do aplikacji napisanych w Java. Błędy usuwać można też ze skryptów napisanych w innych językach wspierających uniwersalne metody usuwania błędów, takich jak REXX czy PerlScript.
Stosując Script Debugger można:
Przeglądać kod źródłowy skryptu.
Kontrolować wykonywanie pojedynczych wierszy skryptu.
Przeglądać i zmieniać wartości zmiennych i właściwości.
Ustanowić punkty kontrolne i przeglądać stos wywołań.
Przełączyć wątki wykonywania.
Script Debugger może być użyty do usuwania błędów w skryptach po stronie klienta i po stronie serwera. Każda aplikacja ASP, która ma być sprawdzona, musi mieć włączoną opcję usuwania błędów.
v
1.
2.
3.
Aby rozpocząć edycję dokumentów w Script Debugger, należy otworzyć okno Uruchomione dokumenty (z menu Widok) i dwukrotnie kliknąć odpowiedni dokument. Żeby otwarcie skryptu było możliwe, musi on znajdować się w lokalnej przeglądarce lub w środowisku ASP na lokalnym serwerze internetowym. Po załadowaniu skryptu możliwe jest określenie punktów kontrolnych i szczegółowe sprawdzenie działania aplikacji.
Podczas działania skryptu wartości poszczególnych zmiennych można przeglądać i zmieniać w oknie Polecenia. Aby wyświetlić wartość zmiennej, należy wpisać nazwę zmiennej poprzedzoną znakiem zapytania (?) i nacisnąć Enter. Znak zapytania służy także do obliczenia prostych wyrażeń liczbowych. Wartość zmiennej można zmienić wpisując nazwę zmiennej, znak równości (=) oraz nową wartość liczbową lub łańcuchową.
Script Debugger funkcjonuje tylko ze skryptami działającymi na lokalnym serwerze internetowym. Script Debugger przerywa wykonywanie skryptu w przypadku błędu, dlatego nie należy włączać usuwania błędów w systemach, w których działają aplikacje niezbędne dla pracy przedsiębiorstwa. W przypadku takich systemów lepszą metodą śledzenia wykonywania jest kontrolowanie dzienników i produktu programów.
Więcej informacji o Script Debugger znajduje się w dokumentacji online IIS 5.0.
Śledzenie błędów
Na śledzenie błędów w ASP składają się trzy następujące metody:
Częste używanie w kodzie poleceń Response i Write.
Użycie Response.AppendToLog do zapisywania wartości i zdarzeń w dzienniku serwerowym IIS 5.0.
Niestandardowy komponent zapisujący informacje kontrolne w dzienniku zdarzeń Windows w Windows 2000 Server, w bazie danych lub w pliku tekstowym określonym dla danej aplikacji.
Śledzenie błędów należy stosować rozsądnie. Przy dodawaniu do skryptu komunikatów, należy skupić się na zdarzeniach umożliwiających odtworzenie przebiegu kodu poprzedzającego błąd. Należy zapisać wywołania funkcji i wartości parametrów. Należy zapisać tylko najważniejsze wartości – dodanie zbyt dużej ilości komunikatów spowoduje znaczne spowolnienie działania aplikacji.
Włączanie i wyłączanie śledzenia błędów powinno być łatwe. W przypadku małych projektów można wyłączyć polecenia śledzenia błędów przekształcając je w komentarze. Jednak w dużych projektach kod śledzenia błędów należy umieścić w skrypcie lub w funkcyjnym komponencie, który można włączać i wyłączać niezależnie od kodu.
Śledzenie zdarzeń w Global.asa
Usuwanie błędów związanych ze zdarzeniami Session i Application jest trudne, ponieważ wyświetlanie komunikatów w przeglądarce klienta za pomocą metody Response.Write jest niemożliwe. Przydatną metodą jest użycie obiektu Scripting.FileSystemObject do generowania dziennika zawierającego proste komunikaty tekstowe określające udaną lub nieudaną obsługę zdarzeń. Poniższy skrypt zapisuje komunikaty dotyczące wszystkich zdarzeń początkowych lub końcowych Application i Session.
<!--METADATA TYPE=”TypeLib” NAME=”Scripting” FILE=”C:\Winnt\System32\scrrun.dll” UUID=”420B2830-E718-11CF-893D-00A0C9054228” VERSION=”1.0” --> <OBJECT ID=”AppFileSystemObject” SCOPE=APPLICATION RUNAT=SERVER PROGID=”Scripting.FileSystemObject”> </OBJECT> <SCRIPT LANGUAGE=VBScript RUNAT=SERVER> Sub OutputDebugFile(ByRef strText) Dim ts Application.Lock Set ts = AppFileSystemObject.OpenTextFile(Application(“DebugFile”),_ ForAppending, True, TristateUseDefault) ts.WriteLine Now & “: “ & strText ts.Close Application.Unlock End Sub Sub Application_OnStart ‘DebugFile must be defined before calling OutputDebugFile. Application(“DebugFile”) = “c:\webs\appevnts.log” OutputDebugFile(“Application Started”) End Sub Sub Application_OnEnd OutputDebugFile(“Application Ended”) End Sub Sub Session_OnStart OutputDebugFile(“Session Started: “ & Session.SessionID) Response.Redirect “./end.asp”
‘End Session (this creates a loop!). End Sub Sub Session_OnEnd OutputDebugFile(“Session Ended: “ & Session.SessionID) End Sub </SCRIPT>
Zarządzanie skryptami
W tej części omówione jest zarządzanie długimi skryptami oraz minimalizacja ilości błędów technicznych w dużych projektach.
Założenie biblioteki procedur pomocniczych
Warto jest zebrać często używane funkcje w jeden plik, który można włączyć za pomocą polecenia include do wszystkich stron korzystających z tych funkcji.
Plik inkluzji może zawierać tekst, deklaracje funkcji i procedur ze znacznikami <SCRIPT> oraz definicje zmiennych i stałych. Aby włączyć ten plik do strony, należy zastosować na górze strony dyrektywę serwerową include, na przykład:
<!-- #include virtual=”/MyRoot/include/funclib.inc” -->
Pliki inkluzji zwykle posiadają rozszerzenie .inc. Jest to sposób rozróżniania tego rodzaju plików, ale w przypadku włączonego przeglądania katalogów mogą wystąpić problemy z zabezpieczeniem. Rozszerzenie .inc normalnie nie jest mapowane przez IIS 5.0 i nie jest rozpoznawane przez większość przeglądarek. Dlatego każda osoba znająca położenie plików może je ściągnąć i otworzyć. Aby uniknąć tego problemu, należy powiązać rozszerzenie .inc z plikiem Asp.dll w mapie skryptowej (na zakładce Mapowanie aplikacji w oknie dialogowym Konfiguracja aplikacji). Alternatywnie można umieścić pliki inkluzji w osobnym podkatalogu oraz wyłączyć przeglądanie katalogów i dostęp do odczytu.
Cały tekst pliku inkluzji zostaje załączony do pliku źródłowego .asp w miejscu wystąpienia polecenia include. W zasadzie liczba załączonych plików jest nieograniczona, ale każdy kolejny zwiększa skompilowany plik .asp, dlatego należy załączyć tylko wykorzystywane pliki.
Ponieważ wszystkie pliki inkluzji są przetwarzane przed uruchomieniem skryptu, nie można decydować dynamicznie, który plik ma zostać załączony. Z tego samego powodu niemożliwe jest zastosowanie dyrektywy include w Global.asa.
Partycjonowanie przestrzeni nazw sesji za pomocą słowników
Obiekt Session może być traktowany jako globalny obszar danych. W przypadku dużych aplikacji internetowych zbiór Session może być wypełniony różnymi nieuporządkowanymi informacjami. W tej sytuacji wzrasta prawdopodobieństwo, że któraś część aplikacji dokona zmian mających niespodziewane skutki w innych częściach. Aby tego uniknąć, projektanci muszą zastosować konwencje nazw zmniejszające prawdopodobieństwo powtórzenia się nazw kluczy Session. Alternatywnie można zastosować inne metody przechowywania wartości związanych z sesją.
Jedna z tych metod polega na dalszym partycjonowaniu globalnej przestrzeni nazw sesji za pomocą obiektu Dictionary. Podobnie jak obiekt Session, obiekt Dictionary może przechowywać dowolną liczbę wartości i słów kluczowych w tablicy asocjacyjnej. Różne części aplikacji mogą w miarę potrzeb tworzyć obiekty Dictionary do przechowywania wartości lokalnych wraz z pojedynczym odsyłaczem do ich przestrzeni nazw w obiekcie Session. Obiekt Dictionary ułatwia nie tylko zarządzanie grupą wartości jako pojedynczą jednostką, lecz także zbiorowe zwolnienie niepotrzebnych aplikacji zasobów. Więcej informacji o obiekcie Dictionary znajduje się w dokumentacji online IIS 5.0.
Usuwanie błędów z ISAPI i komponentów serwerowych
W tej części omówione są sposoby łączenia się z uruchomionymi aplikacjami oraz używania Script Debugger do lokalizacji błędów w kodzie źródłowym komponentów, filtrów ISAPI i rozszerzeń.
Wyłączenie obsługi wyjątków
Eksperci w zakresie ASP rozpoznają następujący komunikat błędu:
Error ‘ASP 0115’ Unexpected error A trappable error occurred in an external object. The script cannot continue running.
Powyższy błąd jest spowodowany naruszeniem reguł dostępu przez proces komponentu. ASP może wyświetlić komunikat, ponieważ błąd został wykryty przez wbudowaną obsługę wyjątków procesu ASP.
Usuwanie błędów z komponentu aplikacji jest w wielu przypadkach łatwiejsze przy wyłączonej obsłudze wyjątków. Aby wyłączyć obsługę wyjątków, należy wybrać zakładkę Opcje procesu w oknie dialogowym Konfiguracja aplikacji w Menedżerze usług internetowych. Zakładka Opcje procesu pojawi się przy edycji globalnych właściwości dotyczących wszystkich aplikacji działających wewnątrz procesu lub przy edycji właściwości aplikacji zewnątrzprocesowej działającej w osobnym obszarze pamięci.
Uruchomienie aplikacji w osobnym procesie wymaga większej ilości zasobów systemowych, ale pozwala ochronić inne aplikacje przed skutkami błędów. Gdy pole wyboru Włącz obsługę wyjątków dla usuwania błędów na zakładce Opcje procesu jest wyczyszczone, ASP nie przechwyci poważnych błędów aplikacji. Takie zdarzenia będą traktowane jako błędy wyizolowanego procesu aplikacji oraz jako błędy komponentów wewnątrzprocesowych.
Usuwanie błędów z IIS 5.0
Usuwanie błędów z IIS 5.0 może być konieczne w następujących sytuacjach:
Strony wywołujące komponenty serwerowe zwracają komunikaty błędów ASP 0115.
IIS 5.0 przestał obsługiwać strony ASP.
Usługa internetowa przerwała się i klienci nie mogą podłączać się do serwera.
Inetinfo.exe spowodował błąd dr Watsona.
Działanie Inetinfo.exe zostało przerwane bez oczywistego powodu.
Istnieją dwa sposoby utworzenia środowiska usuwania błędów z komponentów serwerowych i rozszerzeń ISAPI:
Zastosowanie narzędzia usuwania błędów do procesu IIS 5.0.
Uruchomienie narzędzia usuwania błędów z usługi publikacji internetowej.
Zastosowanie narzędzia usuwania błędów do usługi IIS 5.0
Jeśli używane jest narzędzie usuwania błędów, które może być dołączone do procesów Windows 2000 Server, to powinno się wykorzystać to narzędzie do usunięcia błędów z komponentu lub rozszerzenia.
v
1.
2.
3.
4.
5.
Uruchomienie narzędzia usuwania błędów za pomocą usługi publikacji
Jeśli używane narzędzie usuwania błędów nie może być dołączone do procesów Windows 2000 Server, to konieczne będzie utworzenie odpowiedniego środowiska usuwania błędów.
v
1.
2.
3.
4.
5.
6.
HKEY_LOCAL_MACHINE \Software \Microsoft \WindowsNT \CurrentVersion \Image File Execution Options key
Do nowego klucza dodaćnastępujący wpis:
Debugger = DebuggerExeName, gdzie DebuggerExeName jest pełną ścieżką do używanego narzędzia usuwania błędów.
Ostrzeżenie: Nie należy modyfikować rejestru bezpośrednio za pomocą edytora rejestru, chyba że nie ma innej możliwości. Edytory rejestru omijają standardowe zabezpieczenia dostarczone przez narzędzia administracyjne. Zabezpieczenia uniemożliwiają wprowadzenie ustawień sprzecznych albo mogących zmniejszyć wydajność lub uszkodzić system. Bezpośrednia edycja rejestru może mieć poważne, niespodziewane skutki uniemożliwiające uruchomienie systemu i wymagające ponownej instalacji Windows 2000. Aby skonfigurować lub dostosować Windows 2000, należy skorzystać z programów w Panelu sterowania lub Microsoft Management Console (MMC), gdy to tylko możliwe.
Uruchomienie usługi publikacji internetowej spowoduje także uruchomienie narzędzia usuwania błędów. W tym momencie można ustanowić punkty kontrolne w rozszerzeniu ISAPI.
Nie można ustanawiać punktów kontrolnych w kodzie źródłowym komponentu, dopóki komponent nie zostanie załadowany do pamięci. Należy uruchomić Internet Explorer i załadować stronę ASP zawierającą dany obiekt. Następnie należy ustanowić punkty kontrolne w komponencie, kliknąć Odśwież i uruchomić wybrane punkty kontrolne. Jeśli załadowanie komponentu jest niemożliwe (na przykład, jeśli występuje błąd w kodzie inicjacyjnym), to należy załadować plik DLL komponentu przed rozpoczęciem usuwania błędów.
Brak możliwości tworzenia komponentów
Czasami metoda Server.CreateObject generuje błąd „ASP 0177: Server.CreateObject Failed”. Jest to możliwe nawet w przypadku, gdy komponent działa bez problemu w Visual Basic na tym samym komputerze lub przy użyciu ASP na innych komputerach.
Przyczyną tego zachowania jest często brak uprawnienia do uruchomienia obiektu COM. W najprostszym przypadku użytkownik nie ma dostępu do DLL lub pliku wykonywalnego komponentu. W wielu przypadkach jednak problem polega na braku dostępu do innych plików DLL, od których komponent jest zależny. Zazwyczaj większość użytkowników uzyskuje dostęp do witryny pod anonimowym kontem IUSR_computername.
Aby potwierdzić związek problemu z uprawnieniami, należy uruchomić komponent z innego narzędzia, takiego jak Visual Basic. W ten sposób można sprawdzić, czy komponent jest prawidłowo zarejestrowany na serwerze. Jeśli komponentu nie można utworzyć w Visual Basic, to problem prawdopodobnie nie wynika z braku uprawnień, lecz z braku rejestracji komponentu.
Jeśli problem wydaje się być związany z uprawnieniami, to należy sprawdzić uprawnienia dotyczące komponentu i ewentualnych plików zależnych, takich jak inne DLL. Jeśli problemu nie da się rozwiązać w ten sposób, należy systematycznie przejrzeć wszystkie uprawnienia.
Zasoby dodatkowe
Poniższe witryny i książki zawierają dodatkowe informacje o IIS 5.0 i innych cechach Windows 2000 Server oraz o narzędziach do projektowania aplikacji internetowych.
Witryny
Bezpłatne źródło materiałów dla projektantów pracujących z systemami internetowymi Microsoft. Witryna ta zawiera biuletyn informacyjny 15 Seconds, często zadawane pytania opracowane przez Stephena Genusę, serwery listy i program Consultant. Znajdują się tu także recenzje książek, artykuły z praktycznymi radami i oferty zatrudnienia związane z ASP i systemami internetowymi Microsoft.
http://www.sun.com/software/chilisoft/
Chili!Soft ASP udostępnia możliwości ASP serwerom innym niż IIS. Chili!Soft ASP pozwala na umieszczenie stron ASP i komponentów na różnych serwerach internetowych bez zmian kodu. Wspiera serwery Netscape oparte na Windows.
http://www.activeserverpages.com/genusa
Najważniejsza „nieoficjalna” witryna ASP. Zawiera doskonały zbiór zasobów dla ASP.
Ta witryna, zwana TechNet, zawiera wszystko co potrzebne do zaplanowania i zbudowania witryny w sieci wewnętrznej – dokumentacją White Paper, często zadawane pytania, prawdziwe historie oraz bezpłatne narzędzia napisane przez Microsoft Solution Providers.
Po otwarciu menu Libraries oraz wskazaniu Web Workshop Home i Server Technologies pojawi się obszar Microsoft MSDN poświęcony Active Server Pages. Witrynę tę należy koniecznie odwiedzić.
Książki
ActiveX Web Programming, Adam Blum, 1996, Nowy York: John Wiley & Sons, Inc.
Książka napisana jeszcze podczas projektowania ASP, jednakże stanowi doskonałe wprowadzenie do CGI, ISAPI, kontrol ActiveX i skryptów klienckich.
Working with Active Server Pages, Michael Corning, 1997, Indianapolis: Que Corporation.
Opisuje metody projektowania i realizacji stron ASP. Zawiera wzięte z życia przykłady zastosowania ASP i ADO do obsługi baz danych.
Professional Active Server Pages 2.0, Alex Federov, 1998, Chicago: Wrox Press Ltd.
Często zalecany i wszechstronny podręcznik na temat ASP i ADO. Zawiera praktyczne metody tworzenia wielowarstwowych aplikacji internetowych.