クッキーとは何でしょう
クッキーは何故必要になるのでしょう
クッキーは何処に保管されのでしょう
クッキーと JavaScript について
クッキーはどうやって保管するのでしょう*2,*3,*4
クッキーはどうやって取り出すのでしょう
クッキーをどうやって削除するのでしょう*5
クッキーはいつまで保管されているのでしょう
他のページのクッキーとの関係について
クッキーはどんな利用が考えられるでしょう
「幕の内弁当」での応用紹介
簡単な応用サンプルの紹介*6
クッキーを使うときの注意事項について*1,*2
サーバーからのクッキーの操作について

*1 98/01/14 saijoinx様からのご指摘で一部追加
*2 98/01/14 yosj's! HOME-PAGE様からのご指摘で補足
*3 98/08/23 すえぽんさいと様からのご指摘で訂正
*4 98/10/03 書き込み関数の呼び出しにキーを追加した
*5 98/10/08 kyu@doi様からのご指摘で削除関数の記述誤りを訂正
*6 99/02/26 良寛様からのご指摘で削除関数の記述誤りを訂正


クッキーとは何でしょう

 クッキーとは、ホームページ単位で保存することが出来て、
かつ、必要なときに呼び出せるデータのことをいいます。
データーべースの様に大量なデータではなく、
チョットかじる程度の(これがクッキーの語源と思いますが)、
メモ的なデータが対象となります。

 一般的に、何かデータを保存する場合はサーバに保存します。
その為には、サーバーを動かす、CGIとかSSIと呼ばれる
サーバー用のプログラムを作る必要があります。
それには、かなり専門的なプログラムの知識が必要になります。

 しかし、技術的な問題や、サーバーのパワー、セキュリティ、
或いは保安上の問題などで、これらのプログラムの使用を、
禁止しているプロバイダーも少なくありません。

 ところがクッキーは、閲覧者のシステムに記録されるのです。
しかも、HTMLの中に書かれた JavaScript によって動作するのです。
ですから、サーバーを動かすプログラムを使う必要はありません。
どのプロバイダーのサーバーでも利用することが出来るのです。

 新規登録、内容変更、読み出し、削除したりすることが出来ます。
Navigator の場合、ドメイン別に20個、1個当たり4キロバイト、
全部で300個迄の制限があります。


クッキーは何故必要になるのでしょう
 HTMLだけで作ったページの、表示内容は固定的です。
例えば背景色は、<BODY BGCOLOR=.....>によって固定されます。

 JavaScript を使えば、閲覧者に背景色を選んでもらい、
onClick とか onMouseOver によってdocument.bgColor="....." で、
変化させることができます。

 けれどもサブページにリンクした時にも、その色を
引き続き背景色にすることは出来ません。
勿論、次回に再訪してくれたときに、前回選択した背景色で
表示するということは、なお出来ないことです。

 また、<FORM>の中に記入してもらった
例えばメイルアドレスを、次回再記入してもらうときに、
自動的に記入欄に埋め込むようなことも出来ません。

 もし自分のページ用に、データを保存することが出来れば、
背景色や、アドレスを保存しておいて、必要になったときに
それを呼び出すことによって、これを実現することができます。

 もちろん、初めてページを見てもらったときには、
クッキーには何も保存されていませんが
このとき、必要なデーターをクッキーに保存しておけば、
自分の他のページや、次回リピートの閲覧をしてもらったときに
それを呼び出して、使うことができるようになるのです。


クッキーは何処に保管されているのでしょう*2
 上でご説明したように、閲覧者のシステムの中に保管されます。
ブラウザが管理している特定の場所に保管されるのです。

 Netscape では Netscape フォルダーに cookies.txt という名前で
テキストファイルが作られています。
このファイルの中に、すべてのページのクッキーが
URL単位のレコードとして保存されています。
例えば C:\Program Files\Netscape\Users\.....\cookies.txt です。

 インターネットエクスプローラでは、windows フォルダーの中に
