Wednesday, March 23, 2005

JavaScript URL encoding with Apostrophe

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/javascript_url_encoding_with_apostrophe.htm]

In a previous post I discussed using HttpUtility.UrlEncode to encode querystrings. While this is a great start, we can extend our encoding abilities using JavaScript's escape and unescape methods.

Sometime you'll need to encode at the client side, such as passing data to and from a pop-up window using querystrings (solely a client activity). While escape is very similar to HttpUtility.UrlEncode, there are some slight differences. Escape will encode both the apostrophe (%27) and space (%20 instead of '+').

The problem is that sometimes the security filter on the Web Server won't even allow the escaped chars. They won't allow apostrophe, but they won't allow %27 either. An easy way to test the allowed URL characters on a development site is to just append a dummy querystring, such as www.mySite.com?url=. Depending on the security system installed, you may get an error like "Inline Html scripts are not allowed in URLS for security purposes."

One solution is to take advantage of the safe '*' character. You could first encode the string, and then replace all '%' with '*'. This would give you the safe sequence %*27 instead of  ' or %27. We could then synchronize our server side encoding functions to match this pattern to allow us to freely pass encoded data between the client and server. Below is the HTML for a page to demonstrate this. It contains a encode and decode textbox and button. The buttons call their respective functions to encode/decode the data and store it in the other textbox.

DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
 <HTML
>
     <HEAD
>
         <title>Encodetitle
>
         <meta name="GENERATOR" Content
="Microsoft Visual Studio .NET 7.1">
         <meta name="CODE_LANGUAGE" Content
="C#">
         <meta name="vs_defaultClientScript" content
="JavaScript">
         <meta name="vs_targetSchema"
             content
="http://schemas.microsoft.com/intellisense/ie5">
         <script language
="javascript">
            

         script
>
     HEAD
>
     <body MS_POSITIONING
="FlowLayout">
         <form id="Form1" method="post" runat
="server">
             <P>Encoding TestP
>
             <P><INPUT id="TxtEncode" type="text" name="TxtEncode">
             <INPUT id="BtnEncode" title="Encode"
                     onclick
="DoEncode(document.Form1.TxtEncode.value)"
                     type="button" value="Encode" name="BtnEncode">
             <INPUT id="TxtResult" type="text" name
="TxtResult">
             <INPUT id="BtnDecode" onclick="DoDecode(document.Form1.TxtResult.value)"
                     type="button" value="Decode" name="BtnDecode">P
>
         form
>
     body
>
 HTML>

We can encode our data between client and server by combining JavaScript's escape and unescape methods, HttpUtility's UrlEncode and UrlDecode methods, and taking advantage that '*' isn't encoded in either.

1 comment: