JavaScriptでcookieを使う話

 掲示板などのCGIでcookieを使う場合、たいていの場合はCGIが直接cookieを処理する。 誰かがそのCGIに書き込みなどをしたとき、名前やメールアドレスをcookieとして記録し、次にそのCGIにアクセスしたときに、そのcookieデータをCGIが取得して、フォームの初期値に「value="なんたらかんたら"」というように使用するのだ。
 しかし、この形式でcookieを使う場合、フォームを呼び出されるときに必ずCGIが動かなければならない。 つまり、HTMLファイルを出力するタイプの掲示板では使用できないのだ。

 すでに出力されたHTMLファイルからcookieを使う方法はないだろうか?

 ある。

 JavaScriptを使えばいいのだ。

 では、理論編(なにがどーなってなにををどーするのか)と、実践編(具体例とその解説っぽいもの)にわけて、話を進めることにしよう。

理論編:なにがどーなってなにをどーするのか

1、cookieの書式とかなんとか。

 cookieには、文字列以外にも情報が付加される。
 cookieを保存する期間(通称:賞味期限)、cookieを記録したURL、cookieの名前、などがくっついてくるのだ。 実際のcookieを見たかったら、ブラウザの設定で、cookieを受け入れる前に警告するようにするといい。 ブラウジング中に、いろいろなcookieをもらうことができるはずだ。

 また、ブラウザをインストールしてあるフォルダに、cookies.txtとかがあると思うので見てみるのもいいだろう。 なお、このファイルをエディタで修正しようとすると、cookieがすっきりなくなったりするので注意。

 で、まあ、具体的には、
「name=文字列」「name2=文字列2」
などという形式でセーブされて、
それを呼び出してくると、
「name=文字列; name2=文字列2; name3=文字列3; name4=文字列4;」
とかいう形でロードされてくる。

 というふうに理解しておけばいいんじゃないだろうか?

2、cookieで情報を保存したりする。

 cookie使用の第1歩、とりあえずcookieで情報を保存する方法だ。
 JavaScriptだから、
document.cookie="なんたらかんたら";
とか書いて保存する。

 具体的な書式については後程ということで。

3、cookieで情報を呼び出したりする。

 で、cookie使用の第2歩であり、もしかしたら最終目的、cookie情報を反映させる方法である。
 基本的には、
string=document.cookie;
とか書いてやればいいのだが、こうやって書くとstringという変数にcookieの中身が全て代入される。
 さっきの例でいうところの
「name=文字列; name2=文字列2; name3=文字列3; name4=文字列4;」
っていうのが全部代入されるのだ。

 ここから、nameの値をつかって、必要な値を抽出する作業が君を待っている。

 その具体的なやり方はやっぱしまた後程。

4、呼び出したりした文字列を使うとか。

 ともかく、JavaScriptの変数に代入してしまえばこっちのものだ。
document.フォームの名前.要素の名前.value=string;
とか書いてテキストボックスにつっこんでやればいい。

 まあ、あるいは、その文字列で分岐して違う処理をさせてみてもいいし、だいなみっくHTMLな気分で画面内を飛び回らせたりしても構わない。(飛び回らせてどうするかは知らないが・・・)

実践編:具体例とその解説っぽいもの

 実際に動作するJavaScriptのプログラムを掲示して、それを解説してみよう。 とりあえず動作するものがこっち。新しいwindowで開くのがいいだろう。

 「記録」でテキストボックスの内容をクッキー情報として保存して。
 「呼び出し」でそれを呼び出してテキストボックスに表示する。
 「りせっと」はフォームのリセットボタン、type="reset"だ。

 ブラウザの設定で、cookieを受け取る前に警告するようにしておいて、何か文字列を書いて記録ボタンを押す。
 もちろん、JavaScriptも有効にしておく必要がある。
 すると、cookieを送ってくる(完全にあなたのマシンローカルで行われているのだが)1日で消えてしまうようなものなので、とりあえず受け入れてもらいたい。

 さて、りせっとボタンを押して、内容を消してから、 呼び出しボタンを押すと、さっきの内容がフォームに書き込まれる。
 一度別のページを見たり、ブラウザを閉じてから、(1日以内に) また同じページを開いても、やはり内容がフォームに書き込まれる。

 さて、このプログラムについて解説していこう。

 で、ソースと解説はこんな感じ。

