セッションを管理する

Web アプリケーションの開発を成功させるうえでの課題の 1 つは、利用中、つまり "セッション" 中のユーザーがアプリケーションのページ間を移動する間もユーザー情報を保持することです。HTTP は、状態を保持しないプロトコルです。つまり、Web サーバーは、ページに対する各 HTTP 要求を独立した要求として扱います。サーバーでは、前の要求が現在の要求の数秒前にあった場合でも、前の要求に関する情報は保持していません。このように、前の要求に関する情報を保持できないため、オンライン カタログなどのアプリケーションを作成することが困難になります。このようなアプリケーションでは、ユーザーがカタログ内のさまざまなページ間を移動している間に選択したカタログ項目を追跡することが必要になる場合があるためです。

ASP は、セッション情報を管理する際の問題に対して、独自の解決方法を提供します。ASP の Session オブジェクト、およびサーバーによって生成された特殊なユーザー ID を使うと、各利用ユーザーを識別し、情報を収集する高機能なアプリケーションを作成できます。アプリケーションは、この情報を使用してユーザーの設定や選択項目を追跡できます。

重要   ASP では、HTTP cookie という方法を使用してユーザー ID を割り当てます。HTTP cookie は、ユーザーのブラウザに格納される小さなファイルです。したがって、cookie をサポートしないブラウザ用のアプリケーションを作成する場合、またはユーザー側で cookie を拒否するようにブラウザを設定する可能性がある場合は、ASP のセッション管理機能を使用しないでください。

セッションの開始と終了

セッションは、次の 4 とおりの方法で開始できます。

指定された時間内に、ユーザーがアプリケーションのページを要求または更新しない場合、セッションは自動的に終了します。この値の既定値は 20 分です。アプリケーションの既定値を変更するには、インターネット インフォメーション サービス スナップインの [アプリケーションのオプション] プロパティ シートの [セッションのタイムアウト] プロパティを設定します。 この値は、Web アプリケーションの要件とサーバーのメモリ容量に合わせて設定します。たとえば、Web アプリケーションを閲覧するユーザーは各ページに数分しかとどまらないと予想される場合、セッション タイムアウトの値を既定値より大幅に小さくすることができます。セッション タイムアウトの時間を長くすると、利用できるセッションの数が増え、サーバーのメモリ リソースを圧迫する場合があります。

特定のセッションに対し、アプリケーションの既定のタイムアウトより短いタイムアウト間隔に設定するには、Session オブジェクトの Timeout プロパティを設定することもできます。たとえば、次のスクリプトは、タイムアウト間隔を 5 分に設定します。

<%  Session.Timeout = 5  %>

また、既定値、つまり Session Timeout プロパティで設定された値より長いタイムアウト間隔に設定することもできます。

   Timeout は、状態を保持しているセッションにのみ適用されます。"状態を保持しないセッション" の間は、Session オブジェクトにコンテンツや静的オブジェクトはありません。このタイプのセッションは、要求が処理されると自動的に終了し、同じブラウザから次の要求があった時点で再作成されます。

また、Session オブジェクトの Abandon メソッドを使用して、セッションを意図的に終了することもできます。たとえば、フォーム上に [終了] ボタンを置き、その ACTION パラメータを次のコマンドが含まれている .asp ファイルの URL に設定します。

<% Session.Abandon %>

   Session.Abandon を開始する前に実行キューに入れられたユーザーの要求は、中止されるセッションのコンテキストとして実行されます。Session.Abandon の実行が完了すると、新しい要求があっても、このセッションには関連付けられません。

SessionID と cookie について

ユーザーが特定のアプリケーション内で最初に .asp ファイルを要求したときに、ASP は "SessionID" を生成します。複雑なアルゴリズムによって作成された数値である SessionID は、各ユーザーのセッションを一意に識別します。新しいセッションの開始時に、サーバーはユーザーの Web ブラウザに SessionID を cookie として格納します。

SessionID cookie は、ロッカー キーに似ています。 ユーザーがセッション中にアプリケーションとやり取りするとき、ASP はサーバー上の "ロッカー" にユーザーに関する情報を格納します。ロッカー キーによってロッカーの中身を利用できるように、ユーザーの SessionID cookie によって、その情報にアクセスすることができます。 ユーザーの SessionID cookie は、HTTP 要求ヘッダーの中で送信されます。ASPは、ページに対する要求を受け取るたびに、HTTP 要求ヘッダーの SessionID cookie を調べます。

