今天實現了從Google App Engine的Datastore資料庫提取中文資料然後以JSON格式作為XNJS的Ajax物件發出請求的傳回值傳回校內網,並且正常顯示在網頁裡(汗...... 組織這個句子成分還真花了好一會)。
XNJS的Ajax物件在JSON模式下接受的資料是一個內容為JSON格式的純字串。 雖然校內網的網頁是utf-8編碼的,但Google App Engine的Datastore預設的儲存編碼是unicode。
開始的時候我以為從Datastore裡query出來的中文資料需要用data.encode('utf8')處理,然後用str()轉換成字串作為Ajax的請求結果返回,但是這樣返回的資料在校內網頁上顯示出來是亂碼。 這讓我百思不得其解:如果我不用encode('utf8')的話,str()在轉換unicode的時候則會在每個字串前面加上一個"u"字元,這樣就會破壞JSON格式! 難道要手工去掉這些討厭的u嗎? 這太不符合Python的哲學了! (太麻煩了! )
絕望之下我只好四處求救,然後意識到真正在使用XNJS這個Ajax物件的人實在是少啊...... 後臺架在Google App Engine上面的就更是稀缺(我懷疑除了我之外還有誰也抽風到這程度)。 不過最後我終於瞭解到了了問題的關鍵(謝謝houyongr牛):我在轉換Python內置資料結構dict到JSON格式字串的時候用的方法不對。 原來str()是解決不了問題的,提前轉換utf8也是不對的——正確的辦法應該是用小兒強大的simplejson模組!
Google App Engine環境的simplejson並不在Python標準模組的路徑下,而是在 django.utils裡面。 而實現本文開頭所說的目的其實很簡單:從Datastore裡面查詢出需要的字串,然後用它構造成任何需要的Python資料結構(當然出於JSON的需要,最外層必須是dict);然後通過simplejson.dumps() 將其轉換成一個目標字串然後返回給校內就可以了。 中間的一切編碼過程交給Python/Django/GAE/XNJS等等處理就好了,我們自己不用擔心unicode和utf8之間的轉換。
其實說到這裡我還是不明白,unicode究竟是什麼時候變成utf8的?