cookies と言う名前のフォルダーがあり、その中にそれぞれ
URL単位のテキストファイルとして作成されています。
例えば C:\Windows\Cookies\.....@URL.txtです。

 皆さんのシステムの中にも、既に幾つかのクッキーが
作られていると思います。「幕の内弁当」のクッキーも
作られているはずです。キーコードは「history」です。

ご注意:形はテキストファイルですが、特殊な構造です。
    メモ帳などで、内容を変更すると破壊されます。


クッキーと JavaScript について
 クッキーは、JavaScript を使って保存し、
JavaScript を使って読み出すことが出来ます。
JavaScript の機能の中で、最も高度なものと言えます。

 クッキーの取り扱いで JavaScript の出来ることは、
データーを「登録」「読み出し」「削除」の3種類です。
これらは、一つの JavaScript の命令で行われるのではなく
チョット複雑な一連の処理が必要になります。

 クッキーの仕様に従って処理しなくてはいけないので、
JavaScript の書き方は多少変わるだけですから
開発済みの「関数」を利用するのが便利です。

 Bill Dorch 氏の開発した「関数」の利用をお勧めします。
http://www.hidaho.com/cookies/cookie.txt で参照出来ますが、
ここでご紹介しておきます(一部、アレンジしてあります)。


クッキーはどうやって保管するのでしょう

name の値をキーとして、value の内容をクッキーに書き出す関数

function SetCookie (name,value)
{
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path    = (argc > 3) ? argv[3] : null;
var domain  = (argc > 4) ? argv[4] : null;
var secure  = (argc > 5) ? argv[5] : false;

document.cookie = name + "="  + escape (value) +
 ((expires == null) ? ""		: ("; expires=" + expires.toGMTString())) +
 ((path == null)    ? ""		: ("; path=" + path)) +
 ((domain == null)  ? "" 	: ("; domain=" + domain)) +
 ((secure == true)  ? "; secure" : "");
}

// 消去日の設定は、この関数の中に指定します
function set_data(name,put_data)
{
var expdate = new Date ();
expdate.setTime (expdate.getTime() + (24 * 60 * 60 * 1000 * 31 * 1));
SetCookie (name,put_data,expdate);
}

特別の理由がなければ、このままコピーして下さい。

クッキーを保管するときに、必要な設定値は

(1)キーを決める。(例えば KEYWORD)
(2)有効期限を決める(例えば1ヶ月)

消去日(expdate.setTimeの計算式)末尾の"1"は 必要があれば、変更して下さい。
これらをセットした関数を用意しておいて、
書き込みたいデータ "new_data" を、次のように指定します。
set_data("KEYWORD",new_data)

これで、書き込みが完了します。

*3
  閉じ括弧を全角から半角に訂正致しました。
訂正前のスクリプトは、 JavaScript エラーになります。
多くの方にご迷惑をお掛け致しましたことを、お詫び申し上げます。


クッキーはどうやって取り出すのでしょう

name で指定されたキーのクッキーを読み出す関数

function GetCookie (name)
{
	var arg  = name + "=";
	var alen = arg.length;
	var clen = document.cookie.length;
	var i = 0;
	while (i < clen)
		{
		var j = i + alen;
		if (document.cookie.substring(i, j) == arg)
		return getCookieVal (j);
		i = document.cookie.indexOf(" ", i) + 1;
		if (i == 0) break;
		}
	return null;
}

function getCookieVal (offset)
{
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
	endstr = document.cookie.length;
	return unescape(document.cookie.substring(offset,endstr));
}

この関数を用意しておいて、

get_data = GetCookie("KEYWORD")

これで、get_data にクッキーが代入されます。
もし、そのキーでクッキーが登録されていない場合は、
get_data の内容は、null になります。


クッキーをどうやって削除するのでしょう

name で指定されたキーのクッキーを削除する関数

