2008年10月2日木曜日

SDKのバグ?

Google App Engineネタです。

ブラウザから日本語を含む文字列をPOSTするとき、基本的にはGAEは文字コードをUTF-8として扱ってくれるようです。OK。

でも、POSTをXMLHttpRequest、いわゆるAJAX的な方法でSDKのサーバに投げると、そのデータをDatastoreに格納するところで怒られます。

File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_types.py", line 1092, in PackString
pbvalue.set_stringvalue(unicode(value).encode('utf-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinalnot in range(128)

こんな風に。
でもそもそもが、ブラウザからはUTF-8で送信されているはずで、エンコードの必要などないはずなのに。それに普通にフォームからPOSTした時は怒られないよ?

てーことで色々調べてみたら、フォームからの場合とAJAXからの場合とでHTTP Requestのヘッダがどのように違うかというと、

フォームの場合
'Content-Type': 'application/x-www-form-urlencoded'

AJAXの場合
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'

ふむ。。。Content-Typeにcharsetが指定されてるかそうでないかね。なるほど。
ではこれをフォームに合わせて消してやれば同じ動きをするはず。

・・・で、うまくいかず。
自分が使ってるAJAX系ライブラリのmootoolsというやつで、このライブラリで、charsetだけを消す方法が見つけられず断念(数時間悩みましたけど)。

でもね、ちょっと待ってよ。そもそもcharsetでUTF-8って言ってるんだから、やっぱり変換の必要ないのは同じじゃね?と思う。
思ったところでSDKは聞いてくれないので、試しに「これはUTF-8の文字列ですよ~」と指定してUnicodeに変換する。

↓こんな感じ。
mydb.nihongo = unicode(self.request.get('nihongo'), 'UTF-8')
mydb.put()

OK。通りました。代わりにフォームから通らなくなりました・・・がっくし。
ブチギレ3秒前です。

もう、これって、SDKのバグじゃねーの?ってことで本番サーバに元のままでアップロードする。
・・・通った!!もちろんフォームからでもAJAXからでも。
ブチギレ0.1秒前、ギリギリでセーフです。

ですが、このままだとSDK環境でAJAXの試験ができないことには変わりないんで、困りましたねえ。
DeadlineExceededErrorの件で使ったみたいに、localhostで、かつ、charsetがありなら、って分岐を入れるのか?バカバカしい。ブチギレ。
自分の入れてるPythonとの相性でも悪いのかなあ???

0 件のコメント: