XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)


Posted in Javascript onJanuary 12, 2011

在数据发送一方,利用 javascript 的 escape 函数事先将所有中文转换成英文编码并保存(也可以用 ASP 等其它语言的函数实时转换输出)。
在数据接收一方,利用 javascript 的 unescape 函数将所有英文编码还原。
由于 Ajax 不论任何编码都能正常传送英文,所以用这种方法可以轻松解决。

--------------------------------------------------------------------------------
用XMLHTTP Post Form时的表单乱码有两方面的原因——Post表单数据时中文乱码;服务器Response被XMLHTTP不正确编码引起的乱码。换句话说,本文主要解决两个问题——怎样正确Post中文内容&怎样正确显示得到的中文内容。
Part I Post中文内容
先看看E文的表单是怎么提交的:

<SCRIPT language="JavaScript"> 
strA = "submit1=Submit&text1=scsdfsd"; 
var oReq = new ActiveXObject("MSXML2.XMLHTTP"); 
oReq.open("POST","http://ServerName/VDir/TstResult.asp",false); 
oReq.setRequestHeader("Content-Length",strA.length); 
oReq.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded"); 
oReq.send(strA); 
</ScRIPT>

如果把strA = "submit1=Submit&text1=scsdfsd";换成:
strA = "submit1=Submit&text1=中文";
你会发现提交上去的东东根本不对,ASP中Request.Form("Text1")根本取不到值。俺用Request.BinaryRead把一个HTML Form中的Post内容写出来看了看,才发现问题——Form提交时也要编码的,编码后的中文是类似于%??%??的转义字符,比如“中文”就被编码为:%D6%D0%CE%C4。呵呵,也怪俺笨,人家CONTENT-TYPE里明明写的清清楚楚——application/x-www-form-urlencoded,urlencoded嘛当然就是这个样子了。既然这样,那我们也知道该怎么办了——自己做转换,代码见下:
<SCRIPT language="VBScript"> 
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 
strA = URLEncoding("submit1=Submit&text1=中文") 
oReq = CreateObject("MSXML2.XMLHTTP") 
oReq.open "POST","http://ServerName/VDir/TstResult.asp",false 
oReq.setRequestHeader "Content-Length",Len(strA) 
oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded" 
oReq.send strA 
</SCRIPT>

(在这里俺把前面的JavaScript的代码改成了VBScript,不是吃饱了撑的没事干,原因见后)
Part II.正确显示得到的中文内容
OK,如果你在Server端把Form的内容写到数据库/文件的话,你在那里看到的中文毫无问题,但是,假如你想看看Server的Response——问题来了:如果Response的结果不是XML,XMLHTTP.responseXML里当然是不会有东东的,那就用responseText好了,在代码的最后加一句:
alert(oReq.responseText)
看看俺们辛勤劳动的结果 :P
但是但是.....怎么所有的中文全变成了方格? (我打不出来,有兴趣自己去试,也不用Post,Get一个含有中文的网页就可以发现了。)
原因很简单:XMLHTTP得到Response时假定Response是UTF8编码的,如果Response是XML,那还可以通过encoding来指定编码,但HTML就不行了。(见鬼的GB2312,再次打倒!)所以它把含GB2312编码的HTML当成UTF8格式,不出错才有鬼!
不过好在还有补救的办法:XMLHTTP的responseBody 属性里包含的可是未解码的Resonse——"a raw undecoded bytes as received directly from the server" :),唯一的问题是,responseBody返回的是一个unsigned bytes数组,我们怎么去访问它,怎么把它转换成BSTR?
这就是为什么我在上面把代码改成VBScript的原因——VBScript Can do it,but JavaScript Cannot!
代码见下:
<SCRIPT language="VBScript"> 
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 
Function bytes2BSTR(vIn) 
strReturn = "" 
For i = 1 To LenB(vIn) 
ThisCharCode = AscB(MidB(vIn,i,1)) 
If ThisCharCode < &H80 Then 
strReturn = strReturn & Chr(ThisCharCode) 
Else 
NextCharCode = AscB(MidB(vIn,i+1,1)) 
strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode)) 
i = i + 1 
End If 
Next 
bytes2BSTR = strReturn 
End Function 
strA = URLEncoding("submit1=Submit&text1=中文") 
oReq = CreateObject("MSXML2.XMLHTTP") 
oReq.open "POST","http://ServerName/VDir/TstResult.asp",false 
oReq.setRequestHeader "Content-Length",Len(strA) 
oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded" 
oReq.send strA 
alert bytes2BSTR(oReq.responseBody) 
</SCRIPT>

----------------------------------------以上为转载-----------------------------
http://www.dhtmlx.com

Start Building Professional Ajax
Web Applications Today
最近用了 DHTMLX的tree,中文的xml居然用不了,报错,整个系统是GB2312的,而DHTMLX只支持UTF8,英文是正常的,中文就出错。

用法也很简单,是DHTMLX 演示里用的代码。

var obj=document.getElementById(oid); 
obj.style.display="block"; 
obj.focus(); 
if(obj.innerHTML!="")return; 
tree=new dhtmlXTreeObject(oid,"100%","100%",0); 
tree.setImagePath("js/imgs/csh_vista/"); 
tree.setOnClickHandler(click1); 
tree.setXMLAutoLoading("tree.asp"); 
//load first level of tree 
tree.loadXML("tree.asp?id=0");

