IE で日本語を含むパスにあるローカル HTML からクッキーを保存すると保存されたクッキーを取得できない件
なんのこっちゃという感じだろうから順に説明する。
- 対象ブラウザは IE11。クッキーはデフォルトなら「インターネットオプション」から辿れる、
C:\Users\(ユーザ名)\AppData\Local\Microsoft\Windows\INetCache\
に保存される。 - ローカルにある HTML ファイルから JavaScript でクッキーを登録したい。
- 当該 HTML ファイルまでのパスに日本語がなければ、問題なくクッキーを登録でき、ブラウザを閉じて再度開いてからも、そのクッキーを取得できる。
- 例えば、
C:\Hoge\Fuga\Test.html
といったフルパスになる HTML ファイルからなら、クッキーの読み書きが正しくできる。
- 例えば、
- しかし、HTML ファイルまでのパスに日本語が交じると、クッキーは保存でき、ブラウザを閉じるまでは有効なのだが、ブラウザを開き直した時にそのクッキーが取得できない。
- 例えば、
C:\クッキー\取得\Test.html
といったフルパスだと、クッキーの読み込みに失敗する。
- 例えば、
原因を探ったところ、C:\Users\(ユーザ名)\AppData\Local\Microsoft\Windows\INetCache\
に保存されているクッキーファイルで、パスの日本語が文字化けしていた。「名前」列と「インターネットアドレス」の列に現れるパスの日本語部分が、文字化けしていたのだ。
なかなか良い方法が見つからなかったのだが、暫定的に、一旦、とりあえず、解決する方法を見つけたので紹介する。
クッキーの path 属性にドライブレターだけを指定する
解決方法は、path 属性に日本語を含まないように、その HTML ファイルがあるドライブのドライブレターだけを指定する。
/* この JavaScript を実行する HTML は C:\クッキー\取得\Test.html (C ドライブ内) であると仮定する */
// 登録する値。エスケープ処理などは適宜行っておく
var value = $("#msg").val();
// msg という名前で value を登録する。
// 「path=/C:/」 とし、パスに日本語のフォルダ名を含めない。
// expires 属性は有効期限。2030年1月まで有効とする (第2引数の 0 は1月を表す)。
document.cookie = "msg=" + value + "; path=/C:/; expires=" + new Date(2030, 0).toUTCString();
こうすると、保存されるクッキーファイルの「名前」が file:///C:/
になり、「インターネットアドレス」列も Cookie:(ユーザ名)@~~local~~/C:/
となり、文字化けする箇所がなくなるので、ブラウザを一度閉じたあとでもクッキーを読み取ることができた。
当然、副作用がある。C ドライブ直下の HTML ファイル全てで有効なクッキー情報になってしまうので、同じドライブの他の HTML ファイルからも、同じクッキー情報を読み取ることができてしまう。名前が重複すれば意図しない上書きも発生しうるので、あまりそのドライブ内でクッキーを多用するローカル HTML ファイルがない場合にのみ、なんとか有効な方法といえる。
試したけどうまくいかなかった方法
色々な文献を漁ったが、IE で、ローカルファイルからクッキーを発行して、かつ日本語を含むパスで文字化けが発生して…、といったニッチな環境でのトラブルシューティングは見つからず。
- HTML 文書のエンコードは Shift-JIS や UTF-8 など関係なし。
- ただ、登録されるクッキーの「インターネットアドレス」列で文字化けしている様子は、UTF-8 エンコードされた日本語を Shift-JIS 解釈したときの文字列に似ている (UTF-8 のページのエンコードを Shift-JIS に変えた時に似ている)。だが、HTML 文書の、ファイル自体のエンコード、および meta 要素の charset 指定は影響しなかった。
- domain 属性を指定してみる … どういう値でも関係なし。
- path 属性に、Punycode 変換したパスを指定してみる … 日本語は Punycode 変換されたが、異なるアドレスとみなされて読み取れなかった。
他に良い解決策をご存じの方がいましたら教えてください。