*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>の中に記入してもらった
例えばメイルアドレスを、次回再記入してもらうときに、
自動的に記入欄に埋め込むようなことも出来ません。もし自分のページ用に、データを保存することが出来れば、
背景色や、アドレスを保存しておいて、必要になったときに
それを呼び出すことによって、これを実現することができます。もちろん、初めてページを見てもらったときには、
クッキーには何も保存されていませんが
このとき、必要なデーターをクッキーに保存しておけば、
自分の他のページや、次回リピートの閲覧をしてもらったときに
それを呼び出して、使うことができるようになるのです。
上でご説明したように、閲覧者のシステムの中に保管されます。
ブラウザが管理している特定の場所に保管されるのです。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 の出来ることは、
データーを「登録」「読み出し」「削除」の3種類です。
これらは、一つの JavaScript の命令で行われるのではなく
チョット複雑な一連の処理が必要になります。クッキーの仕様に従って処理しなくてはいけないので、
JavaScript の書き方は多少変わるだけですから
開発済みの「関数」を利用するのが便利です。Bill Dorch 氏の開発した「関数」の利用をお勧めします。
http://www.hidaho.com/cookies/cookie.txt で参照出来ますが、
ここでご紹介しておきます(一部、アレンジしてあります)。
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 エラーになります。
多くの方にご迷惑をお掛け致しましたことを、お詫び申し上げます。
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 になります。
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
クッキーは閲覧者のシステムに記録される、ということです。閲覧者はブラウザの設定で、クッキーの受け入れを拒否できます。
不用意なクッキー投入で、閲覧者がクッキー拒否派になれば
閲覧者も利用できないし、善良なページも機能しなくなってしまいます。クッキーの投入は自分のページだけでなく、他人のページにも、
有形無形の影響力があることに、充分配慮する必要があるのです。
複数の項目を保存したいときに、キーワードを増やすのではなく(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 の値がセットされることになります。
有限な閲覧者のディスクを、利用させて戴いているのです。(3)有効期限は、必要最短にして下さい。
他のページも、利用します。お互いに、譲り合いましょう。
クッキーはJavaScriptで、ディナーはレストランcgiで...
使わなくなったクッキーでも、賞味期限までは保管されるのです。(4)テストは、くれぐれも厳重にやって下さい。
ミスがあって、既に記録されてしまった閲覧者のクッキーを(5)プライバシーを侵害する畏れのあるデータは記録しないで下さい。
修正したくなっても、直接修正する方法はありません。
それには、修正ロジックを組み込んだJavaScriptを作成し、
ページに載せて修正するしか、方法はないのです。
(お恥ずかしいのですが、「幕の内弁当」にも現在組み込んであります)また、ブラウザが閲覧者のシステムに侵入できないように
保護している筈ですが、あなたのJavaScriptが
閲覧者のシステムに不具合を発生させないことが100%
保証されている訳ではありません。ロジックが複雑になれば、普通のプログラムと同等に、
或いはそれ以上に、テストデーターによるデバッグが必要です。
ブラウザは、ある程度の保護はしていますが、(6)出来るだけ多くの種類のブラウザを用意してテストして下さい。
漏洩の可能性を、否定することは出来ません。
あなたが要求保存したデータが、漏洩することを前提として、
閲覧者側に立ってデザインをするように、心がけて下さい。
Netscape は v2.0 以降で完全に動作しますが、(7)クッキーは、メモ帳、テキストエディタで修正すると破壊されます。
Microsoft Internet エクスプローラは v3.0 以降です。
また、ローカルディスクからテストしようとすると、
MSIE 3.02 for Win3.1 ではエラー、MSIE 3.01 for Win95 では、
cookie を書き込んでくれません。リモートで、サーバーからロードする場合は正常に動作します。
従って、ローカルディスクでテストする場合は、
Netscape Navigator Ver 2.0 以上が必要となります。
クッキーのテストをする時は、必ずバックアップを取って下さい。
(8)クッキーは、ディレクトリ単位で作られます。*1
"KEYWORD" を同じにしても、ディレクトリが変わると、
新しいクッキーが作られます。つまり、パス単位で作られるのです。上位で作られたクッキーを、それより階層の低いディレクトリで
同じ "KEYWORD" で読み出すと、上位のクッキーを読み出します。
けれども、書き込みをすると、新しいクッキーが作られます。
従って階層の低いディレクトリで、2度目の読み出しでは、
自分の作った新しいクッキーを読み出すことになります。上位の階層では、下位の階層にクッキーが有っても無くても、
常に自分のクッキーを読んだり、書いたりすることになります。
つまり、上位の階層で作ったクッキーを、下位の階層では
更新することが出来ない、ということです。上位の階層で書き込まないで、下位の階層で作ったクッキーを、
上位で読みだそうとしても読み出せません。未定義となります。<ご注意> 実は、この説明は正しくありません。
サンプルで示した関数が、ディレクトリ(パス)の指定を
していないから、このようなことが起きるのです。
つまり、暗黙に自分自身のパスを指定しているからなのです。
パスを適切に指定すれば、このようなことにはなりません。サンプルの関数は、この指定が出来るようになっていますが、
説明は割愛します。 挑戦する方は、コードを解読してください。初めてクッキーに挑戦してみる方で、複数のページで
同じクッキーを使いたい場合は、ページを同じディレクトリに
入れて利用されることを、強くお勧め致します。
クッキーは、サーバーからCGIを使っても、操作できますが、
詳細については、「幕の内弁当」の範囲を超えますので割愛します。
運用上は、JavaScript との併用が、便利と思います。クッキーの内容を取得するには、<FORM>の中に項目を設定し、
代入しておけば、閲覧者の submit(送信)により、送信されます。
TYPE="hidden" を使用すれば、表示されません。
この操作は、フォーム以外のCGIは必要ありません。