上一篇剩下的问题,为了搞明白编码问题,进一步进行测试。测试服务器端的设定,对客户端读取的影响。以及参数上传相关的东西。
上回说到responseBody是未解码的二进制数据,而responseText是解码后的字符串,而xmlhttp默认解码方式为utf-8字符集,对于没有指定返回数据编码的页面,就会出现中文解码为乱码的情况。指定返回编码的方法:PHP:header('Content-Type:text/html;charset=GB2312');ASP:response.Charset="GB2312"JSP:response.setHeader("Charset","GB2312");这样,responseText的数据中的中文应该就能正确解码了。
今天进行了测试,测试环境: Windows XP + IIS5.1 + IE6.0测试语言: ASP测试结果:
测试结果 编码设定情况responseTextresponseBodygb2utf8(responseBody) 服务器动态页面编码方式不设定 中文乱码 乱码 中文正常 服务器动态页面编码GB2312 中文正常 乱码 中文正常 服务器动态页面编码UTF-8(动态页面要保存为UTF-8编码文件) 中文正常 乱码 中文乱码
另外,作了xmlhttp参数请求的测试,该测试只是改变客户端的参数发送内容,而服务器端的处理不变,看服务器接收到和解析出的信息是否和自己的目的参数一样。其中用到一中文URL编码的函数,是从网上找来的,只对中文转码的话,是没有问题的,可发现对空格和特殊字符的处理是有问题的。原版函数如下:
Function URLEncoding(vstrIn) strReturn = "" For i = 1 To Len (vstrIn) ThisChr = Mid (vStrIn,i, 1 ) If Abs ( Asc (ThisChr)) < & HFF Then strReturn = strReturn & ThisChr Else innerCode = Asc (ThisChr) If innerCode < 0 Then innerCode = innerCode + & H10000 End If Hight8 = (innerCode And & HFF00) & HFF Low8 = innerCode And & HFF strReturn = strReturn & " % " & Hex (Hight8) & " % " & Hex (Low8) End If Next URLEncoding = strReturn End Function 这个函数的缺点是,只对ASCⅡ>=255的字符进行转码,就是对Unicode(UTF-8?)等双字节编码的字符进行 ASCⅡ双字节取得,用%+十六进制的传输。而对于ASCⅡ<255则原封不动的保留,这样的话,有些特殊字符 就不能当参数传递了,比如你要传值 ,服务器端就会给你翻译成空格。 网上找了些资料,也看了下URI的定义文档RFC2396,觉得正确的编码应该是这样的: 1。只对每项参数的参数值进行编码,不对这个URL编码。 2。按RFC2396定义的规则就行编码,对于除了“0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz-_.!~*'()”这些字符以外的字符都进行编码(“”不包括在内)。虽然 自己测试IE的编码方式对于一些ASCⅡ<255的数据提交时不进行编码,不过如果编码的话,在服务 器端解析以后的参数内容也是正确的,也就是request.QueryString和request.form整体读取的时候可能 与IE发送的不一样,不过request.QueryString(pname)和request.Form(pname)读出的数据都是正确 的。对于上述以后的字符,如果ASCⅡ<255的话,用%XX来进行转码,如果ASCⅡ>=255,用上面函数 中的那种方法,%XX%XX进行转码。有一个特殊的字符,空格要转为+,但是如果和其他字符一样转换, 被转换为 ,也是可以正常接受的。所以修改后的函数为: Function URLEncoding(vstrIn) ' Written By 蓝田/流浪狗 strReturn = "" stresc = " 0123456789 " & _ " ABCDEFGHIJKLMNOPQRSTUVWXYZ " & _ " abcdefghijklmnopqrstuvwxyz " & _ " -_.!~*'() " ' RFC2396 Mark characters For i = 1 To Len (vstrIn) ThisChr = Mid (vStrIn,i, 1 ) if ThisChr = " " then strReturn = strReturn & " + " ElseIf inStr (stresc,ThisChr) > 0 then strReturn = strReturn & ThisChr ElseIf Abs ( Asc (ThisChr)) < & HFF Then strReturn = strReturn & " % " & Hex ( Asc (ThisChr)) Else innerCode = Asc (ThisChr) If innerCode < 0 Then innerCode = innerCode + & H10000 End If Hight8 = (innerCode And & HFF00) & HFF Low8 = innerCode And & HFF strReturn = strReturn & " % " & Hex (Hight8) & " % " & Hex (Low8) End If Next URLEncoding = strReturn End Function 贴一下上面测试的结果 测试结果 提交方式提交内容request.QueryStringrequest.QueryString(pname) GET的URL 空格(写入空格) 空格被转换成 空格 GET的URL 空格(写入 ) 空格 GET的URL 空格(写入+) + 空格 GET的URL 中文(直接写入中文) 中文 中文 GET的URL 中文(写入编码的中文) 编码的中文 中文 POST的URL 空格(写入URL空格) 空格被转换成 空格 POST的URL 空格(写入 ) 空格 POST的URL 空格(写入+) +被转换成 空格提交方式提交内容request.request.Formrequest.request.Form(pname) POST的form-urlencoded(实际POST内容没整体编码) 空格(写入空格) 空格 该空格删除 POST的form-urlencoded(实际POST内容没整体编码) 空格(写入 ) 空格 POST的form-urlencoded(实际POST内容没整体编码) 空格(写入+) + 空格 POST的form-urlencoded(实际POST内容没整体编码) 中文(直接写入中文) 乱码 乱码 POST的form-urlencoded(实际POST内容没整体编码) 中文(写入编码的中文) 编码的中文 中文 POST的form-urlencoded(实际POST内容已整体编码) 空格(编码为 ) 空格 POST的form-urlencoded(实际POST内容已整体编码) 空格(编码为+) + 空格 POST的form-urlencoded(实际POST内容已整体编码) 中文(写入编码的中文) 编码的中文 中文
好了,先这样吧,这两天废寝忘食的看这个东西,比上班还累10倍.如果大家看到哪里写的不对,烦请留个言我改过来。