Ex DOM Storageがあるからと安心してWeb Storage使いまくりなWebアプリを作ると落とし穴に嵌る件
Ex DOM Storageを使っていて嵌った。
頭がおかしくなりそうだったがなんとかとりあえずの解決はできたので、
その件について話をする。
Ex DOM Storage
IE6,7でWeb Storageを使えるようにするライブラリ。
userData behaviorとhtcを使って実装されている。
落とし穴
こちらのリリース告知エントリで言及されているものの他にも、
userData behaviorにはWeb Storageの機能を再現できない制限がある事が分かった。
Ex DOM Storage をリリースしました - Yet Another Hackadelic
別ディレクトリとデータを共有出来ない
userData behaviorは同じディレクトリ内でないとデータを共有出来ない。
a UserData store is available only in the same directory and with the same protocol used to persist the store.
http://msdn.microsoft.com/en-us/library/ms531424(VS.85).aspx
Web Storageの機能デモ用に1個HTMLを用意しておくというものなら何も問題ない。
しかし、例えばRailsのscaffoldで作られるindexとnewはpathが
"/hoge"と"/hoge/new"というふうになっているが、これらの間でデータが共有出来ない。
("/hoge/と"/hoge/new"なら共有出来る")
ドメイン毎のデータ容量上限がある
ごく当たり前の事に思えるだろうが、
別ディレクトリとデータを共有出来ない事と合わせると
恐ろしい事が起こる。
例えば"/hoge/:id/edit"といった動的に作られる"ディレクトリが異なる"URLのページ上で
localStorageを使い、時々消し忘れる・消し損ねる等して少しずつ容量を使っていくとする。
使った容量の合計がドメイン毎のデータ容量上限に達してしまえば、
全く容量を使っていないまっさらなディレクトリ上であっても、
localStorageにデータを入れる事ができなくなってしまう。
動的に作られる無数のディレクトリの中に容量を食っているのが散らばっていたら、
回収するのは非常に困難である。
おまけに、残り容量以上のデータを入れようとするとcatchできないエラーになるし、
ドメイン毎の残り容量は参照不能で、やっかいなことこの上ない。
別ディレクトリとデータを共有出来ない件の対策
今のところ極力同じディレクトリ内で完結させるようにするしかない。
簡単なものだと"/hoge"と"/hoge/new"ではなく"/hoge/と"/hoge/new"にするとか。
"/hoge"でlocalStorageを消して、"/hoge/:id/edit"に遷移する場合等は、
"/hoge"でcookieでフラグを立てて、遷移先の"/hoge/:id/edit"でlocalStorageを消す等の対応をした。
どうしてもディレクトリをまたいで何かやりたい場合は、
Ex DOM Storageを読み込んだ後localStorageに何かをするJavaScriptを実行するHTMLを
返すだけのactionを実装して、それをiframeで読み込む事で、
別ディレクトリ上のlocalStorageを操作する等という事もやった。
これらの対応は全てアドホックなものだが、最後の例を発展させれば、
ディレクトリをまたいでデータ共有出来ない件は完全に解決するのではないかと思う。
特定ディレクトリ上にEx DOM Storageを読み込んで使用可能にするだけのhtmlを配置し、
実際に使うページではそのhtmlをiframeで読み込みそこ経由でデータを共有する。
という事になると思う。
expiresでドメイン毎のデータ容量溢れを防ぐ
まずこの件に関してsessionStorageの使用は解決策にならない。
どうやらcookieでフラグを立てて初期化時にフラグが立ってなかったらsessionStorageを空にする
といった感じの実装なので、二度と読み込まれないディレクトリにゴミが溜まっていたら回収されない。
そこで、exdomstorage.htcの中のexdomstorage_impl.jsの部分に手を入れ、
element.save()の前にexpiresを設定するようにした。
expiresも相当癖が強い。具体的にはこんな感じ。
- 期限切れになるとuserData behaviorにアクセス出来なくなる→localStorageの読み書きができなくなる
- 期限切れになった後IEを再起動するとアクセス出来るようになっている
- IE起動中に期限切れになっても容量は解放されない
基本的にユーザの該当ディレクトリ上での操作中に期限切れになると困るので、
長めに設定するのがよいと思う。
消すのに失敗したまま長時間放置されたものが自動で回収されるような感じ。
感想とか
もうすこしノウハウを溜めないと怖い。
外で公開するWebアプリで使うのはちょっとまだ厳しいのではないかな、という気がする。