RFC 3986 Compliant URI Encoding in JavaScript
Friday, March 14th, 2008I spent some time yesterday reading up RFC’s on URI encoding for use with OAuth. More specifically, I was getting a handle on how different languages interpret and encode assorted character strings. What I learned is that JavaScript and PHP do not get along well. Even a benign string like “Hello world!” is not escaped consistently between languages.
In his article, Marc Worrell spells out in detail the differences between assorted encoding standards in PHP, Perl and Javascript as well as between different RFC’s. He even provides a great (and simple) function which escapes strings in PHP. I highly recommend taking a look at his page.
What he did not do was show the differences between encodeURIComponent() and escape() in Javascript. It turns out neither are compatible with RFC 3986, and more specifically, the “!” character caused me a bit of grief. Why is this important to OAuth? Because properly signed signatures require identical strings in the hashing alogrithm. Because “!” is not “%21″ a computed hash value would differ resulting in a nightmare when trying to validate signatures. As it turns out, encodeURIComponent() does a pretty good job, but there are a few other characters that are improperly escaped using the built in javascript function.
So I wrote a prototype method to handle the discrepancies and offer that here for folks who might require just such a method.
String.prototype.to_rfc3986 = function (){
var tmp = encodeURIComponent(this);
tmp = tmp.replace('!','%21');
tmp = tmp.replace('*','%2A');
tmp = tmp.replace('(','%28');
tmp = tmp.replace(')','%29');
tmp = tmp.replace("'",'%27');
return tmp;
}
Usage is very simple - when you require an encoded version of the string, simply call the to_rfc3986() method. You could easily make this a standalone function if you wanted.
var mystring = "Hello world!"; alert(mystring.to_rfc3986());