<html>

<head>
<title>JavaScriptCookie</title>

<script language="javascript">
<!--
JavaScriptを使うときのお約束。
JavaScript非対応ブラウザのために、<!--と書いておきます。

ckusr = "";
ckeml = "";
ckurl = "";
初期値の代入、それほど大した意味はないが、これがないとエラーになったりする。
本当は文字列型の変数として定義するべきなんだろうけどね。

function setck(){
cookieを保存したりするfunction(関数):setck()の宣言。

usr = document.forms[0].usr.value;
eml = document.forms[0].eml.value;
url = document.forms[0].url.value;
フォームに記入された値を変数に代入。
詳しくはJavaScriptの資料を見てもらうのがいいのだが、大まかに言うと、
「forms[0]」は、ページ内の1つめのフォーム<form>〜</form>のことで、
その後の「url」や「eml」は、テキストボックスにつけられた名前である。

//alert ('◎フォームの内容\n'+usr+' '+mail+' '+url);
虫退治&動作チェック用のおまじない。
//でコメントアウトしてるから、実際は動作しない。

var now=new Date();
var exp=new Date();
日付型の変数としてnowとexpを定義

exp.setTime(now.getTime()+1000*60*60*24*1);
expを1日後にセット。ちなみにgetTime()で現在時間を取得し、
その後の「1000*60*60*24*1」で1日分追加している。
なお、JavaScriptの時間は、1/1000秒が基本単位である。

document.cookie = "h99-usr=" + escape (usr) + "; expires=" + exp.toGMTString();
document.cookie = "h99-eml=" + escape (eml) + "; expires=" + exp.toGMTString();
document.cookie = "h99-url=" + escape (url) + "; expires=" + exp.toGMTString();
クッキー情報を書き込む、h99-***ってゆーのは単なる名前、勝手につけて構わない。
escape()は、文字列のアスキーコード(よーするに文字コード)を返すもの、
文字コードの話を参照のこと。
変な文字列いれるとプログラムの誤動作の原因になるから逃がしている。
やらなくてもそれほど大きな問題は発生しないと思うけどね。
expires=で、クッキーの賞味期限を決める。
exp.toGMTString()は、expを標準形式に変換している。

}
setck()はここまで。

function getck(){
cookieを呼び出したりする関数getck()の宣言

//alert ('◎cookie文字列全体\n'+document.cookie);
虫退治&動作チェック用のおまじない。
//でコメントアウトしてるから、実際は動作しない。

cklng = document.cookie.length;
cookie文字列全部の長さ。理論編の例で言うところの
「name=文字列; name2=文字列2; name3=文字列3; name4=文字列4;」
全部の長さ。

i = 0;
ループ用のiの初期値。すぐ後のwhile文の条件で使うから初期値が必要。

while (i < cklng){
iがcklng(cookieの長さ)より小さい限りループし続ける。
このループで、「name=文字列」のペアを探し出し、
文字列を適宜変数に代入する処理を行っている。

	j = document.cookie.indexOf(" ", i);
変数jは、cookie文字列のなかで、i番めから探して最初に半角スペースがあった場所。
「name=文字列;」の直後の空白を探している。
ちなみにindexOf()は、指定文字列が何バイトめに出てくるかを調べるものである。

	if (j == -1) j = cklng+1;
半角スペースがなかったらjは-1を返す。その場合はcookie文字列の最後まで

	ckstr = document.cookie.substring(i,j-1);
iからj-1までを、ckstrという文字列に代入。
ckstrは、「name=文字列」という形式になる。
substring()は、文字列から、指定された部分を取り出すものである。


●ここが重要!
与えられるcookie文字列が例によって以下のものだったとする。
「name=文字列; name2=文字列2; name3=文字列3; name4=文字列4;」
すると最初のiは0だから、そのときのjは「文字列;」の直後の空白の位置を指す。
2回目には、i=j+1で、「name2」の最初のnの位置、
そのときのjは、「文字列2;」の後の空白の位置だ。 
3回目以降も同様で、最後の1回については、jは文字列全体の長さ+1だから、
「文字列4;」の直後の位置になり(何もないけどね)
substring(i,j-1)で、無事に「name=文字列」が取り出せる。

//alert ('◎名前と文字列のペア\n'+ckstr);
動作チェック用

	cknam = ckstr.substring(0,8);
「name=文字列」から「name=」を切り出す。
この8という数字は、cookie情報を保存するときにつけた、
「h99-***=」という文字列の長さである。

//alert ('◎名前部分\n'+cknam);
例によってチェック用

	strln = ckstr.length;
「name=文字列」という文字列の長さを求める。

	if (cknam == "h99-usr=") ckusr = unescape(ckstr.substring(8,strln));
	if (cknam == "h99-eml=") ckeml = unescape(ckstr.substring(8,strln));
	if (cknam == "h99-url=") ckurl = unescape(ckstr.substring(8,strln));
「name=文字列」の「name=」部分(変数cknam)が、
保存したときのnameの値「h99-***=」と一致していたら、
「name=文字列」の「文字列」部分を、変数に代入(これを後で使う)。
なお、unescape()は、escape()の逆。アスキーコードを文字列に戻す。

	i = j+1;
iの値をj+1にする。つまり、次の「name=文字列」の頭に合わせる。
上記の「●ここが重要!」を参照のこと。

//alert ('◎iとcklngの値\ni = '+i+' cklng = '+cklng);
いつもの

}
whileのループはここまで、iがcklngよりでかくなったらループ終わり。

if (ckusr != "") document.forms[0].usr.value = ckusr;
if (ckeml != "") document.forms[0].eml.value = ckeml;
if (ckurl != "") document.forms[0].url.value = ckurl;
さっきcookieから抽出した文字列をフォームに書き込む。
文字列が空だったらなにもしないけど。

}
getck()ここまで。

