注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

云淡风轻

云淡风轻近午天,傍花随柳过前川。

 
 
 

日志

 
 

关于异步传输里的乱码问题  

2008-08-16 17:00:24|  分类: 格物致知 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
之前对ajax的一点总结,发到组内的邮件列表了,现在贴出来。有一些语言可能不正确,因为我自己的理解也还不够透彻,先放在这里,反正blog里的文章是可以以后再修改的。

中文世界里,还是gb的编码使用得比较多。在unicode一统江湖之前,异步通讯里的编码问题总还是一个问题。
这里讨论的就是,当服务器的数据使用gb编码存储时,异步通讯的一些问题和解决办法。

普通ajax:
    使用XMLHttpRequest对象,如果返回的http报文头里没有在Content-Type里指定charset,
    则默认当作utf-8编码,或者是unicode字面量表示
    (如: '\去'表示汉字"去", 53BB是"去"在unicode中的code point的十六进制表示)。
     如果数据是gb编码,就会出现乱码。

    有三个解决的办法:
    第一个是不推荐的,在客户端实现,比较复杂。
        首先是对IE,用一个vb函数(函数附后),可以把gb编码转成utf-8的(写这个函数的人真是牛人!)
        其实是对于FireFox,XMLHttpRequest对象有一个overrideMimeType方法,
        可以使用这个方法,强行覆盖返回数据的content-type头信息。
        就是在调用send()之前,先调用
            xhr.overrideMimeType("text/html;charset=gb2312");
        就可以了。
       没有测试,不知其他浏览器是否支持overrideMimeType。

    第二个办法是服务器把返回的数据转换成utf-8编码。
        网上可以找到一个python函数,把一个python对象里的字符串转换成 unicode。
        作者是limodou,http://blog.donews.com/limodou/archive/2006/09/14/1037959.aspx
        然后再用simplejson转成json。

    第三个办法是在http报文头里加入Content-Type,如:
        Content-Type: text/html; charset=gb2312
    或
        Content-Type: text/plain; charset=gb2312
    推荐这个办法。
 
    Apache可以给每个请求的返回数据里加入默认的charset,方法是:
        AddDefaultCharset gb18030
    但不推荐这个做法,除非服务器上完全没有utf-8编码的文件,
    完全不会输出utf-8编码的内容

jsonp:
    jsonp通过在文档树里动态增加一个script标签的办法来实现异步请求。
    而script标签有一个charset的属性,可以指定src所引用的文档的编码。
    例如:
        var script = document.createElement('script');
        script.charset = 'gb2312'; // 或者'utf-8'
        script.src = 'http://some-jsonp-calls';
        document.body.appendChild(script);


客户端传回服务器的数据,如果不做处理的话,一般根据页面文件的编码而不同。
如果页面是gb的,则数据是gb的;如果页面是utf-8,则是utf-8。
但不推荐这样做。
推荐使用encodeURIComponent函数对数据进行编码,编码的结果是utf-8。
不推荐使用escape函数,这个函数原来是设计给服务器端javascript使用的,现在已经是deprecated的了。


附:
  2 window.utf8 = function(data) {
  3     //only works for microsoft internet explorer
  4     var glbEncode = [], t, i, j, len;
  5     utf8_data = data;
  6     execScript("utf8_data = MidB(utf8_data, 1)+' '", "vbscript");
  7     t = escape(utf8_data).replace(/%u/g,"")
  8             .replace(/(.{2})(.{2})/g,"%$2%$1")
  9             .replace(/%([A-Z].)%(.{2})/g,"@$1$2");
 10     t = t.split("@");
 11     i = 0;
 12     len = t.length;
 13     while(++i < len){
 14         j = t[i].substring(0,4);
 15         if(!glbEncode[j]) {
 16             utf8_char = eval("0x"+j);
 17             execScript("utf8_char=Chr(utf8_char)","vbscript");
 18             glbEncode[j] = escape(utf8_char).substring(1,6);
 19
 20         }
 21         t[i] = glbEncode[j] + t[i].substring(4);
 22
 23     }
 24     utf8_data = utf8_char = null;
 25     return unescape(t.join("%")).slice(0,-1);
 26 };
  评论这张
 
阅读(271)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017