Request.QueryString and Request.ServerVariables ("QUERY_STRING") UNICODE not displayed
I am adding logging functionality to a classic ASP application and I am having a hard time getting Request.QueryString and Request.ServerVariables to display correctly when users submit UNICODE requests.
For example -
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
However, if I specify a UNICODE variable in Request.QueryString, it prints correctly:
Response.write Request.QueryString("strVar2")
行雲流水
How can I get Request.QueryString or Request.ServerVariables ("QUERY_STRING") to enable UNICODE? I have this on both search and results pages, the queries are running successfully on the database:
<%
Response.CodePage = 65001
Response.CharSet = "utf-8"
%>
To answer bobince's question, I'm trying to find the search terms and the pages they are sent from - if there is a better way to do this, I'm all ears:
'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
'-----------------------------------------------------------------------------------------------
source to share
This has nothing to do with Unicode.
Request.QueryString
does two separate things.
If you use it with no arguments, it returns the entire query string exactly as it was sent by the browser (as above, the same as the QUERY_STRING server variable).
If you use it with a type argument "strVar2"
, it splits the query string into parameter chunks, finds the one that matches the argument name ( strVar2=...
), and returns a value. That being said, it handles the URL-decoding of the query string components, including the name and value, so %xx
the input sequences are decoded into the sequence of bytes they represent: 0xE8, 0xA1, 0x8C, etc. When you print this byte string to a page that the browser decodes as UTF-8, they will see 行雲流水
.
You can do the url-decode step yourself in the full query string if you like. For classic ASP, there is no built-in for URL decode, but you can write such a function yourself (see for example URLDecode
from http://www.aspnut.com/reference/encoding.asp ) or use
decodeURIComponent(s.replace(/\+/g, ' '))
from JScript.
Note that if you URL-decode the whole URL string together, you are kind of breaking it. For example, for a string of input queries:
foo = abc% 26def & bar =% e6% 97% a5% e6% 9c% ac% e8% aa% 9e
You'll get:
foo = abc & def & bar = 日本語
which is great for Japanese, but the ampersand in the meaning for foo
broke the whole line so that you can no longer tell exactly what the original parameters were. Usually, you should only have to decrypt the URL components once you've separated them with the URL they came in. This is what ASP does for you: it Request.QueryString("foo")
will return correctly abc&def
here, so you should almost always use this method to retrieve parameters.
What exactly are you trying to do by decrypting the whole query string?
source to share
If this could help someone else:
I solved this by extracting the variable names from QUERY_STRING using the split function with and as separator. Then I used variables with Request.QueryString to get values, including UNICODE ones. This works if the user did not include it in the request, which will be quite rare. I am delaying it so that at least in this case I can still see the user and the page available in the logs. Because your answer was excellent and I will choose it as my answer.
'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
source to share