プログラマブログ

by wacul

menu
  • プログラマ
  • cookieに効率的にデータを格納するzcookiesを作りました

2014.09.16cookieに効率的にデータを格納するzcookiesを作りました

cookieに効率的にデータを格納するzcookiesを作ったので使い方と仕組みについて紹介しようとおもいます。

モチベーション

あるとき、sessionStorageを使って一時的にデータを保存しておくようなウェブページを作っていました。 現状ではIE8以上ならsessionStorageを使うことができるので特に問題ないだろうと高をくくっていたのですが、実はsafariのプライベートブラウズモードではsessionStorage含め、Web Storage全般が使えないということがわかりました。

次点の解決策としてcookieを使うことを検討したのですが、いわゆる4kB制限があり作っているウェブページもその制限に引っかかる恐れがありました(特に日本語とか保存しようとすると数倍の容量を食いますからね)。

そこで、オブジェクトを圧縮してcookieに保存できるような仕組みを作ることにしました。

使い方

zcookiesの使い方は簡単です。以下の例を見て下さい。

1
2
zcookies.set('foo', {a: 1, b: 'こんにちは世界'}, options);
zcookies.get('foo');

zcookiesは単純なキーバリューストアとして機能します。 zcookies.setoptions という引数がありますが、これはcookieを保存するときのオプションでScottHamper/Cookiesから流用したのでそちらを参照して下さい。

仕組み

実際に処理してる部分が10行ちょっとなのでここに載せてみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
global.zcookies = {
  get: function(k) {
    return msgpack.unpack(pako.inflateRaw(atob(Cookies.get(k))));
  },
  set: function(k, v, options) {
    var x = Cookies.get(k);
    var cookieSizeBeforeSave = document.cookie.length;
    var y = btoa(String.fromCharCode.apply(null, pako.deflateRaw(msgpack.pack(v), {level: 9})));
    Cookies.set(k, y, options);
    if (x !== y && cookieSizeBeforeSave === document.cookie.length) {
      throw new Error('zcookies: QUOTA Error!');
    }
  }
};

ものすごく巨人の肩に乗った感じのコードですが、保存するときに

  • JavaScriptのオブジェクトをmessagepack形式のバイト列に変換
  • deflateで圧縮
  • 文字列に変換
  • base64形式に変換

というような処理をしているだけです。簡単ですね。

圧縮率

zcookiesとescapeを使った場合で比較してみました。

テキスト zcookies escape
こころ(1章, 1509字) 2748 9039
Alice’s Adventures in Wonderland(上から4017字) 2616 5797

比較する対象として妥当か微妙なところですが、割りと長い文字列でもcookieの範囲に収まることが検証出来ました。

まとめ

すごくニッチですが、どうしてもcookieにデータを保存したいときに使えるzcookiesを作りました。 プライベートブラウズモードで困った人は是非使ってみてください。 また、最近普通にブラウザ上でmessagepackやzlib系のライブラリを使える環境が整った感があるのでこの例に限らず選択肢の一つとして頭の片隅に置いておきたいところです。

参考

この記事を書いた人kato

加藤です。JavaScriptに興味があります。

waculでは、プログラマを募集しています。

現在はプロダクトとして、課題発見から改善提案まで自動で行うWeb改善プラットフォーム「AIアナリスト」を開発中です。

waculの採用情報へ

ページトップへ