tree.asp编码为gb2312,和整个系统一致,用response.write返回一个xml
整个系统编码改不了,只有在DHTMLX上想办法了。
查了些资料,最终解决了。

再深入一层发现是,Microsoft.XMLHTTP的原因,就查到了上面的文件。
如是就简单了,修改如下:
1. 增加一个VBScript的中文转换的函数

<script language="VBScript"> 
'处理中文 
function bin2str(bin) 
dim tmp,ustr,i 
tmp="" 
for i=1 to LenB(bin)-1 
ustr=AscB(MidB(bin,i,1)) 
if ustr>127 then 
i=i+1 
tmp=tmp&chr(ustr*256+AscB(MidB(bin,i,1))) 
else 
tmp=tmp&chr(ustr) 
end if 
next 
bin2str=tmp 
end function 
</script>

2.dhtmlxcommon.js的 getXMLTopNode处
var xmlString = this.xmlDoc.responseText;
改为
var xmlString = bin2str(this.xmlDoc.responseBody);//可以在js里直接调用VBScript脚本

3.同时 在输出xml的asp 文件开头加入
<%response.ContentType="application/xml"%>
<?xml version='1.0' encoding='GB2312'?>
当然文件也是保存为gb2312格式的。

Javascript 相关文章推荐
javascript截取字符串(通过substring实现并支持中英文混合)
Jun 24 Javascript
jQuery EasyUI 右键菜单--关闭标签/选项卡的简单实例
Oct 10 Javascript
JS 实现Base64编码与解码实例详解
Nov 07 Javascript
BOM之navigator对象和用户代理检测
Feb 10 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(2)
Feb 20 Javascript
ionic2打包android时gradle无法下载的解决方法
Apr 05 Javascript
用js屏蔽被http劫持的浮动广告实现方法
Aug 10 Javascript
详解封装基础的angular4的request请求方法
Jun 05 Javascript
浅谈Vue数据响应
Nov 05 Javascript
Vue父组件如何获取子组件中的变量
Jul 24 Javascript
微信小程序导入Vant报错VM292:1 thirdScriptError的解决方法
Aug 01 Javascript
JavaScript计算正方形面积
Nov 26 Javascript
奉献给JavaScript初学者的编写开发的七个细节
Jan 11 #Javascript
从盛大通行证上摘下来的身份证验证js代码
Jan 11 #Javascript
javascript 设为首页与加入收藏兼容多浏览器代码
Jan 11 #Javascript
javascript获取当前日期时间及其它操作函数
Jan 11 #Javascript
JavaScript中URL编码函数代码
Jan 11 #Javascript
Jquery跨域获得Json时invalid label错误的解决办法
Jan 11 #Javascript
JS无限树状列表实现代码
Jan 11 #Javascript
You might like
php下将多个数组合并成一个数组的方法与实例代码
2011/02/03 PHP
PHP之短标签开启设置
2013/06/17 PHP
PHP的一个完美GIF等比缩放类,附带去除缩放黑背景
2014/04/01 PHP
PHP和javascript常用正则表达式及用法实例
2014/07/01 PHP
ThinkPHP多语言支持与多模板支持概述
2014/08/22 PHP
使用php实现网站验证码功能【推荐】
2017/02/09 PHP
Jquery中dialog属性小记
2010/09/03 Javascript
基于jquery的finkyUI插件与Ajax实现页面数据加载功能
2010/12/03 Javascript
JQuery扩展插件Validate—6 radio、checkbox、select的验证
2011/09/05 Javascript
jQuery实现冻结表头的方法
2015/03/09 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
2016/07/09 Javascript
在JS中a标签加入单击事件屏蔽href跳转页面
2016/12/16 Javascript
AngularJS中run方法的巧妙运用
2017/01/04 Javascript
使用JS在浏览器中判断当前网络连接状态的几种方法
2017/05/05 Javascript
解决angular双向绑定无效果,ng-model不能正常显示的问题
2018/10/02 Javascript
jQuery实现适用于移动端的跑马灯抽奖特效示例
2019/01/18 jQuery
生成无限制的微信小程序码的示例代码
2019/09/20 Javascript
Python使用ftplib实现简易FTP客户端的方法
2015/06/03 Python
python创建进程fork用法
2015/06/04 Python
PyCharm在win10的64位系统安装实例
2017/11/26 Python
Python Numpy,mask图像的生成详解
2020/02/19 Python
python中数据库like模糊查询方式
2020/03/02 Python
浅谈Selenium+Webdriver 常用的元素定位方式
2021/01/13 Python
HTML5通过调用canvas对象的getContext()方法来获取绘图环境
2014/06/23 HTML / CSS
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
Groupon比利时官方网站:特卖和网上购物高达-70%
2019/08/09 全球购物
struct和class的区别
2015/11/20 面试题
幼儿园中秋节活动反思
2014/02/16 职场文书
白酒市场营销方案
2014/02/25 职场文书
节约电力资源的建议书
2014/03/12 职场文书
《冬阳童年骆驼队》教学反思
2014/04/15 职场文书
服务型党组织建设典型材料
2014/05/07 职场文书
新闻专业毕业生求职信
2014/08/08 职场文书
四风问题原因分析及整改措施
2014/10/24 职场文书
2015年暑期社会实践报告
2015/07/13 职场文书
2016高中社会实践心得体会范文
2016/01/14 职场文书