// -->
</script>
スクリプトはここまで。おつかれさま。

</head>

<body bgcolor="#ffffff" onLoad="getck()">
ページが読み込まれたらcookie情報を呼び出す。

<form>
<input type="text" name="usr" size="40"><br>
<input type="text" name="eml" size="40"><br>
<input type="text" name="url" size="40"><br>
<input type="button" value="記録" onClick="setck()">
記録ボタンを押したときcookie情報を保存する。

  <input type="button" value="呼び出し" onClick="getck()">
呼び出しボタンでcookie情報を呼び出す。

  <input type="reset" value="りせっと">
フォームの中身を初期値に戻す。

</form>

</body>
</html>

 なお、このソースを適当な名前をつけて保存してやれば、完全にローカルでも動作が可能だ。 サーバとやりとりをしなくてもいいことが、JavaScriptの最大のメリットの1つだからだ。

 ちなみに、このスクリプトはIE3以上、ねすけ3以上で動作確認をしている。 JavaScriptが動作するブラウザなら、まあ大丈夫だろう。
 ただし、IE3の場合、ローカルでは動作しないし、呼び出しボタンも動作しないようだ(リロードすれば表示される)注意されたし。

 実験の際は、あちこちにある動作試験用のalert文を動かすのも手だ。 //でコメントされているので、//を消去してやれば動作する。 実際にどういう処理がされているのか、理解しやすくなると思う。 全部動かすとすごく処理がうざったいと思うけど・・・

 さて、解説はこのくらいで終わりである。 理解できたひとも理解できてないひともごくろうさまでした。 このページについての疑問質問意見その他はメールか掲示板でどうぞ。

 理論よりも実践に偏っているので、cookieやJavaScriptについての詳しい仕様などは書いてない。 探せばもっとちゃんとした解説ページもあるので、興味のある方は探してみるのがいいだろう。

 なお、このスクリプトは「はしもと@ASH」の制作したもので、無断使用などはあまりやって欲しくない。
 けれど、ここまでソースを公開したら、これを参考にして(一部をコピー&ペーストで切り貼りしたりて)オリジナルのcookie処理スクリプトを作るのは簡単だと思う。
 もし、このページが何かの参考になったのなら、感謝のメールでも出してくれると幸いである。 なお、お礼はカタチのあるものでも一向に構わない(笑) 送り先はこちらの通り。

 では、また会う日まで。



Copyright (c)1999 ASH multimedia lab.
mail : wmaster@ash.or.jp