×

Loading...
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。

编码问题

本文发表在 rolia.net 枫下论坛编码问题很复杂,从最基础说起:
>wget -d wenxuecity.com (-d表示debug,显示详细信息)

HTTP request sent, awaiting response... HTTP/1.1 200 OK
Date: Wed, 07 Dec 2005 20:54:35 GMT
Server: Apache/1.3.33 (Unix) PHP/4.3.11
X-Powered-By: PHP/4.3.11
Connection: close
Content-Type: text/html; charset=gb2312

最后一行就表示,服务器通知浏览器,这里发出的编码将是GB2312。
但是在发出来的文档中,很有可能存在<META HTTP-EQUIV=Content-Type CONTENT='text/html; charset=GBK'>的字样。

浏览器本身也有两个编码:1,系统本身的语言,是中文还是英文系统?2,浏览器的缺省配置。比如说Internet Option中的Language Options。有些电脑访问cnn.com的时候总出现中文的句号、逗号,还吃了下一个字母,就是因为它企图用中文来显示。

所以,现在有4个编码:服务器偷偷发出的文件头中的编码;HTML头的编码;客户端系统的编码和客户端浏览器的编码。如果这几个编码不一致,浏览器会用哪个来显示,取决于各个浏览器。所以Firefox/Opera/IE表现不一样。

在你的问题中,还多了一个编码:浏览器用XMLHTTPRequest从服务器读过来的时候,按你说的是UTF-8编码。

下面一段是从GB2312转成UTF-8的js程序:

// Encode to UTF8. CC ben@fadshop.net
function EncodeUtf8(s1)
{
var s = escape(s1);
var sa = s.split("%");
var retV ="";
if(sa[0] != "")
{
retV = sa[0];
}
for(var i = 1; i < sa.length; i ++)
{
if(sa[i].substring(0,1) == "u")
{
retV += Hex2Utf8(Str2Hex(sa[i].substring(1,5)));

}
else retV += "%" + sa[i];
}

return retV;
}
function Str2Hex(s)
{
var c = "";
var n;
var ss = "0123456789ABCDEF";
var digS = "";
for(var i = 0; i < s.length; i ++)
{
c = s.charAt(i);
n = ss.indexOf(c);
digS += Dec2Dig(eval(n));

}
//return value;
return digS;
}
function Dec2Dig(n1)
{
var s = "";
var n2 = 0;
for(var i = 0; i < 4; i++)
{
n2 = Math.pow(2,3 - i);
if(n1 >= n2)
{
s += '1';
n1 = n1 - n2;
}
else
s += '0';

}
return s;

}
function Dig2Dec(s)
{
var retV = 0;
if(s.length == 4)
{
for(var i = 0; i < 4; i ++)
{
retV += eval(s.charAt(i)) * Math.pow(2, 3 - i);
}
return retV;
}
return -1;
}
function Hex2Utf8(s)
{
var retS = "";
var tempS = "";
var ss = "";
if(s.length == 16)
{
tempS = "1110" + s.substring(0, 4);
tempS += "10" + s.substring(4, 10);
tempS += "10" + s.substring(10,16);
var sss = "0123456789ABCDEF";
for(var i = 0; i < 3; i ++)
{
retS += "%";
ss = tempS.substring(i * 8, (eval(i)+1)*8);



retS += sss.charAt(Dig2Dec(ss.substring(0,4)));
retS += sss.charAt(Dig2Dec(ss.substring(4,8)));
}
return retS;
}
return "";
}

我印象中只有二三十行,现在才发现EncodeUtf8函数很短,但是还接着好几个辅助函数.你看能不能把它decode出来。更多精彩文章及讨论,请光临枫下论坛 rolia.net
Sign in and Reply
Modify
Report