function DeleteCookie (name)
{
var exp =new Date();
exp.setTime(exp.getTime() - 1);
var cval = GetCookie (name);
document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}

この関数を用意しておいて、

DeleteCookie ("KEYWORD")

これで、削除になります。
有効日を「現在まで」として、ブラウザに削除させているのです。

*5 削除関数4行目 name + cval を name + "=" + cval に訂正


クッキーはいつまで保管されているのでしょう
 クッキーには、データの有効日の概念があります。
これを経過すると自動的に削除されます。

 例えば、データーの内容を変更し書き込むときに、
有効日を1ヶ月先にしておけば、書き込んだ時から、
常に1ヶ月先まで、保存されることになります。

 勿論、自動的に削除されても、再度登録のやり直しを
すれば、再び使用できるようになります。


他のページのクッキーとの関係について
 他人のクッキーを呼び出したり、書き直すことは出来ません。
従って自分のクッキーが、他人に利用されることもありません。

 登録したり、読み出したりするときは「キーワード」を
指定するわけですが、この「キーワード」は、
その指定が出るページのURLの範囲で有効なのです。
その範囲を超えるクッキーにはアクセスできないように、
ブラウザが管理してくれています。


クッキーはどんな利用が考えられるでしょう
 何にどう使うかは、アイディア次第ということになります。
ご紹介できるほど、アイディアを持ちあわせておりませんが、
機能的には、閲覧者側の行動、状況、履歴情報を保持でき、
かつ読み出して再利用できる、ブラウザ側での情報局所化が実現し、
インタラクティブなページを実現出来るということなのです。

 従って、例えば、

(1)フォーム等で入力された情報
(2)選択されたメニュー、或いは情報
(3)ゲーム等での進行情報、到達ポイント
(4)来訪日、その時刻
(5)来訪回数
等が、その対象となる情報と考えられるでしょう。
これらをどう利用するかは、ページの目的によって変わるでしょう。


「幕の内弁当」での応用紹介
「幕の内弁当」では、次の情報を記録させていただいています。

初めてご来訪戴いた日:
前回のページの更新日:
ご覧のページの更新日:
ご覧のページの来訪日:
初回以降ご来訪の回数:

 この情報を、トップページで次のように利用しています。

(1)来訪者個別の来訪回数をお銚子画像で表示
(2)前回来訪日以後の更新ページを点滅ランプ表示
(3)前回来訪日以降未更新の時、工事中アニメの表示
(4)未更新日数をお銚子の首の長さに変換して表示
(5)初回来訪日以降の累積来訪率をグラフ表示
(6)更新状況によるウエルカムメッセージの切り替え
(7)来訪10回毎の、料理交換コントロール

 これらの状況は、来訪者毎に違う訳ですから、
個別の履歴情報がないと、表示することが出来ません。
簡単な処理の流れは、フローチャートをご参照下さい。
(お詫び:ブラウザによっては正常に表示できません)


簡単な応用サンプルの紹介

<HTML>
<HEAD>
<TITLE>クッキーによる訪問回数の実験</TITLE>

<SCRIPT LANGUAGE="JavaScript">
<!------

//(ここに、クッキーの「保管」と「取り出し」の関数を定義して下さい)

// ------>
</SCRIPT>

</HEAD>
<BODY BGCOLOR=#E0E0F0>
<CENTER>
ブラウザの「再読み込み」または「更新」ボタンを押すか、<br>
ブラウザをクローズして、再度立ち上げてみて下さい。<p>
<TABLE BORDER=1 BGCOLOR=mistyrose><TR><TD ALIGN=center>
<BR>

<SCRIPT LANGUAGE="JavaScript">
<!------

// KEYWORD を key にしてクッキー読み込み
times = GetCookie("KEYWORD")

if (times == null)
	times = 1	// 未登録なら、回数=1
else
	times ++	// 登録済みなら、回数を1増やす

