Google App Engine の webapp の仕様がちょっと気に入らなかったので、URLのディスパッチとコントローラー部分を自作していますが、Cookie をハンドルするメソッド回りで文字化けが発生して困ってました。
Request/Response オブジェクトには、WebOb を使いました。
で、クッキーに保存する値は、urllib.quote で url エンコードします。
1 2 |
value = urllib.quote(value) response.set_cookie(key, value) |
で、読み出す時は、urllib.unquote でデコードします。
1 2 |
value = request.cookies.get(key) value = urllib.unquote(value) |
ところがこれだと日本語文字が文字化けするんですね…。
全てを utf-8 に統一しているので問題は無いつもりなんですが、色々やっても文字化けです。
散々悩んでようやく気付いたのが、request.cookies.get で取得した値が、unicode オブジェクトになっているということ!そして、urllib.unquote が unicode オブジェクトの入力を、正しく処理できないらしいということでした。
urllib.unquote の挙動については、itasukeさんのこちらの記事で教えて頂きました。例外が出ないので、なかなか気付けなかったみたいです(…言い訳でーす)。itasukeさんの記事によると、UTF-8 のまま unicode にされてしまうとか…。どうりで、文字化けしてしまうわけですね…。
で、WebOb の Request からの取得値を value.encode(‘raw_unicode_escape’) してstr にしてみたところ、文字化けは解消されました。
これを受けて、クッキーをハンドルしているクラスに、次の作業メソッドを追加。
1 2 3 4 5 |
def __decode(self, value): if isinstance(value, unicode): value = value.encode('raw_unicode_escape') value = urllib.unquote(value) return value |
もちろん、エンコード側も似たように作成。
というわけで、解決。
こんなことに3日も悩んだわけですが、
おかげさまで Python の文字コード周りの見通しが良くなりました♪*1