Replies, comments and Discussions:

  • 工作学习 / 专业技术讨论 / JavaScript使用XMLHttpRequest,返回中文乱码。对于Mozilla,可以使用overrideMimeType强行设置字符集。对于IE的Microsoft.XMLHTTP,该怎么办?我这是一个纯静态网站,也就是必须在client端想办法。有高手知道么?谢谢。
    • gb2312? utf8?gbk?
      • gb2312。不过如果能解决的话,应该跟具体哪个charset没关系吧。
        • 没人知道?自己顶一下。
        • 你可以在静态网页html的meta里设为gb2312,那么javascript得到的字符集就和它一致了
          我觉得,不存在“中文乱码”的说法。你所看到的乱码只是因为你用错误的charset来显示而已。只要你在服务器端和客户端都用相同的charset,还会有什么问题呢?

          ajax里头,又不允许跨站访问,所以服务器端和静态页面都是同一个网站的,那就更不会有charset问题了。
          • 如果有那么简单楼下就不会说“AJAX还不是成熟的技术”了。
            您老兄好像没玩过这个吧。
            • 要不你把链接PM过来看看?
              • 没link。:( 不过文件很简单。不知道这里贴不贴得上。
                本文发表在 rolia.net 枫下论坛<script language="JavaScript">
                var xmlhttp;

                function loadXMLDoc(url) {
                if (url=="") return;
                xmlhttpChange =getArticle;

                // code for Mozilla, etc.
                if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = xmlhttpChange;
                xmlhttp.overrideMimeType("text/html; charset=gb2312");
                xmlhttp.open("GET",url,true);
                xmlhttp.send(null)
                }
                // code for IE
                else if (window.ActiveXObject) {
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
                if (xmlhttp) {
                xmlhttp.onreadystatechange = xmlhttpChange;
                xmlhttp.open("GET",url,true);
                xmlhttp.setRequestHeader("Content-Type", "text/html; charset=gb2312");
                xmlhttp.send()
                }
                }
                }

                function getArticle() {
                if (xmlhttp.readyState==4) {
                if (xmlhttp.status==200) {
                document.getElementById("test").innerHTML = xmlhttp.responseText
                }
                }
                }
                </script>
                </head>

                <input onclick="loadXMLDoc('test.html')">

                <div id="test" name="test"></div>更多精彩文章及讨论,请光临枫下论坛 rolia.net
    • 所以AJAX还不是成熟的技术,IE的support也没netscape好。用户的机器语言可能是任何语言,也就是说html可以在服务器设编码
      所以AJAX还不是成熟的技术,IE的support也没netscape好。用户的机器语言可能是任何语言,也就是说html可以在服务器设编码,但用XMLHttpRequest返回的response可能被用任何编码的阅览器表现出来,所以在send request的时候就要把用户使用的codeset send到你的xml 服务器,然后根据用户的编码返回response。
      • HOW? - "所以在send request的时候就要把用户使用的codeset send到你的xml 服务器,然后根据用户的编码返回response。 "
      • 這個"所以"沒有邏輯性.AJAX成熟不成熟和他的問題沒啥關係,gmail對多語言多字符集支持就很好.我覺得大致應該是benlin說的那樣,是靜態頁面本身的字符集問題.很多老外給的例子啥的都沒考慮國際化,咱們照著用就有字符集問題,太普遍了.
        • 跟静态页面的字符集设置是没有关系的。主要是XMLHttpRequest在从服务器端读文件的时侯,都缺省当UTF-8读的。FireFox可以指定encoding方式。但是IE不行。如果用PHP什么的,可以在服务器端强行指定charset,但是对于静态文件,
          即使你在文件头上设定了charset也不管用。
          • 嗯,昨天正好有空我就试了下,确实如此,firefox没问题ie有问题。但是firefox如果charset都对的话是不需要overrideMimeType。这问题你解决之后能不能把结果跟大家也分享一下?
            • 我现在能说的就是打倒IE。 :(
              • 我从xml读内容,IE和firefox都OK了。html和xml全部都是utf-8编码,xml内容是中英文混合,alert和innerHTML都正确。如果你们的数据可以改成xml不用html应该就没问题了
                function alertContents() {

                if (http_request.readyState == 4) {
                if (http_request.status == 200) {
                var xmldoc = http_request.responseXML;
                var root_node = xmldoc.getElementsByTagName('root').item(0);
                alert(root_node.firstChild.data);
                document.getElementById("test").innerHTML = root_node.firstChild.data;
                } else {
                alert('There was a problem with the request.');
                }
                }

                }
                • 用XML是我的下下策了。因为原始都是HTML文档,转成XML不容易。而且用XML只能一个NODE一个NODE拿信息,然后再拼回HTML格式。不太容易实现。除非就是放弃所有格式,用plain text了。:(
                • 有意思,我现在读html然后显示在innerHTML也没有问题了。之前不能显示的原因还不确定,因为我同时改动了两个不同的地方。不过我都是UTF-8做的。
                  • 能不能具体说一下?谢谢
                    • GB2312也通过了。我还在找之前不能work的原因呢,有发现我会尽快告诉你
                      • 谢谢。能否先告诉一下你当前的设置、code,我好和你一起研究研究。
                        • 抱歉刚刚吃饭来着。这么交流挺费劲的,你能上msn不,或者电话?我都可以。
                          • 抱歉,我也是忙着,只能有一搭没一搭的过来看一下问一下。PM你了。
                      • 没有根据,但是我怀疑你其实没有改变编码方式,仅仅改变<meta>的内容。
                        • 你的懷疑是很正確的,html頭的編碼沒任何影響,有影響的是文件本身的編碼。只要文件本身的編碼是UTF-8就OK。因爲我公司的電腦是2000,我連回家裏的XP才發現是這原因。老兄你是真有經驗,向你學習!
                          • 一起学习.怎么你跟bdbs都是17:00准时回复?
          • 建议两种解决方案
            1,服务器使用UTF-8. 既然问题是XMLHttpRequest缺省使用UTF-8,为什么不让全部系统都用UTF-8呢?

            2,如果一定用GB2312,可以在取到文档之后用一个二三十行的函数转成gb2312。

            你给了js程序,但是不知道整个页面的编码是什么,也不知道你的服务器设置怎么样(比如说,AddDefaultCharset utf-8?),所以没法试验。
            • 1.现有文档不是utf-8编码。2.服务器不是说改就能改的,而且我试过在IIS下强行设置也无效。3.页面charset=gb2312 4.“取到文档之后用一个二三十行的函数转成gb2312” 你该不是指Javascript吧?如果是,请赐教。
              • No sure if it is going to work, but try it.
                you need to set codepage=1381 in your asp page to tell server you are using chinese in asp page for decoding
                <@ codepage=1381%>

                and then Use Response.BinaryWrite xml.responseBody to write out whatever from HTML


                ----
                • 拜托。开贴就说了,这是一个纯静态网站。
              • I think you can reference Inputking.
    • 编码问题
      • 所以现在我不明白,你的问题是:1,XMLHttpRequest用UTF-8的方式从服务器取GB2312编码的文件。2,XMLHttpRequest取到了UTF8编码的文档,你要转成GB2312在客户端显示。到底是1还是2?
      • 再加一个编码
        -----
        所以,现在有4个编码:服务器偷偷发出的文件头中的编码;HTML头的编码;客户端系统的编码和客户端浏览器的编码。
        -------
        再加一个编码:文档内容真正的编码。用notepad看到中文,但是它有可能是gbk编码,也有可能是UTF-8编码,你看不出分别的。

        所以我怀疑HeelToe测试了UTF8之后,仅仅把HTML头的编码修改成GB2312,继续测试,发现也跑得很好;其实文件还是UTF-8编码。(怀疑而已,no offence)
        • 猜测正确。结论是,只要called file是utf-8编码的中文,无论calling file, browser, web server, etc 是什么编码,IE & Firefox都正确显示。否则IE就没戏了。所以看来把called file Save As utf-8 文档是最好的办法了。谢谢楼上诸位。