トップ «前の日記(2009-05-18) 最新 次の日記(2009-05-23)» 編集

Ussy Diary


2009-05-22

[JavaScript]cookie を操作する関数

jquery.cookie.js が分かりやすかったので、勉強がてら写経しつつ自分なりに依存を取り除いたり、ロジックを変えてみました。

コード

function cookie(name, value, options) {
  function getExpires(value) {
    const baseTime = 60 * 1000;
    var date;
    if (typeof value == "number") {
      date = new Date();
      date.setTime(date.getTime() + (value * baseTime));
    } else if (value.toUTCString) {
      date = value;
    } // else error

    return "; expires=" + value.toUTCString();
  }

  if (typeof value == "undefined") {
    var kv = /(^.+?)=(.+$)/;
    var space = /^\s+|\s+$/;
    var cookies = document.cookie.split(";");
    for (var i = 0; i < cookies.length; i++) {
      var cookie = cookies[i].replace(space, "");
      var match = cookie.match(kv);
      if (name == match[1]) {
        return decodeURIComponent(match[2]);
      }
    }

    return null;
  } else {
    options = options || {};
    if (value === null) {
      options.expires = new Date(0);
    }

    var expires = options.expires ? getExpires(options.expires) : "";
    var path = options.path ? "; path=" + (options.path) : "";
    var domain = options.domain ? "; domain=" + (options.domain) : "";
    var secure = options.secure ? "; secure" : "";

    document.cookie = [name, "=", encodeURIComponent(value), expires, path, domain, secure].join("");
  }
}

実行

cookie("hoge", "foo", {"expires" : 15});
console.log(cookie("hoge"));
foo
cookie("hoge", null);
console.log(cookie("hoge"));

元のスクリプトは期限 (expires) の単位が日単位だったのですが分単位にしています。クライアント側だけで一時的に使うことを想定したためです。

日単位に戻す場合は baseTime をいじります。

const baseTime = 24 * 60 * 60 * 1000;

JavaScript では実引数を指定しない場合、仮引数には undefined が入ります。今回の cookie 関数では削除する場合は第二引数に null を明示的に渡すようになっていて、 undefined と null を効果的に使い分けた例だと言えます。

今更 cookie なのかもしれませんが、 localStorage は有効期限が指定できなかったりと用途が違うのかなと思う節があるので、 cookie はこれからも使われ続けていくでしょう。