Apache2.4+mod_wsgi+Flask搭建web站點時的中文unicode問題

問題

最近公司購買了阿里雲,預裝的ubuntu1404,上面自帶Apache2.4,計劃安裝Flask,需要通過wsgi適配,於是看到了這篇文章,按照上面的方法搭建成功

進一步豐富業務邏輯時,發現如果瀏覽器提交的表單數據包含中文字符,則Flask會報unicode錯誤

UnicodeEncodeError: 'ascii' codec can't encode characters in position

排查過程

但是我記得Flask默認支持unicode的,通過腳本啓動Flask自身的簡易HTTP server也印證了這一點,所以問題出在apache或mod_wsgi,apache的字符編碼相關配置在/etc/apache2/conf-enabled/charset.conf文件,但打開下面這一行開關後也無效

# AddDefaultCharset UTF-8
再尋找mod_wsgi的字符編碼相關配置文件,沒找到,最接近的是/etc/apache2/mods-enabled/wsgi.conf,但裏面也有任何字符編碼相關的選項

決定深挖WSGI,閱讀其設計方案文檔PEP 333,發現Unicode Issues一節有這麼一段話

HTTP does not directly support Unicode, and neither does this interface. All encoding/decoding must be handled by the application
說明mod_wsgi並不關心編碼,問題排查貌似走到了死衚衕,但是既然mod_wsgi不是問題所在,那apache肯定還有什麼地方有問題

解決方案

經過一番摸索,發現/etc/apache2/envvars文件裏有這麼一段

## The locale used by some modules like mod_dav
export LANG=C
## Uncomment the following line to use the system default locale instead:
#. /etc/default/locale
原來apache默認是ascii編碼,而且很可能影響mod_wsgi!我的ubuntu系統雖然是英文的,但也是en_US.UTF-8編碼,因爲/etc/default/locale文件的內容是

LANG="en_US.UTF-8"
LANGUAGE="en_US:"
將envvars文件上述段落的第二行註釋掉,第四行打開,重啓apache服務,一切正常

心得

apache是以www-data用戶運行的,沒有登陸shell,環境變量不能在rc文件裏設置,所以環境變量是通過讀取envvars文件實現的

mod_wsgi類似於mod_python,是一個將python語言和apache運行環境連接起來的binding,負責的內容包括類型映射,IO映射等,它並不是一個縮水版的python解釋器,所以不關心字符編碼之類的環境變量


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章