当前位置: 主页 > 日志 > WEB UI >

客户端gb2312 ajax urlencode 中文乱码,分析解决

前两天遇到了一个这样的问题:

客户端页面采用GB2312编码,服务端也是采用GB2312编码,在客户端采用ajax提交含中文的数据时(采用encodeURIComponent进行url编码),在服务端接收显示的是乱码。

经分析发现:

服务端采用$_REQUEST(PHP)或者request(ASP)获取参数时,会根据当前程序页指定的字符集对参数进行“相应字符集的url解码”。
因此只有当客户采用的url编码字符集和服务端采用的解码字符集相同时,才能得到正常的数据。

回到本例:

在我的案例中,客户端页面虽然采用的GB2312编码,但是由于对参数采用了encodeURIComponent进行编码,encodeURIComponent对汉字均采用UTF-8字符集进行URL编码,就和服务端采用的GB2312字符集进行URL解码不匹配了,因此得到的是乱码数据。


encodeURIComponent("红冰")结果为:%E7%BA%A2%E5%86%B0,(encodeURIComponent对汉字均采用UTF-8字符集进行URL编码,因此无论页面采用的是GB2312还是UTF-8字符集,都是这个结果)

“红冰”两个中文字符对应的GB2312字符集的URL编码是:%BA%EC%B1%F9

在服务端如果对"%E7%BA%A2%E5%86%B0"进行GB2312字符集的URL解码,得到的结果就是“绾㈠啺”,也就是我所说的“乱码”。


经过苦苦寻找,最终终于找到了一段gb2312字符集URL编码代码,代码如下:

// 我是从http://www.ialvin.cn/blog/article.asp?id=172这个地址拷过来的,感谢原作者!
// gb2312 urlencode

function encodeURL(s) {
    var img = document.createElement("img");
    function escapeDBC(s) {
        if (!s) return ""
        if (window.ActiveXObject) return s.replace(/[dD]/g, function($0) {
            window.vbsval = "";
            execScript('window.vbsval=Hex(Asc("' + $0 + '"))', "vbscript")
            return "%" + window.vbsval.slice(0,2) + "%" + window.vbsval.slice(-2);
        });
        img.src = "nothing.asp?key=" + s;
        return img.src.split("key=").pop();
    }
    return s.replace(/([^x00-xff]+)|([x00-xff]+)/g, function($0, $1, $2) {
        return escapeDBC($1) + encodeURIComponent($2||'');
    });
}



下面分别是在GB2312页面和UTF-8页面所做的测试截图:




PS:

文中我所说的服务端"GBK URL解码" 和 "UTF8 URL解码"其实是不存在的,服务端在URL解码的时候根本不会考虑要解码的字节流采用的是什么编码方式,只是进行%HH到0xHH的转换。至于怎么显示,还是浏览器说了算。同样的字节序列,浏览器采用不同的编码方式查看,显示出的字符是不一样的。

 

例如,可以做这样一个实验:

新建一个记事本文件,重命名为test.html,然后利用UtraEdit 16进制编辑模式,写入E7  BA  A2,保存后,用IE打开。

先用GBK编码查看,是“绾”。

再换用UTF8编码查看,是“红”。

 

上面我之所以说“服务端GBK URL解码 和 UTF8 URL解码”主要是为了便于理解。

 

 


总结:

(1)Jquery的序列化函数对中文采用的也是UTF-8字符集的URL编码。
(2)如果客户端和服务端均采用UTF-8字符集,也就不存在这个问题了。推荐用encodeURIComponent,而不用escape,原因见我这篇文章http://www.redicecn.cn/view-220.html。
(3)GB2312页面的表单直接提交给GB2312编码的服务端程序怎么不会出现乱码呢?答:  默认表单提交采用的URL编码字符集是浏览器根据当前页面的编码方式决定的,所以采用的是GB2312字符集的URL编码,所以不存在问题了。

附:测试文件

File: Click to Download

 

[日志信息]

该日志于 2010-06-21 12:18 由 redice 发表在 redice's Blog ,你除了可以发表评论外,还可以转载 “客户端gb2312 ajax urlencode 中文乱码,分析解决” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)
   
验证(必填):   点击我更换验证码

redice's Blog  is powered by DedeCms |  Theme by Monkeii.Lee |  网站地图 |  本服务器由西安鲲之鹏网络信息技术有限公司友情提供

返回顶部