这样的地址 xxx.asp?name=中国 ,通过 超链接打开这个链接 ,xxx.asp能够成才接收参数,但是如果将地址直接放到浏览器地址栏上,回车, xxx.asp就无法正确接收中文参数,一直显示乱码。做了很多实验终于知道原因:
因为我的xxx.asp是gb2312编码, 如果通过超链接进入,地址编码与xxx.asp编码会保持一致, 而如果通过浏览器地址栏进入, 现在大部分浏览器地址栏中的字符都被当做utf-8处理。 所以我们知道原因了,通过地址栏传过来的字符串都被当成了utf-8的编码进行传递,自然xxx.asp处理会变成乱码。
所以解决这个问题就是要将url中的utf-8字符转成gb2312然后再,重新传一遍参数
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>无标题文档</title> </head> <body> <% function chinese2unicode(Str) dim i dim Str_one dim Str_unicode for i=1 to len(Str) Str_one=Mid(Str,i,1) Str_unicode=Str_unicode&chr(38) Str_unicode=Str_unicode&chr(35) Str_unicode=Str_unicode&chr(120) Str_unicode=Str_unicode& Hex(ascw(Str_one)) Str_unicode=Str_unicode&chr(59) next Response.Write Str_unicode end function function UTF2GB(UTFStr) for Dig=1 to len(UTFStr) if mid(UTFStr,Dig,1)="%" then if len(UTFStr) >= Dig+8 then GBStr=GBStr & ConvChinese(mid(UTFStr,Dig,9)) Dig=Dig+8 else GBStr=GBStr & mid(UTFStr,Dig,1) end if else GBStr=GBStr & mid(UTFStr,Dig,1) end if next UTF2GB=GBStr end function function ConvChinese(x) A=split(mid(x,2),"%") i=0 j=0 for i=0 to ubound(A) A(i)=c16to2(A(i)) next for i=0 to ubound(A)-1 DigS=instr(A(i),"0") Unicode="" for j=1 to DigS-1 if j=1 then A(i)=right(A(i),len(A(i))-DigS) Unicode=Unicode & A(i) else i=i+1 A(i)=right(A(i),len(A(i))-2) Unicode=Unicode & A(i) end if next if len(c2to16(Unicode))=4 then ConvChinese=ConvChinese & chrw(int("&H" & c2to16(Unicode))) else ConvChinese=ConvChinese & chr(int("&H" & c2to16(Unicode))) end if next end function function c2to16(x) i=1 for i=1 to len(x) step 4 c2to16=c2to16 & hex(c2to10(mid(x,i,4))) next end function function c2to10(x) c2to10=0 if x="0" then exit function i=0 for i= 0 to len(x) -1 if mid(x,len(x)-i,1)="1" then c2to10=c2to10+2^(i) next end function function c16to2(x) i=0 for i=1 to len(trim(x)) tempstr= c10to2(cint(int("&h" & mid(x,i,1)))) do while len(tempstr)<4 tempstr="0" & tempstr loop c16to2=c16to2 & tempstr next end function function c10to2(x) mysign=sgn(x) x=abs(x) DigS=1 do if x<2^DigS then exit do else DigS=DigS+1 end if loop tempnum=x i=0 for i=DigS to 1 step-1 if tempnum>=2^(i-1) then tempnum=tempnum-2^(i-1) c10to2=c10to2 & "1" else c10to2=c10to2 & "0" end if next if mysign=-1 then c10to2="-" & c10to2 end function response.Write UTF2GB(request.QueryString)&"<br>" response.Redirect("bb.asp?"&UTF2GB(request.QueryString))%> </body> </html>
bb.asp
<% response.Write request.QueryString&"<br>" response.Write request.QueryString("id") %>
bb.asp 中的request.QueryString("id") 可以正常显示成中文了。
UTF2GB函数就是将utf-8编码的字符 ,转换成了中文,然后再讲参数重新传递一下,就正常了。
这里为什么不在xxx.asp里直接
UTF2GB(request.QueryString("id"))这样来做?
这样做并不会显示成正确的中文,因为
request.QueryString("id") 取值的时候已经被系统自动转化成了中文,因为编码不对所以,就变成了乱码的中文, 在这之上再进行转换已经没有意义,它已经不是utf-8编码,而是被转化成乱码的中文
。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
半个小时后,我终于找到问题的关键。。。继续更新。。。。。。。。。
知道为什么会出现乱码了, 因为在地址栏输入地址,地址会被执行utf-8 的 urlencode ,地址被转码了, 到了xxx.asp后,取值的时候, 会自动按页面编码执行相应的urldecode函数, 也就是gb2312编码下的urldecode 函数, 所以就出现了乱码,有个很简单的办法就是 ,对url执行utf-8编码的 urldecode就可以了, 在网上又找到一个简单的函数
<% Function UrlEncode_GBToUtf8(ByVal str) Dim B ''单个字符 Dim ub ''中文字的Unicode码(2字节) Dim High8b, Low8b ''Unicode码的高低位字节 Dim UtfB1, UtfB2, UtfB3 ''Utf-8码的三个字节 Dim i, s For i = 1 To Len(str) B=Mid(str, i, 1) ub = AscW(B) If (ub>=48 And ub<=57) Or (ub>=65 And ub<=90) Or (ub>=97 And ub<=122) Or ub=42 Or ub=45 Or ub=46 Or ub=64 Or ub=95 Then ''48 to 57代表0~9;65 to 90代表A~Z;97 to 122代表a~z ''42代表*;46代表.;64代表@;45代表-;95代表_ s=s & B ElseIf ub=32 Then ''空格转成+ s=s & "+" ElseIf ub<128 Then ''低于128的Ascii转成1个字节 s=s & "%" & Right("00" & Hex(ub),2) Else High8b = (ub And &HFF00) / &H100 ''Unicode码高位 Low8b = ub And &HFF ''Unicode码低位 UtfB1 = (High8b And &HF0) / &H10 Or &HE0 ''取Unicode高位字节的二进制的前4位 + 11100000 UtfB2 = ((High8b And &HF) * &H4 + (Low8b And &HC0) / &H40) Or &H80 ''取Unicode高位字节的后4位及低位字节的前2位 +10000000 UtfB3 = (Low8b And &H3F) Or &H80 ''取Unicode低位字节的二进制后6位 + 10000000 s = s & "%" & Hex(UtfB1) & "%" & Hex(UtfB2) & "%" & Hex(UtfB3) End If Next UrlEncode_GBToUtf8 = s End Function ''“汉”-AscW("汉")=27721(十进制) 01101100 01001001(二进制) 6C49(十六进制) ''将Gb2312码转成Utf-8码(十六进制表示)的方法为,先用AscW将Gb2312转为Unicode码(2字节),再''将Unicode码的二进制中的位按utf-8(3字节)模板规则填充 x 位: ''URL解码,Gb2312页面提交到Utf-8页面 Function UrlDecode_GBToUtf8(ByVal str) Dim B,ub ''中文字的Unicode码(2字节) Dim UtfB ''Utf-8单个字节 Dim UtfB1, UtfB2, UtfB3 ''Utf-8码的三个字节 Dim i, n, s n=0 ub=0 For i = 1 To Len(str) B=Mid(str, i, 1) Select Case B Case "+" s=s & " " Case "%" ub=Mid(str, i + 1, 2) UtfB = CInt("&H" & ub) If UtfB<128 Then i=i+2 s=s & ChrW(UtfB) Else UtfB1=(UtfB And &H0F) * &H1000 ''取第1个Utf-8字节的二进制后4位 UtfB2=(CInt("&H" & Mid(str, i + 4, 2)) And &H3F) * &H40 ''取第2个Utf-8字节的二进制后6位 UtfB3=CInt("&H" & Mid(str, i + 7, 2)) And &H3F ''取第3个Utf-8字节的二进制后6位 s=s & ChrW(UtfB1 Or UtfB2 Or UtfB3) i=i+8 End If Case Else ''Ascii码 s=s & B End Select Next UrlDecode_GBToUtf8 = s End Function Private Function UrlEncode_GBToUtf8_V2(szInput) Dim wch, uch, szRet Dim x Dim nAsc, nAsc2, nAsc3 If szInput = "" Then UrlEncode_GBToUtf8_V2= szInput Exit Function End If For x = 1 To Len(szInput) wch = Mid(szInput, x, 1) nAsc = AscW(wch) If nAsc < 0 Then nAsc = nAsc + 65536 If wch = "+" then szRet = szRet & "%2B" ElseIf wch = "%" then szRet = szRet & "%25" ElseIf (nAsc And &HFF80) = 0 Then szRet = szRet & wch Else If (nAsc And &HF000) = 0 Then uch = "%" & Hex(((nAsc 2 ^ 6)) Or &HC0) & Hex(nAsc And &H3F Or &H80) szRet = szRet & uch Else uch = "%" & Hex((nAsc 2 ^ 12) Or &HE0) & "%" & _ Hex((nAsc 2 ^ 6) And &H3F Or &H80) & "%" & _ Hex(nAsc And &H3F Or &H80) szRet = szRet & uch End If End If Next UrlEncode_GBToUtf8_V2= szRet End Function
response.Write UrlDecode_GBToUtf8(request.QueryString)&"<br>"
response.Redirect("bb.asp?"&UTF2GB(request.QueryString))
- UrlEncode_GBToUtf8 不支持生僻字,比如:鎔。
- UrlEncode_GBToUtf8_V2 支持生僻字
- UrlDecode_GBToUtf8 支持生僻字
如果xxx.asp是utf-8的编码, 就不存在以上问题