编码问题二三事

1、邮件查收组件编码问题

之前开发过程中遇到的,使用一个开源的邮件组件,除了重构的时候误用了多线程,查收邮件并解析某些邮件内容的时候还发现死活都是乱码,然后分析邮件组件源码才知道,这个邮件类库使用UTF-8格式的编码,而我们查收的用户邮件很多都不是UTF-8格式的,而且还有一些多语言格式的邮件,比如俄语和日语,使用UTF-8解析也会碰到乱码问题。

2、截取字符串长度问题

一个很简单的函数,按照输入长度截取字符串,一个汉字算两个字符。
使用这个函数的时候,开发和测试环境都是通过的,但是生产环境发现截取的字符串就是不正确。最后发现这个函数的内部通过System.Text.Encoding.Default.GetByteCount(str)的方式获取单字节字符长度。Encoding.Default静态属性是用于获取操作系统的当前ANSI代码页的编码,开发和测试没有问题而生产有问题毫无疑问是因为操作系统的编码设置不同造成的。后来该函数改造成强制使用GB2312格式的编码,问题没有重现。

3、子系统或异构系统或内外部系统页面跳转编码问题

虽然页面交互的时候,很多系统之间的“切换”没有显式传人编码,但很多浏览器非常智能,可以很轻松识别系统编码或者使用默认编码,自动做出切换,所以有时候你不能很明显发现问题。
但是对于需要编程实现一些业务的时候,不同编码问题不能不考虑进去。比如你使用WebClient进行编程访问页面的时候,如果指定编码不正确,乱码了吧?猜对了。

还有一个简单的例子,比如电商网站接入第三方支付:
在网站接入支付宝支付的时候,发现用户从支付宝支付完成后,跳转回到当前网站总是验证签名不通过。支付宝提供的接入文档只是说,“在通知返回参数列表中,除去sign、sign_type两个参数外,凡是通知返回回来的参数皆是要签名的参数”。然后你按照NameValueCollection解析构造签名,发现返回的签名就是不正确,哪怕自己加上input_charset(这个参数支付宝没有显式返回,但是发起支付请求跳到支付宝的时候,我们使用的是UTF-8编码格式)参与签名也不行。
后来尝试使用下面这种方式通过GB2312解码构造签名排序数组,竟然就通过了。

       foreach (var item in collection.AllKeys)
            {
                if (item == AlipayField.sign)
                {
                    continue;
                }
                if (item == AlipayField.sign_type)
                {
                    continue;
                }
                //支付宝页面同步返回的数据是用GBK编码的
                sortedList.Add(item, HttpUtility.UrlDecode(collection[item], Encoding.GetEncoding("GB2312")));
            }

AlipaySortedList

原来支付宝页面同步返回的数据是用GBK编码的,也就是说你提交请求给支付宝input_charset使用的是UTF-8编码,支付宝页面同步返回的是GBK编码,而且支付宝不会把input_charset显式返回。
对比一下财付通,财付通打破了这个潜规则,页面同步通知的时候直接显式返回input_charset,验签的时候按照财付通传人的编码方式进行解码。

最后就是asp.net编码和解码,推荐使用系统自带HttpUtility这个实用类,最好不要自己搞封装,尤其是很可能无意识地引入了web请求上下文HttpConext.Current的编码方法,说不定那天就会碰到问题。

参考:http://www.cnblogs.com/xiaomia/archive/2010/11/28/1890072.html

时间: 2024-10-11 13:36:47

编码问题二三事的相关文章

老曹眼中的研发管理二三事

这是在gitchat上的第一次分享,中生代联手gitchat在做研发管理的专题活动,作为先锋,抛砖引玉. 关于管理,必然会谈到业界先贤德鲁克先生对管理的定义. 管理就是界定企业的使命,并激励和组织人力资源去实现这个使命.界定使命是企业家的任务,而激励与组织人力资源是领导力的范畴,二者的结合就是管理. 这是对企业管理的阐述,管理是一种实践,其本质不在于'知'而在于'行':其验证不在于逻辑,而在于成果:其唯一权威就是成就. 而我们多数人不是企业家,更多是基层的管理者,面对的一个或几个小型的组织.尤其

程序猿二三事之Java基础--Java SE 5增加的特性--语法篇(一)