// クッキーの更新
set_data("KEYWORD",times)

if (times == 1)
	document.write("初めてのご来訪、ようこそいらっしゃいました")
else
	document.write("また来てくれましたね。" + times + "回目ですね")

// ------>
</SCRIPT>

<P>
今までの訪問回数をゼロにするときは、ボタンを押して下さい。<BR>
<FORM>
<INPUT TYPE="button" NAME="dummy"
	VALUE="ゼロクリヤー" onClick="set_data('KEYWORD',0)">
</FORM>
</TABLE>
</CENTER>
</BODY>
</HTML>

ローカルディスクからは、クッキーが動作しないブラウザがあります。

*6 ゼロクリヤー関数呼び出しの "KEYWORD" を 'KEYWORD' に訂正


クッキーを使うときの注意事項は何でしょう

 最も気を付けなくてはならないことは、
クッキーは閲覧者のシステムに記録される、ということです。

 閲覧者はブラウザの設定で、クッキーの受け入れを拒否できます。
不用意なクッキー投入で、閲覧者がクッキー拒否派になれば
閲覧者も利用できないし、善良なページも機能しなくなってしまいます。

 クッキーの投入は自分のページだけでなく、他人のページにも、
有形無形の影響力があることに、充分配慮する必要があるのです。

(1)キーワードをいたずらに増やさないで下さい。*2

 複数の項目を保存したいときに、キーワードを増やすのではなく
キーワードは一つにしておいて、連続したデータとします。

 「幕の内弁当」では、history を KEYWORD として、
クッキーのフォーマットを、次のように設定しています。

99/99/99,99/99/99,99/99/99,99/99/99,999
初回来訪日,前回更新日,最新更新日,最新来訪日,来訪回数

 つまり、5種類の記録データーを、個別のキーで
保存するのではなく、このように結合してしまい、
1種類の連続した39桁のデーターにしているのです。

 データーの区切りとして "," を入れていますが、
これは必須ではありません。
ベタ詰めにすれば、35桁になります。

 区切りを入れている理由は、テストの時に見やすいのと、
先々、このデーターを活用するときに、
「区切り文字の付いたテキストファイル」即ち csv形式
にしておいたほうが、都合が良さそうだったからです。

日付の形式が、99/99/99 になっていますが、
これも 999999 でも差し支えありません。
表示するときに、余計な編集をしなくても済むからです。

 さて、例えばいま、

aa = "98/01/01"; //初回来訪日
bb = "98/01/05"; //前回更新日
cc = "98/01/06"; //最新更新日
dd = "98/01/10"; //最新来訪日
ee = "002";    //来訪回数

こんな値がセットされているとします。

set_data(aa + "," + bb + "," + cc + "," + dd + "," + ee)

これで、上記のフォーマットでクッキーが記録されます。

 次に、

v_data = GetCookie("KEYWORD")	// クッキーの取得

if (v_data == null)		// 未登録の時、null がセットされる
	{			// 未登録の時、初期値セット
	first    = "98/01/01";
	v_update = "98/01/01";
	s_update = "98/01/01";
	last     = "98/01/01";
	times    = "000";
	}
else	{			// 登録されている時、項目に分解
	first    = v_data.substring(0,8);
	v_update = v_data.substring(9,17);
	s_update = v_data.substring(18,26);
	last     = v_data.substring(27,35);
	times    = v_data.substring(36,39);
	}

これで、
first には、aa の値、
v_update には、bb の値、
s_update には、cc の値、
last には、dd の値、
times には、ee の値がセットされることになります。

(2)大きなデーターを保管しないで下さい。

 有限な閲覧者のディスクを、利用させて戴いているのです。
他のページも、利用します。お互いに、譲り合いましょう。
クッキーはJavaScriptで、ディナーはレストランcgiで...

(3)有効期限は、必要最短にして下さい。

 使わなくなったクッキーでも、賞味期限までは保管されるのです。

