xrea-banner xreaad

Hello, cookie!

namespace kilrey; / JavaScript / 応用 / Hello, cookie!

前のページ(Hello, GM_world!)へ / 次のページ(Hello, hash!)へ

本段では cookie について扱います。 cookie とは http の接続時に遣り取りされるデータの一種で クライアント側に保存されるものです。

インターネットのウェブページの閲覧は、サーバー(ホスト、情報提供側)がウェブブラウザ(クライアント、情報請求側)の要求に従って情報をブラウザ側に送ることで成り立っている。 最初にブラウザがサーバーに対して要求を送るとき、閲覧したいページのURLの他に、ブラウザの種類などの情報を送信する。 それに従って、ページの表示情報やその他の情報をサーバーが送信するが、このときにブラウザ側に対し、ブラウザが保管しておくべき情報を挿入することがある。これがcookieである。 クッキーを受け取ったブラウザでは、ブラウザがcookieに対応していれば、cookie情報を、ブラウザのあるコンピューター(クライアント)に、サーバーのアドレスとともに保存する。 次にブラウザがそのサーバーに対して要求を送るとき、閲覧したいページのURLの他に、ブラウザの種類などの情報にcookieの内容を加えて送信する。これによって、サーバーは、最初の閲覧時に送信したcookieを受け取るのである。

サンプルとなるスクリプトは Save Draftです。 これをインストールしてください。

input や textarea など、 form の入力部品の内容を自動でセーブするスクリプトです。
あらゆるWebページで name属性を指定されたinputやtextarea要素に対して ブラウザのクッキーにその内容を自動的に保存します。 一旦ページを閉じてから再びそのページを開いた際に 前回の入力内容が再現されます。 またそのページからformを送信した場合、 今までセーブしていた内容が消去されます。

という説明を付けてあります。 例えば、下に form を一つ用意しました。 この form の input には name 属性を指定してあるので Save Draft によりデータが保存できます。 何か文字を入れてから別のページへ移動し また戻ってくるという操作をしてみてください。 ちゃんとデータが復帰しているはずです。

それではスクリプト自体の説明を始めましょう。 まずは cookie の読み込みです。

    var patGet = /([^=]+)=([^=]+)/;
    function get(key){
        var cookies = document.cookie.split('; ');
        for (var i = 0; i < cookies.length; i++) {
            var match = cookies[i].match(patGet);
            if(match && key == decodeURIComponent(match[1])){
                return decodeURIComponent(match[2]);
            }
        }
        return '';
    };
    

document.cookie を参照することで読み込みが出来ます。 ただし、読み込んだ cookie は ; で区切られた一塊の文字列となっています。なので最初に

        var cookies = document.cookie.split('; ');
    

というように ; で切り分けます。 各片は「名 = 値」式のデータとなっているので、 正規表現により名と値を取り出します。 そして与えられた key と名が一致したものを返すというわけです。
次は cookie の書き込みです。

    function set(key,val){
        var date = new Date();
        date.setTime(date.getTime() + (7*24*60*60*1000));
        var expires = 'expires=' + date.toGMTString();
        document.cookie = encodeURIComponent(key) + '=' +
            encodeURIComponent(val) + "; " +
            expires + '; path=/';
    };
    

最初には有効期限を設定します。

        var date = new Date();
        date.setTime(date.getTime() + (7*24*60*60*1000));
        var expires = 'expires=' + date.toGMTString();
    

現在から見て一週間後まで cookie は有効になっています。 そして cookie を書き込みます。

        document.cookie = encodeURIComponent(key) + '=' +
            encodeURIComponent(val) + "; " +
            expires + '; path=/';
    

document.cookie に値を与えることで書き込みが行われます。 通常の JavaScript における代入と見た目は同じですが、 振舞いが異なるので注意してください。
次は cookie の消去です。

    function clear(key){
        document.cookie = key + '=;'
            +'expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/';
    };
    

ここでは単に cookie の有効期限を過去に設定しています。 こうしておくと次にアクセスした際にデータが消去されます。
以上で基本関数は終わりです。 このような関数は一度書けば今後も使いまわしが利きます。 便利に使いましょう。

それでは本文を読みましょう。 まずは全部の値を記録する関数 save() です。

    function save(){
        for(var i = 0; i < document.forms.length; i++){
            for(var j = 0; j < document.forms[i].length; j++){
                var name = document.forms[i][j].name;
                if(name && document.forms[i][j].value.length > 0 &&
                   (document.forms[i][j].type == 'text' ||
                    document.forms[i][j].nodeName.
                    toLowerCase() == 'textarea')){
                    set(name,document.forms[i][j].value);
                }
            }
        }
    };
    

save() 関数では document 中の全部の form に対して 各要素が条件を満たす場合に値を cookie に記録しています。 条件は

  • 要素に名前がある
  • 値が入力されている
  • text 型か textarea 型である

というものです。

    setInterval(save, 1000);
    

はその save() 関数を 1000 ミリ秒ごとに実行するという意味です。
次は全部の値を消去する関数 reset() です。

    function reset(){
        for(var i = 0; i < document.forms.length; i++){
            for(var j = 0; j < document.forms[i].length; j++){
                var name = document.forms[i][j].name;
                if(name && document.forms[i][j].value.length > 0 &&
                   (document.forms[i][j].type == 'text' ||
                    document.forms[i][j].nodeName.
                    toLowerCase() == 'textarea')){
                    clear(name);
                }
            }
        }
    }
    

続いて reset() 関数です。 save() 関数と同様の条件で clear() を実行します。

    window.addEventListener("submit", reset, false);
    

は submit イベント時に reset() を実行するという意味です。
最後は全部の値を書き込む命令です。

      for(var i = 0; i < document.forms.length; i++){
        for(var j = 0; j < document.forms[i].length; j++){
            var name = document.forms[i][j].name;
            var val = get(name);
            if(name && val &&
               (document.forms[i][j].type == 'text' ||
                document.forms[i][j].nodeName.
                toLowerCase() == 'textarea') &&
               document.forms[i][j].value == ""){
                document.forms[i][j].value = val;
            }
        }
    }
    

save() 関数と同様の条件で、以前に記録した値を代入しています。 スクリプト読み込み時にこの部分の命令が実行されるので、 読み込み時に cookie から値を復帰するという動作になります。

前のページ(Hello, GM_world!)へ / 次のページ(Hello, hash!)へ