首页 > 开发 > XML > 正文

用XMLHTTP Post/Get HTML页面时的中文乱码之完全Script解决方案

2024-07-21 02:04:26
字体:
来源:转载
供稿:网友
以前我曾经贴过一篇用xmlhttp post form 的帖子,那里的代码中我post e文的value毫无问题,但是后来发现post含有中文的表单时会出现乱码,原因当然是utf-8 和gb2312 之间的转换问题了!tnnd,打倒gb2312!大家都用utf8多好。

用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>

嘿嘿,是不是很简单啊,用这个再试试看?一切ok!

(顺便说说byte(),这个东东在vbscript里的表现只能用妖来形容——对它调用vartype 返回8209——vbarray + vbbyte,用lbound、ubound能拿到数组的上界下界,但是就是不能用name(i)的形式访问,搞得我以为在script里根本没法处理这种类型,在bytes2bstr函数里可以看到我是把它当成string来处理的——lenb/midb什么的,发现这点纯属意外——我开始往这个函数里传的是xmlhttp.responsetext,想一个byte一个byte地看看里面到底有点什么,后来一时性起把responsetext改成responsebody,结果就中奖了,哈哈)

最后的废话:
1、以上代码在msxml parser 3 release+vbscript 5.5环境下通过。那位兄弟有早一点版本的script可以帮我试试看能不能成。
2、一直以为javascript vs vbscript应该是javascript略好,所以有时候想彻底抛弃vbscript,asp server/client统统用javascript,看来未必是个好主意。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表