前面提到的了 ASP 输出 UTF-8 编码的中文不定时出现乱码的解决方案:ASP页面改为UTF-8编码后,刷新页面中文输入输出不定时乱码终极解决方案
今天遇到的则是输入 UTF-8 编码中文 URI 参数乱码的问题,第一次可以,刷新后取得的输入参数就变成乱码。以下是解决方案:
针对 Ascii 32(0x20)~126(0x7E):
0x20~0x7E
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 完整时
*+ -./0123456789 @ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz escape()未编码字符
%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
! #$ &'()*+,-./0123456789:; = ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ~ encodeURI()未编码字符,空格编码为%20
%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~
! '()* -. 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ~ encodeURIComponent()未编码字符,空格编码为%20
%20!%22%23%24%25%26'()*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~
* -. 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz form data 提交后剩余未编码字符
针对中文
escape("中文"): %u4E2D%u6587 Unicode的16进制形式,等价于 中文 hex(20013)=&H4E2D
encodeURI("中文"): %E4%B8%AD%E6%96%87 UTF-8
encodeURIComponent("中文"): %E4%B8%AD%E6%96%87 UTF-8
虽然 escape
函数已被废弃,推荐使用 encodeURI
或 encodeURIComponent
,而且 jq 的 serialize 已经用 encodeURI 转换了 URI 中的中文,因此不能再对
serialize 的结果进行 encodeURI 转换,单独测试了只用
encodeURI
和 encodeURIComponent 不用
serialize ,除非将 % 符号替换掉,否则中文参数提交到 ASP 页面后,ASP 的 Request 接收到参数二次刷新依然会是乱码,因为是 UTF-8 编码,简言之,就是 ASP 接收处理 encodeURIComponent 编码后的中文时灵时不灵的。故
对于 ASP 来说,最适配的 URI 中文参数传递转换应该还是推荐 escape 转
Unicode 编码,不和转换为 UTF-8 的编码扯皮,扯不清楚,于是自己写了个简单的 VBS 版 unescape
:
' VBS 版 unescape
Public Function unescape(s)
Dim w
w = wsplit(s, "%u", 4) '--处理Unicode编码双字节
w = wsplit(w, "%", 2) '--处理Unicode编码单字符
unescape = w
End Function
Public Function wsplit(s, sp, L)
Dim w, p, i
w = s
If (InStr(w, sp) > 0) Then
p = Split(w, sp)
w = p(0)
For i = 1 To UBound(p)
w = w + ChrW("&H" & Mid(p(i), 1, L)) '----取出定长编码字节
If Len(p(i)) > L Then '----取出后面的编码字符
w = w + Mid(p(i), L + 1)
End If
Next
End If
wsplit = w
End Function
'以下是针对 Unicode 编码的 “中文” 形式的解码函数
public Function asctow(s)
Dim p, w, a, i
w = s
If (InStr(s, "&#") > 0) Then
p = Split(s, "&#")
w = ""
For i = 0 To UBound(p)
If (InStr(p(i), ";") > 0) Then
a = Split(p(i), ";")
a(0) = Replace(a(0), ";", "")
w = w + (ChrW(a(0)) + a(1))
Else
w = w + p(i)
End If
Next
End If
asctow = w
End Function
这回,不管怎么刷新都不会乱码了。
dim TmpStrA
rw "代码:<br/>dim TmpStrA" & "<br/>"
rw "TmpStrA=" & d & "A%20%21%22%23%24%25%26%28%29%u4E2DD%u6587123%u6587%u5B57Bc" & d & "<br/>"
rw "rw TmpStrA" & "<br/>"
rw "Rw " & d & "< hr/" & d & "<br/>"
rw "rw unescape(TmpStrA)" & "<br/><br/>"
Rw "<hr/> 运行结果:<br/><br/>"
TmpStrA="A%20%21%22%23%24%25%26%28%29%u4E2DD%u6587123%u6587%u5B57Bc"
rw TmpStrA
Rw "<hr/>"
rw unescape(TmpStrA)
re
但是 jq 的 .serialize() 默认会将中文参数用 encodeURIComponent() 转换掉,因此,不能用 .serialize() 。还是自己组装一下参数了。