程序猿二三事之Java基础–Java SE 5增加的特性–语法篇(一) [ TOC ] 为什么是Java SE 5? 目前已经到了JDK-8u74了,JDK7的主版本已经于2015年4月停止公开更新. 那为什么还要来说Java/JDK5呢? Java SE在1.4(2002)趋于成熟,随着越来越多应用于开发企业应用,许多框架诞生于这个时期或走向成熟. Java SE 5.0的发布(2004)在语法层面增加了很多特性,让开发更高效,代码更整洁. 自动装箱/拆箱.泛型.注解.for循环增强.枚举.可

初识zabbix需了解的二三事

简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案: zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题: 监控平台的组成 数据采集 --> 数据存储 --> 数据展示和分析 --> 报警 常见监控实现方案对比 cacti 优点:利用rrdtool绘图,图形美观: 缺点:报警功能薄弱,不适合大规模监控场景: nagios 优点:报警功能强大: 缺点:只关心正常与否的状态,数

Ubuntu12.04 Version 安装二三事

Ubuntu12.04 Version 安装二三事 安装输入法 因为是全英的系统,所以,中文输入法是一定要装的!!! 介绍一:(和我电脑配置很像,from http://vb2005xu.iteye.com/blog/1748575) Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等.其中Scim和Ibus是输入法框架. 在Ubuntu的中文系统中自带了中文输入法,通过Ctrl+Space可切换中英文输入法.这里我们主要说下Ubuntu英文系统

iOS7下滑动返回与ScrollView共存二三事

[转载请注明出处] = =不是整篇复制就算注明出处了亲... iOS7下滑动返回与ScrollView共存二三事 [前情回顾] 去年的时候,写了这篇帖子iOS7滑动返回.文中提到,对于多页面结构的应用,可以替换interactivePopGestureRecognizer的delegate以统一管理应用中所有页面滑动返回的开关,比如在UINavigationController的派生类中 1 //我是一个NavigationController的派生类 2 - (id)initWithRootV

转手项目二三事

程序员下班之余除了自己充电学习,一般都期待搞个私活做做,这样的方式给自己加班仿佛有了一层光环:自动回血又加经验.我也是今年才开始做一些个人的小案子,都是朋友的朋友介绍的,没什么价.只是这样的过程还是比较好的:慢慢建立自己的客户,提高自己的代码效率,驱动你去研究一些你不熟悉东西,了解别的行业,积累人脉关系.但遇到转手项目这种案子 营养不多,麻烦却不少. 上次一个朋友介绍一个接口的小差,大概一共就是二十几个方法,还没开始做就打了1000元给我.当时心想:写几个方法给这么多,太多了吧.按照他说的 一两

零基础JavaScript编码(二)

任务目的 在上一任务基础上继续JavaScript的体验 学习JavaScript中的if判断语法,for循环语法 学习JavaScript中的数组对象 学习如何读取.处理数据,并动态创建.修改DOM中的内容 任务描述 参考以下示例代码,页面加载后,将提供的空气质量数据数组,按照某种逻辑(比如空气质量大于60)进行过滤筛选,最后将符合条件的数据按照一定的格式要求显示在网页上 <!DOCTYPE html> <html> <head> <meta charset=&

Linux基础回顾(2)——Linux系统分区二三事

问题来自Linux教材,答案自我整理难免会有不足之处.这是我Linux期末的总结 1. 一块硬盘上可以有几种类型的分区?各自可以有多少个?(各个分区能安装操作系统吗?) 硬盘分区有三种类型的分区:主分区,扩展分区,逻辑分区:一个硬盘最多能划分4个主分区,或者3个主分区加上一个扩展分区,扩展分区上可以划分多个逻辑分区(最多20个).能安装操作系统. 2.用户能否在安装过程中创建扩展分区呢? 分区工具在文件系统类型中没有提供扩展(extended)分区类型,即用户不能根据需要不能手工创建扩展分区.安

[C语言]Unicode编码(二)-中文字符刷选

Unicode编码(二)-中文字符刷选 1,UTF-8编码中三字节中文字符的刷选方法如下: int chinese_filter(unsigned char one, unsigned char two ) {     int flag = -1;     if ( one >= 0x4E && one < 0x9F )     {         flag = 1;     }     else if ( one == 0x9F && two <= 0x