Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get firefox to not automatically url-decode values assigned to document.location.hash?

I'm using document.location.hash to preserve state on the page, and I'm putting url-encoded key value pairs up there, separated by "&" chars. So far so good.

However I'm running into an annoying problem on Firefox -- Firefox will quietly url-decode the hash value on the way in, so when you get it out later it's been decoded.

I can patch the problem by detecting when I'm running on firefox and calling encodeURIComponent on everything twice on the way in, but obviously that is hideous and I don't really want to do that.

Here's a simple example, where I encode "=" as "%3D", put it in the hash, and when I get it out later it's been turned back into "=" automatically:

// on the way in::
document.location.hash = "foo=" + encodeURIComponent("noisy=input");

//then later.....
// on the way out: 
var hash = document.location.hash;
kvPair = hash.split("=");

if (kvPair.length==2) {
    console.log("that is correct.")
} else if (kvPair.length==3) {
    console.log("oh hai firefox, this is incorrect")
}

I have my fingers crossed that there's maybe some hidden DOM element that firefox creates that represents the actual (un-decoded) hash value?

but bottom line -- has anyone run into this and found a better solution than just doing browser detection and calling encodeURIComponent twice on Firefox?

NOTE: several other questions I think have the same root cause. Most notably this one:

https://stackoverflow.com/questions/4834609/malformed-uri-in-firefox-not-ie-using-encodeuricomponenet-and-setting-hash

like image 754
nmealy Avatar asked Apr 26 '11 23:04

nmealy


1 Answers

I would strongly advise against using the hash value to preserve the state. Hash is supposed to point to object's fragment-id, as explained in RFC 1630

This represents a part of, fragment of, or a sub-function within, an object. (...) The fragment-id follows the URL of the whole object from which it is separated by a hash sign (#).

Is there anything stopping you from using cookies to preserve the state? Cookies are simple enough to use in JS, described on Geko DOM Reference pages, and would do the trick quietly, without appending values to the URL which is never pretty.

If you absolutely have to use hash though, you may want to consider replacing '=' with some other character, e.g. ":".

like image 110
Jacek Ciolek Avatar answered Oct 20 '22 00:10

Jacek Ciolek