Decoding URL encoded UTF-8 strings in VBScript
urldecode, utf-8, vbscript
Solution
I want to show three methods for three vary environments. All of these methods requires JScript's `encodeURIComponent` and `decodeURIComponent` functions.
1. In ASP, using server-side JavaScript is one of most appropriate solutions :
<script language="javascript" runat="server">
URL = {
encode : function(s){return encodeURIComponent(s).replace(/'/g,"%27").replace(/"/g,"%22")},
decode : function(s){return decodeURIComponent(s.replace(/\+/g, " "))}
}
</script>
<%
Response.Write URL.decode("Paris%20%E2%86%92%20Z%C3%BCrich")
Response.Write URL.encode("Paris → Zürich")
%>
2. 32-Bit only (due to MSScriptControl.ScriptControl is 32-bit only component) in any other WSH :
Dim JSEngine
Set JSEngine = CreateObject("MSScriptControl.ScriptControl")
JSEngine.Language = "JScript"
Function UrlEncode(s)
UrlEncode = JSEngine.CodeObject.encodeURIComponent(s)
UrlEncode = Replace(UrlEncode, "'", "%27")
UrlEncode = Replace(UrlEncode, """", "%22")
End Function
Function UrlDecode(s)
UrlDecode = Replace(s, "+", " ")
UrlDecode = JSEngine.CodeObject.decodeURIComponent(UrlDecode)
End Function
WScript.Echo UrlDecode("Paris%20%E2%86%92%20Z%C3%BCrich")
WScript.Echo UrlEncode("Paris → Zürich")
3. With 64-bit support in any other WSH using a WSC:
urlencdec.wsc (created by using WSC Wizard)
<?xml version="1.0"?>
<component>
<?component error="true" debug="true"?>
<registration
description="Url Encode / Decode Helper"
progid="JSEngine.Url"
version="1.0"
classid="{80246bcc-45d4-4e92-95dc-4fd9a93d8529}"
/>
<public>
<method name="encode">
<PARAMETER name="s"/>
</method>
<method name="decode">
<PARAMETER name="s"/>
</method>
</public>
<script language="JScript">
<![CDATA[
var description = new UrlEncodeDecodeHelper;
function UrlEncodeDecodeHelper() {
this.encode = encode;
this.decode = decode;
}
function encode(s) {
return encodeURIComponent(s).replace(/'/g,"%27").replace(/"/g,"%22");
}
function decode(s) {
return decodeURIComponent(s.replace(/\+/g, " "));
}
]]>
</script>
</component>
and vbs code :
Dim JSEngine
Set JSEngine = GetObject("Script:C:\urlencdec.wsc")
WScript.Echo JSEngine.decode("Paris%20%E2%86%92%20Z%C3%BCrich")
WScript.Echo JSEngine.encode("Paris → Zürich")
Problem
I need to URL decode a string in a VBScript. The string may contain Unicode characters which are encoded as multiple bytes as per UTF-8. So for example "Paris%20%E2%86%92%20Z%C3%BCrich" would decode to "Paris → Zürich". To do the job, I'm using a piece of code that looks like this: ``` Function URLDecode(str) set list = CreateObject("System.Collections.ArrayList") strLen = Len(str) for i = 1 to strLen sT = mid(str, i, 1) if sT = "%" then if i + 2 <= strLen then list.Add cbyte("&H" & mid(str, i + 1, 2)) i = i + 2 end if else list.Add asc(sT) end if next depth = 0 for each by in list.ToArray() if by and &h80 then if (by and &h40) = 0 then if depth = 0 then Err.Raise 5 val = val * 2 ^ 6 + (by and &h3f) depth = depth - 1 if depth = 0 then sR = sR & chrw(val) val = 0 end if elseif (by and &h20) = 0 then if depth > 0 then Err.Raise 5 val = by and &h1f depth = 1 elseif (by and &h10) = 0 then if depth > 0 then Err.Raise 5 val = by and &h0f depth = 2 else Err.Raise 5 end if else if depth > 0 then Err.Raise 5 sR = sR & chrw(by) end if next if depth > 0 then Err.Raise 5 URLDecode = sR End Function ``` This seems to be working well, but it looks exaggeratedly complex to me. In times of HTML5 and web standards, there must be a simpler way to get this done without a bunch of hand-made loops and conditions. Any suggestions?