ASP はユーザーのブラウザに SessionID cookie を格納した後は、ユーザーが別の .asp ファイルを要求または、ほかのアプリケーションで実行されている .asp ファイルを要求する場合でも、同じ cookie を再利用してセッションを追跡します。同様に、ユーザーが意図的にセッションを中止したり、意図的にセッションをタイムアウトにしてから、別の .asp ファイルを要求する場合でも、ASP は同じ cookie を使用して新しいセッションを開始します。唯一、ユーザーが新しい SessionID cookie を受け取るのは、サーバー管理者がサーバーを再起動してメモリに格納された SessionID の設定を消去するか、ユーザーが Web ブラウザを再起動した場合のみです。

SessionID cookie を再利用することにより、ASP はブラウザに送信する cookie の数を最小限にとどめます。さらに、ASP アプリケーションにセッション管理は必要ないと判断した場合には、ASP によるセッションの追跡をやめ、SessionID cookie をユーザーに送信しないように設定できます。

次の場合、ASP はセッション cookie を送信しません。

また、SessionID cookie は、Web サイトの複数回の利用にわたって長期的にユーザーを追跡することを目的としているわけではないことにも注意してください。サーバー コンピュータのメモリに格納された SessionID 情報は、簡単に失われます。Web アプリケーションを利用するユーザーを長期にわたって追跡する場合は、ユーザーの Web ブラウザに特殊な cookie を格納し、データベースに cookie 情報を保存して、ユーザーの識別情報を作成する必要があります。詳細については、「cookie の使い方」を参照してください。

Session オブジェクトに対してデータを格納および削除する

Session オブジェクトは、情報を格納できる、動的な関連配列を備えています。Session オブジェクトには、スカラ変数およびオブジェクト変数を格納できます。

Session オブジェクトに変数を格納するには、Session オブジェクトの名前付きエントリに値を代入します。たとえば、次のコマンドは、Session オブジェクトに 2 つの新しい変数を格納します。

<% 
  Session("FirstName") = "Jeff"
  Session("LastName") = "Smith" 
%>

Session オブジェクトから情報を取得するには、名前付きエントリにアクセスします。たとえば、Session("FirstName") の現在の値を表示するには、次のように指定します。

Welcome <%= Session("FirstName") %>

Session オブジェクトにユーザー設定を格納し、後でその設定情報にアクセスして、ユーザーに返すページを決定することができます。たとえば、アプリケーションの最初のページで、ユーザーがテキスト専用バージョンのコンテンツを指定できるようにしておけば、この設定を、アプリケーション内でユーザーが引き続き利用するすべてのページに対して適用することができます。

<% If Session("ScreenResolution") = "Low" Then %> 
  This is the text version of the page.
<% Else %> 
  This is the multimedia version of the page.
<% End If %>

また、Session オブジェクトにオブジェクト インスタンスを格納することもできます。 ただし、その場合、サーバーのパフォーマンスに影響することがあります。詳細については、「オブジェクトのスコープを設定する」を参照してください。

Session オブジェクトに格納されている項目は、ときどき削除することをお勧めします。たとえば、オンライン ストアを利用するユーザーの気が変わり、一度購入すると決めたいくつもの商品の購入をやめ、まったく別の商品を購入することは、よくあることです。このような場合、不適切な値を削除して、Session オブジェクトを更新した方が便利です。

Session オブジェクトの Contents コレクションには、セッションに格納されている変数、つまり HTML <OBJECT> タグを使わずに格納された変数すべてが含まれています。Contents コレクションの Remove メソッドを使用して、セッションの状態に追加された変数への参照を選択し、削除することができます。次のスクリプトは、Remove メソッドを使用して項目を削除する方法を示しています。 このスクリプトでは、ユーザーの割引率の情報を Session オブジェクトから削除します。

<%
  If Session.Contents("Purchamnt") <= 75 then 
    Session.Contents.Remove("Discount")
  End If 
%>

必要に応じて、Contents コレクションの RemoveAll メソッドを使用して、セッションに格納されている変数すべてを完全に削除することもできます。

Session.Content.RemoveAll()
Remove メソッドを使用する場合、削除する項目は名前またはインデックスで選択できます。次のスクリプトは、Session オブジェクトに格納されている値をすべて調べ、条件に応じてインデックスで指定した値を削除する方法を示しています。
<%
  For Each intQuote in Session.Contents
    If Session.Contents(intQuote) < 200 Then
      Session.Contents.Remove(intQuote)  
    End If
  Next
%>

複数のサーバー全体のセッションを管理する

ASP のセッション情報は、Web サーバーに格納されます。ブラウザは、セッション情報にアクセスするために、同じ Web サーバーにページを要求する必要があります。Web サーバーのクラスタ (ここでは、多数の Web サーバーがユーザー要求に応答する責任を共有しています) では、ユーザー要求が常に同じサーバーに送られるわけではありません。その代わり、特殊なソフトウェアが、サイトの URL に対するすべての要求を空いているサーバーに分配します。 このプロセスは、"負荷分散" と呼ばれています。Web サーバーのクラスタでは負荷分散を行うため、セッション情報を保持することは困難です。

