2007年04月30日

Python Django WAP中文乱码

作者 非鱼

虽然不太想在这里写技术性的文章,不过为了凑数,同时增加点关键字,还是写点吧。

理财易在运营的过程中,会员提出是否可以开发WAP记账的功能。虽然别的记账网站都已经有了这个功能,但是我一直对这个不太感冒,因为我自己都没有用过WAP功能。所以,我觉得别人也不太可能用这种东西。不过既然有人提出来了,就研究一下吧。

开发过程还是比较顺利的,Django的模板系统可以套用在任何框架上,所以只用了一个晚上,一个简易的WAP版记账系统就出炉了。登录/记账/查看最新记账,都有了。结果,很快发现一个比较严重的问题,发送数据不支持中文。

跑到网上搜索了一大堆资料,Python方面还没有先例,还好有另一位高手的PHP代码和ASP代码。但是找了半天,还是没有找到Python中实现同样功能的函数。不过功夫不负有心人,经过了N多级的关键字搜索,终于发现了一点线索,总算是把问题解决了。

方案如下:在WML代码里面,需要使用POST的方式发送数据,因此不能用a,需要用anchor或者按钮,加上postfield的方式,而postfield的值也不能直接使用$(username)这样,需要在客户端先编码。比如,如果你的text控件的name是username,那么这个postfield的value应该等于$(username:e),这样会将username里面的中文强制编码成URL格式,也就是%6D%6E这种格式,然后POST这种数据的时候,就不存在任何编码问题了,因为都是AscII码。后台的Python收到的也就直接是这种编码的一个字符串,要变成你要的中文,需要解码。

虽然有一个问题我一直没有想通,但是却的确不需要想通就通过测试了,那就是无论页面里编码如何设置,这个URL编码都是GB2312格式。因此,在后台收到这个值以后,需要先用urllib.unquote()来解码。就是这个函数,让我查了三天。我一直以为要找urldecode之类的东西。这个函数解码出来以后的结果是GB2312的字符串。因为我的数据库是UTF8的,所有的Python文件也是UTF8的,因此还需要将这个字符串变成UTF8的来用。方法是先将它decode(‘gb2312’),再将结果encode(‘utf-8’)。最后得到的这个字符串,就是用户实际输入的内容了。没有乱码问题,也没有奇偶字数丢失字符的问题了。

这个解决方案目前只在Palm T650的Blazer浏览器上测试过,其它的机器都还没有测试。

WAP版正式推出以后,似乎没有一个用户来用过,也没有人对此留下自己的意见和评论。所以这里又回到了前面的用户真实需求的问题。你想要的,未必是用户想要的,但是即使是用户提出来的,也未必就是他真正想要的,或者他可能想的很美好,但是却未必会真的去用。