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解释器,所以不关心字符编码之类的环境变量


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