負荷分散が行われているサイトで ASP セッション管理を使用するには、ユーザー セッション内のすべての要求を同じ Web サーバーに向ける必要があります。それには、Session_OnStart プロシージャを作成し、Response オブジェクトを使用して、ユーザーのセッションが実行されている特定の Web サーバーにブラウザをリダイレクトするという方法があります。アプリケーション ページ内のすべてのリンクが相対 URL である場合、ページに対するそれ以降の要求は同じサーバーに向けられます。

たとえば、ユーザーがサイトの一般的な URL (http://www.microsoft.com) を要求してアプリケーションにアクセスする場合、負荷の分散を行うソフトウェアは、特定のサーバー (server3.microsoft.com など) に要求を向けます。ASP はそのサーバー上に新しいユーザー セッションを作成し、Session_OnStart プロシージャで、ブラウザは指定されたサーバーにリダイレクトされます。

<% Response.Redirect("http://server3.microsoft.com/webapps/firstpage.asp") %>

指定されたページをブラウザが要求すると、元の URL に特定のサーバー名が参照されていない限り、それ以降の要求はすべて同じサーバーに向けられます。

cookie の使い方

cookie は、ユーザーを識別するために、Web サーバーがユーザーの Web ブラウザに埋め込むトークンです。次に同じブラウザがページを要求するとき、ブラウザは Web サーバーから受け取った cookie を送信します。cookie を使うと、一連の情報をユーザーに関連付けることができます。ASP スクリプトでは、Response オブジェクトと Request オブジェクトの Cookies コレクションを使用して cookie の値の取得および設定ができます。

cookie を設定する

cookie の値を設定するには、Response.Cookies を使用します。cookie がまだ存在しない場合、Response.Cookies は新しい cookie を作成します。たとえば、cookie 名 ("VisitorID") と関連値 ("49") をブラウザに送信するには、次のコマンドを使います。 このコマンドは、Web ページの <HTML> タグより前に置く必要があります。

<% Response.Cookies("VisitorID") = 49 %>

現在のユーザー セッション中にのみ cookie を使う場合、必要なことはブラウザに cookie を送信することだけです。 ただし、ユーザーがブラウザを再起動した後もユーザーを識別する場合は、ブラウザを使用してクライアント コンピュータのハード ディスクのファイルに cookie を強制的に格納する必要があります。cookie を保存するには、Response.CookiesExpires 属性を使い、日付を将来の日付に設定します。

<%
  Response.Cookies("VisitorID") = 49 
  Response.Cookies("VisitorID").Expires = "December 31, 2001" 
%>

cookie には複数の値を設定でき、そのような cookie を "インデックス付き cookie" と呼びます。インデックス付き cookie の値には、キーが割り当てられます。 cookie のキー値は特定の値を設定できます。たとえば、次のように指定します。

<% Response.Cookies("VisitorID")("49") = "Travel" %>

既存の cookie にキー値があっても、Response.Cookies でキー名が指定されていない場合、既存のキー値は削除されます。同様に、既存の cookie にキー値がなくても、Response.Cookies でキー名と値が指定されている場合、cookie の既存の値は削除され、新しいキーと値の組み合わせが作成されます。

cookie を取得する

cookie の値を取得するには、Request.Cookies コレクションを使用します。たとえば、ユーザーの HTTP 要求で VisitorID=49 と設定されている場合、次のステートメントによって値 49 を取得できます。

<%= Request.Cookies("VisitorID") %>

同様に、インデックス付き cookie からキー値を取得するには、キー名を使います。たとえば、ユーザーのブラウザが次の情報を HTTP 要求ヘッダーで送信した場合、

Cookie: VisitorID=49=Travel

次のステートメントは、値 Travel を返します。

<%= Request.Cookies("VisitorID")("49") %>

cookie のパスを設定する

ASP によってユーザーの Web ブラウザに格納された各 cookie には、それぞれパス情報が入っています。ブラウザが、cookie に指定されたパスと同じ場所に格納されているファイルを要求すると、ブラウザは自動的に cookie をサーバーに送ります。cookie のパスの既定値は、もともと cookie を生成した .asp ファイルを含むアプリケーションの名前に対応します。たとえば、UserApplication というアプリケーションに含まれる .asp ファイルが cookie を生成したとします。 この場合、ユーザーの Web ブラウザがそのアプリケーションにあるファイルを取得するたびに、ブラウザは UserApplication によって作成された cookie、およびパス /UserApplication を含むその他の cookie を転送します。

cookie に対し、既定のアプリケーション パス以外のパスを指定するには、ASP の Response.Cookies コレクションの Path 属性を使用できます。たとえば、次のスクリプトは、Purchases という cookie にパス SalesApp/Customer/Profiles/ を割り当てます。

<%
  Response.Cookies("Purchases") = "12" 
  Response.Cookies("Purchases").Expires = "January 1, 2001" 
  Response.Cookies("Purchases").Path = "/SalesApp/Customer/Profiles/"
%>

Purchases cookie を含む Web ブラウザがパス /SalesApp/Customer/Profiles/ またはそのサブディレクトリにあるファイルを要求するごとに、ブラウザは Purchases cookie をサーバーに転送します。

Microsoft Internet Explorer Version 4.0 以降や Netscape のブラウザなど、多くの Web ブラウザは、cookie のパスの大文字と小文字を区別します。したがって、要求されたファイルのパスと格納された cookie のパスの大文字と小文字が異なる場合、ブラウザは cookie をサーバーに送信しません。たとえば、ASP にとっては、仮想ディレクトリ /TRAVEL と /travel は同じ ASP アプリケーションですが、URL の大文字と小文字を区別するブラウザにとっては、/TRAVEL と /travel は 2 つの異なるアプリケーションです。.asp ファイルを示すすべての URL の大文字と小文字が同じであることを確認し、ユーザーのブラウザが、格納された cookie を確実に転送するようにしてください。

次のステートメントを使用して cookie のパスを設定すると、ブラウザがサーバーのファイルを要求したときは、アプリケーションやパスに関係なく、常にユーザーの Web ブラウザが cookie を転送するようにできます。

Response.Cookies("Purchases").Path = "/"

ただし、cookie に重要な情報が入っていて、特定のアプリケーションの外からはアクセスできないようにしている場合があるので注意してください。 その場合、アプリケーションを区別せずにサーバーに cookie を転送するよう設定すると、セキュリティ上の問題が発生することがあります。

cookie を使わずに状態を保存する

すべてのブラウザが cookie をサポートしているわけではありません。また、cookie をサポートしているブラウザでも、ユーザーによっては cookie のサポートを無効にしていることがあります。アプリケーションが cookie をサポートしていないブラウザに応答する必要がある場合は、ASP セッション管理は使用できません。

ASP セッション管理を使わない場合、独自のメカニズムを作成してアプリケーションのページ間で情報の受け渡しを行う必要があります。一般に、次の 2 とおりの方法があります。

ASP のセッション管理を使わない場合、アプリケーションのセッション サポートは無効にしてください。セッションが有効になっている場合、ASP はページを要求するすべてのブラウザに SessionID cookie を送信します。セッション サポートを無効にするには、インターネット インフォメーション サービス スナップインの [アプリケーションのオプション] プロパティ シートで [セッションの状態を有効にする] チェック ボックスをオフにします。

セッションレス ASP ページ

ASP では、セッションレス ページを作成することもできます。セッションレス ページを使うと、セッションの追跡を必要とする ASP ページが利用されるときまで、セッションの作成を遅らせることができます。

セッションレス ページでは、次の処理は "行いません"。

.asp ファイルをセッションレスとして構成するには、次のコマンドを使います。

<%@ EnableSessionState=False %>

このスクリプトは .asp ファイルの先頭行に置き、ほかのスクリプトはその後に置きます。このタグを省略した場合、既定値としてセッションの追跡が有効になります。

セッションレス ASP ページでは、潜在的に時間がかかるセッション活動がないため、ほとんどの場合、サーバーの応答が改善されます。たとえば、2 つの HTML フレームが入った ASP ページの場合を考えてみます。フレーム 1 とフレーム 2 は、1 つのフレームセット内にあります。フレーム 1 には、複雑なスクリプトを実行する .asp ファイルが含まれ、フレーム 2 には、単純な .asp ファイルが含まれます。ASP は、セッション要求を "順番に" 実行するため、フレーム 1 のスクリプトの実行が完了するまで、フレーム 2 の内容は見ることができません。しかし、フレーム 1 の .asp ファイルをセッションレスにした場合、ASP 要求は順次実行されず、フレーム 1 の内容の実行が終了する前に、ブラウザはフレーム 2 の内容を表示します。

残念ながら、異なるフレームに対する複数の要求がどのように処理されるかは、最終的にはユーザーの Web ブラウザの構成に依存します。Web ブラウザによっては、.asp ファイルの構成がセッションレスであるにも関わらず、要求が順次実行される場合もあります。


© 1997-2001 Microsoft Corporation.All rights reserved.