JavaScript's encodeURI Function

For much of JavaScript's life, it was a browser-only programming language and could not run on the server-side like it can now. Because of this, JS has a lot of built-in functions that are specific to browser-side functions, like encoding strings for use in URLs. Some of the most commonly used functions are:

  • encodeURI
  • encodeURIComponent
  • decodeURI
  • decodeURIComponent
  • escape
  • unescape

The function that is the focus of this article, encodeURI, is used to encode a Uniform Resource Identifier (URI) so that characters not meant to be used in a URI (like a space) are formatted properly. These characters are escaped using percent-encoding, or URL encoding, to represent the non-standard URI characters.

Percent-encoding is simply a hexadecimal representation of the ASCII character prefixed with the percent (%) character. So, for example, the percent-encoding representation of the exclamation mark (!) is %21 since 21 is the ASCII hex number for the exclamation mark.

In terms of use-cases, let's say your website has a search bar and the queries entered there are used to construct a URL like this:

https://mysite.com/q=[SEARCH_QUERY]

In a use-case like this, it's pretty likely that the user will enter a string containing a space (or other reserved character), which isn't allowed in URLs. So what do we do if the user enters the string "web development", for example? We can't allow just any character in our URL. That's where encodeURI comes in:

> let query = 'web development';
> let searchUrl = 'https://mysite.com/q=' + query;
> encodeURI(searchUrl)
'https://mysite.com/q=web%20development'

Notice how the space has been replaced with the percent-encoding, %20. The encodeURI function is perfect for this because it doesn't escape any other reserved characters, like the colon or forward slash. This is because it expects to receive a full URL as input, unlike the encodeURIComponent variation of this function. The URL passed to encodeURI can contain any valid part of a URL scheme and not be escaped, while other reserved or disallowed characters are encoded:

> encodeURI('https://scott:[email protected]:443/my/file.html?stack=abuse#javascript')
'https://scott:[email protected]:443/my/file.html?stack=abuse#javascript'
> encodeURI('https://scott:[email protected]:443/my/file.html?stack="abuse"#javascript')
'https://scott:[email protected]n.example.com:443/my/file.html?stack=%22abuse%22#javascript'

Notice how there were no changes made to the URL in the first call above. This is because all characters are valid in a URL. In the second call we have a few quotation marks, which are not valid, and therefore encoded.

The following characters are not encoded by encodeURI, regardless of where they are located in the URL: A-Za-z0-9;,/?:@&=+$-_.!~*'()#

This function can even handle encoding non-ASCII characters using a longer UTF-8 based encoding. For example, the euro currency symbol (€) is encoded using three percent-encoding sets:

> encodeURI('€')
'%E2%82%AC'

This allows for characters from any language, or special formatting characters, to be passed via URLs.

Conclusion

JavaScript's built-in encodeURI function is useful for properly formatting URLs, or more generically, URIs with unreserved ASCII characters or even UTF-8 characters. It should be used any time user input is used in constructing a URL to ensure that it remains properly formatted.

On the other side of things, we also have the decodeURI built-in function, which handles decoding the percent-encoded values, which we'll take a look at in another article.