在HTTP协议中,浏览器不能向服务器直接传递某些特殊字符,就必须对这些字符进行URL编码再传送。
Private Sub cmdEncode_Click()
Dim i As Integer
Dim strChar As String
Dim strMsg As String
Dim strText As String
strMsg = " 中国 "
For i = 1 To Len (strMsg)
strText = strText & " % " & Left ( Hex ( Asc ( Mid (strMsg, i, 1 ))), 2 ) & " % " & Right ( Hex ( Asc ( Mid (strMsg, i, 1 ))), 2 )
Next
Debug.Print strText
End Sub
Private Sub cmdEncode_Click()
Dim strMsg As String
Dim a() As Byte
Dim i As Integer
Dim strText As String
strMsg = " 中国 "
a() = StrConv (strMsg, vbFromUnicode)
For i = LBound (a) To UBound (a)
strText = strText & " % " & Right ( " 00 " & Hex (a(i)), 2 )
Next
Debug.Print strText
End Sub
Private Sub cmdDecode_Click()
Dim strText As String
Dim strMsg As String
Dim strChar As String
Dim i As Integer
strText = " %D6%D0%B9%FA "
For i = 1 To Len (strText)
strChar = Mid (strText, i, 1 )
If strChar = " % " Then
strMsg = strMsg & Chr ( Val ( " &H " & Mid (strText, i + 1 , 2 ) & Mid (strText, i + 4 , 2 )))
i = i + 5
End If
Next
Debug.Print strMsg
End Sub
' 以strConv进行当前页面解码
Private Sub cmdDecode_Click()
Dim i As Long
Dim a() As Byte , vTemp As Variant
Dim strText As String
Dim strMsg As String
strText = " %D6%D0%B9%FA "
vTemp = Split (strText, " % " )
ReDim a( UBound (vTemp) - 1 ) As Byte
For i = LBound (vTemp) + 1 To UBound (vTemp)
a(i - 1 ) = Val ( " &h " & vTemp(i))
Next
strMsg = StrConv (a, vbUnicode)
Debug.Print strMsg
End Sub
Private Function UrlEncode(strUrl As String ) As String
Dim i As Integer , j As Integer
Dim a() As Byte
Dim strChar As String
Dim strText As String
strText = ""
For i = 1 To Len (strUrl)
strChar = Mid (strUrl, i, 1 )
Select Case Asc (strChar)
' 48 to 57代表0~9;65 to 90代表A~Z;97 to 122代表a~z
' 42代表*;46代表.;64代表@;45代表-;95代表_ 此点在文最后做出说明
Case 48 To 57 , 65 To 90 , 97 To 122 , 42 , 45 , 46 , 64 , 95
strText = strText & strChar
' 空格转换成 "+", 注意的"+"会转换成"%2B"
Case 32
strText = strText & " + "
' 其他字符正常转换成十六进制
Case Else
' 转换成为缺省页码
a = StrConv (strChar, vbFromUnicode)
For j = LBound (a) To UBound (a)
strText = strText & " % " & Right ( " 00 " & Hex (a(j)), 2 )
Next
Erase a()
End Select
Next
UrlEncode = strText
End Function
运行:Debug.Print UrlEncode("email:admin@xx.com * 中国")
结果: email%3Aadmin@xx.com+*+%D6%D0%B9%FA
Public Function UrlDecode(strUrl As String ) As String
Dim strChar As String
Dim strText As String
Dim strTemp As String
Dim strRet As String
Dim LngNum As Long
Dim i As Integer
For i = 1 To Len (strUrl)
strChar = Mid (strUrl, i, 1 )
Select Case strChar
Case " + "
strText = strText & " "
Case " % "
strTemp = Mid (strUrl, i + 1 , 2 ) ' 暂时取2位
LngNum = Val ( " &H " & strTemp)
' >127即为汉字
If LngNum < 128 Then
strRet = Chr (LngNum)
i = i + 2
Else
strTemp = strTemp & Mid (strUrl, i + 4 , 2 )
strRet = Chr ( Val ( " &H " & strTemp))
i = i + 5
End If
strText = strText & strRet
Case Else
strText = strText & strChar
End Select
Next
UrlDecode = strText
End Function
运行:Debug.Print UrlDecode("email%3Aadmin@xx.com+*+%D6%D0%B9%FA")
结果:email:admin@xx.com * 中国
需要注意的几点:
1、网络中通常会说CBK,GB2312,JIS,BIG5是字符集,而字符的储存方式叫作编码。各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,同时也包含了“编码”的含义。
2、如果直接在IE地址栏输入:http://www.baidu.com/s?wd=中国是可以访问的,但是换作Opera浏览器则会错误。这是由于不同浏览器识对客户端的URL编码不同造成。具体可参考:浏览器发送URL的编码特性。
3、在本段在URLEncode中加入对[*],[.],[@],[-],[-]的判断。主要是显示编码以后地址栏URL的结果,如baidu搜索中admin@xx.com会依旧会解吸成为admin@xx.com.
但是地址栏的URL并不代表发送到服务器的URL ,发送到服务器的URL实际上已经被编码成为admin%40cnlaunch%2Ecom。
所以如果需要显示成地址栏的结果,可以按以上函数,如果显示大送到服务器的URL编码,可以去掉对这5个字符的Ascii判断即可。