Request.QueryString和Request.ServerVariables(" QUERY_STRING")不显示UNICODE

时间:2015-01-02 18:45:58

标签: unicode vbscript asp-classic

我正在向经典ASP应用程序添加日志记录功能,并且在用户提交UNICODE查询时难以正确显示Request.QueryString和Request.ServerVariables。

例如 -

Response.write Request.QueryString
strVar1=&strVar2=%E8%A1%8C%E9%9B%B2%E6%B5%81%E6%B0%B4&strVar3=blah1&strVar4=blah2


Response.write Request.ServerVariables("QUERY_STRING")
strVar1=&strVar2=%E8%A1%8C%E9%9B%B2%E6%B5%81%E6%B0%B4&strVar3=blah1&strVar4=blah2


然而,如果我在Request.QueryString中指定一个UNICODE变量,它会正确打印:

Response.write Request.QueryString("strVar2")
行雲流水


如何获取Request.QueryString或Request.ServerVariables(" QUERY_STRING")以包含UNICODE?我在搜索和结果页面上都有以下内容,并且查询对数据库成功执行:

<%
Response.CodePage = 65001
Response.CharSet = "utf-8"
%>

要回答bobince的问题,我尝试记录他们提交的搜索字词和网页 - 如果有更好的方法可以做到这一点我全部耳朵:

'Enable Logging: writes to MyDB.dbo.logging
'---------------------------------------------------------------------------------------------
Set cmd = Server.CreateObject("ADODB.Command")
cmd.CommandType = adCmdText
cmd.ActiveConnection = objConn

strADName = UCase(Request.ServerVariables("AUTH_USER"))

Protocol = Request.ServerVariables("SERVER_PROTOCOL")
Protocol = Left(Protocol,InStr(Request.ServerVariables("SERVER_PROTOCOL"),"/")-1)

if Request.ServerVariables("SERVER_PORT") = "80" then
port = ""
else
port = ":" & Request.ServerVariables("SERVER_PORT")
end if

CurPageURL = lcase(Protocol) & "://" & Request.ServerVariables("SERVER_NAME") &_
          port & Request.ServerVariables("SCRIPT_NAME") & "?" & _
          Request.ServerVariables("QUERY_STRING")

strSQL = "INSERT INTO MyDB.dbo.Logging([user],URL) SELECT ?, ? "
cmd.Parameters.Append (cmd.CreateParameter("User", adVarWChar, adParamInput, len(strADName),    strADName))
cmd.Parameters.Append (cmd.CreateParameter("URL", adVarWChar, adParamInput, len(CurPageURL), CurPageURL))

cmd.CommandText = strSQL
set objRS = cmd.Execute
'-----------------------------------------------------------------------------------------------

2 个答案:

答案 0 :(得分:5)

这与Unicode无关。

Request.QueryString分别做两件事。

如果您在没有参数的情况下使用它,它将完全按照浏览器提交的方式返回整个查询字符串(如上所述,与QUERY_STRING服务器变量相同)。

如果将它与"strVar2"之类的参数一起使用,它会将查询字符串拆分为参数部分,找到与参数名称(strVar2=...)对应的一个(),并返回值。在这样做时,它负责对查询字符串的组件进行URL解码,包括名称和值,因此输入中的%xx序列被解码为它们所代表的字节序列:0xE8,0xA1,0x8C等等上。当您将该字节字符串打印到浏览器解码为UTF-8的页面时,他们将看到行雲流水

如果您真的想要,可以在完整的查询字符串上自行执行URL解码步骤。在Classic ASP中没有用于URL解码的内置功能,但您可以自己编写这样的功能(参见http://www.aspnut.com/reference/encoding.asp中的URLDecode),或使用

decodeURIComponent(s.replace(/\+/g, ' '))
来自JScript的

请注意,如果您对整个网址字符串进行URL解码,则会破坏它。例如,对于输入查询字符串:

foo=abc%26def&bar=%e6%97%a5%e6%9c%ac%e8%aa%9e
你会得到:

foo=abc&def&bar=日本語

对于日语来说很好,但是foo的值中的&符号已经打破了整个字符串,因此您无法再确定原始参数是什么。一般情况下,一旦将URL组件从它们所引入的URL中拆分出来,您通常只能对其进行解码。这就是ASP为您所做的事情:Request.QueryString("foo")会正确地返回abc&def这就是为什么您应该几乎总是使用该方法检索参数。

您通过解码整个查询字符串到底想要做什么?

答案 1 :(得分:0)

如果这可以帮助其他人:

我通过使用&amp;分离功能从QUERY_STRING中提取变量名来解决这个问题。作为分隔符。然后我使用Request.QueryString的变量来获取值,包括具有UNICODE的值。除非用户包括&amp;在查询中,这将是非常罕见的。我确实陷阱,所以至少在这种情况下我仍然可以看到日志中访问的用户和页面。 Bobince你的反应很好,我会选择它作为答案。

'Enable Logging: writes to MyDB.dbo.logging
'---------------------------------------------------------------------------------------------
Set cmd = Server.CreateObject("ADODB.Command")
    cmd.CommandType = adCmdText
    cmd.ActiveConnection = objConn
    cmd.CommandTimeOut = 1200

strADName = UCase(Request.ServerVariables("AUTH_USER"))

Protocol = Request.ServerVariables("SERVER_PROTOCOL")
Protocol = Left(Protocol,InStr(Request.ServerVariables("SERVER_PROTOCOL"),"/")-1)

if Request.ServerVariables("SERVER_PORT") = "80" then
   port = ""
else
   port = ":" & Request.ServerVariables("SERVER_PORT")
end if 

CurPageURL = lcase(Protocol) & "://" & Request.ServerVariables("SERVER_NAME") &_
          port & Request.ServerVariables("SCRIPT_NAME") & "?"

On Error Resume Next
a = Request.ServerVariables("QUERY_STRING")
a = split(a,"&")
for each x in a
'response.write(left(x,InStr(x,"=")-1) & "<br />")
CurPageURL = CurPageURL + left(x,InStr(x,"=")-1) + "=" + Request.QueryString(left(x,InStr(x,"=")-1)) & "&"
next

If Err.Number <> 0 Then
    CurPageURL = CurPageURL + "Error: Search Term Contained a &"
    Err.Clear
Else
    CurPageURL = left(CurPageURL,len(CurPageURL)-1)
End If

strSQL = "INSERT INTO MyDB.dbo.Logging([user],URL) SELECT ?, ? "
cmd.Parameters.Append (cmd.CreateParameter("User", adVarWChar, adParamInput, len(strADName), strADName))
cmd.Parameters.Append (cmd.CreateParameter("URL", adVarWChar, adParamInput, len(CurPageURL), CurPageURL))

cmd.CommandText = strSQL
set objRS = cmd.Execute