(4)テストは、くれぐれも厳重にやって下さい。

 ミスがあって、既に記録されてしまった閲覧者のクッキーを
修正したくなっても、直接修正する方法はありません。
それには、修正ロジックを組み込んだJavaScriptを作成し、
ページに載せて修正するしか、方法はないのです。
(お恥ずかしいのですが、「幕の内弁当」にも現在組み込んであります)

 また、ブラウザが閲覧者のシステムに侵入できないように
保護している筈ですが、あなたのJavaScriptが
閲覧者のシステムに不具合を発生させないことが100%
保証されている訳ではありません。

 ロジックが複雑になれば、普通のプログラムと同等に、
或いはそれ以上に、テストデーターによるデバッグが必要です。

(5)プライバシーを侵害する畏れのあるデータは記録しないで下さい。
 ブラウザは、ある程度の保護はしていますが、
漏洩の可能性を、否定することは出来ません。
あなたが要求保存したデータが、漏洩することを前提として、
閲覧者側に立ってデザインをするように、心がけて下さい。

(6)出来るだけ多くの種類のブラウザを用意してテストして下さい。
 Netscape は v2.0 以降で完全に動作しますが、
Microsoft Internet エクスプローラは v3.0 以降です。
また、ローカルディスクからテストしようとすると、
MSIE 3.02 for Win3.1 ではエラー、MSIE 3.01 for Win95 では、
cookie を書き込んでくれません。

リモートで、サーバーからロードする場合は正常に動作します。
従って、ローカルディスクでテストする場合は、
Netscape Navigator Ver 2.0 以上が必要となります。

(7)クッキーは、メモ帳、テキストエディタで修正すると破壊されます。

クッキーのテストをする時は、必ずバックアップを取って下さい。

(8)クッキーは、ディレクトリ単位で作られます。*1

 "KEYWORD" を同じにしても、ディレクトリが変わると、
新しいクッキーが作られます。つまり、パス単位で作られるのです。

 上位で作られたクッキーを、それより階層の低いディレクトリで
同じ "KEYWORD" で読み出すと、上位のクッキーを読み出します。
けれども、書き込みをすると、新しいクッキーが作られます。
従って階層の低いディレクトリで、2度目の読み出しでは、
自分の作った新しいクッキーを読み出すことになります。

 上位の階層では、下位の階層にクッキーが有っても無くても、
常に自分のクッキーを読んだり、書いたりすることになります。
つまり、上位の階層で作ったクッキーを、下位の階層では
更新することが出来ない、ということです。

上位の階層で書き込まないで、下位の階層で作ったクッキーを、
上位で読みだそうとしても読み出せません。未定義となります。

<ご注意> 実は、この説明は正しくありません。

 サンプルで示した関数が、ディレクトリ(パス)の指定を
していないから、このようなことが起きるのです。
つまり、暗黙に自分自身のパスを指定しているからなのです。
パスを適切に指定すれば、このようなことにはなりません。

 サンプルの関数は、この指定が出来るようになっていますが、
説明は割愛します。 挑戦する方は、コードを解読してください。

 初めてクッキーに挑戦してみる方で、複数のページで
同じクッキーを使いたい場合は、ページを同じディレクトリに
入れて利用されることを、強くお勧め致します。


サーバーからのクッキーの操作について
 クッキーは、サーバーからCGIを使っても、操作できますが、
詳細については、「幕の内弁当」の範囲を超えますので割愛します。
運用上は、JavaScript との併用が、便利と思います。

 クッキーの内容を取得するには、<FORM>の中に項目を設定し、
代入しておけば、閲覧者の submit(送信)により、送信されます。
TYPE="hidden" を使用すれば、表示されません。
この操作は、フォーム以外のCGIは必要ありません。


クッキーを使えば、CGIにも負けない、
素晴らしいページが実現します。
さあ、さっそく実験を始めましょう。