history.js
history.js copied to clipboard
Using encodeURI() instead of escape()
Hi,
v1.7, I was wondering if you foresee any problems with changing line 1004 from:
tmp = window.unescape(result); to: tmp = window.decodeURI(result);
and 1114 from:
result = window.escape(result); to: result = window.encodeURI(result);
When using URLs with Unicode in them, I was encountering errors in Chrome and Firefox. In Chrome, if I would encodeURI() the unicode part of the URL that I passed to History.js, it would look corrupt in the location bar. In Firefox, using the straight unicode or encoding it would cause History.js to stop updating the location bar hashtag once it hit a URL with unicode in it. I'm not sure if my fix is correct, but it seems to be working as I desire in both Chrome and Firefox, so I wanted to see if you think this presents any issues?
Thanks,
Matt
Thanks Matt, that is a good point. I'll make the change and see if it breaks anything.
Thanks for looking into it. I didn't want to just issue a pull request because I really didn't do in-depth testing with odd/special characters, it just seemed to work better for my URL format (unicode characters included).
In dev as of https://github.com/balupton/history.js/commit/c79c17f9801373f5218f144088c387f1935f3462 - still need to test.
This improvement is making problem with URL in ISO. [un]escape() is for ISO url, [encode/decode]URI(Component) is for UTF 8 I'me having issue because I use this with ISO encoded URL (I've accent which are not escaped the same way). Maybe you should had a option like I recently did in a tool I made to manipulate URI. I put it on Github if U wanna take a look. https://github.com/MoOx/Url.js
Here is another way to see the problem (check source) http://www.albionresearch.com/misc/urlencode.php
+1 to issue
@mattwright, thanks! Your fix (use encodeURI instead escape) helps me with cyrillic symbols.
I made this change as well when trying to chase down another issue and so far haven't experienced any ill-effects.
You may care, that there's a problem with this solution if you have a percentage sign in the url.
I'm now testing the following solution which seems to work fine:
tmp = window.decodeURIComponent(window.escape(result));
*sorry, my nervous fingers deleted the post before ;-)
What's the status of getting this fix into a release version of History.js? It's still a bug in the latest release.
Solved it this way:
<script src="/js/native.history.js"></script>
<script>
// escape -> encodeURI, unescape -> decodeURI
History.unescapeString = function(str) {
var result = str, tmp;
while ( true ) {
tmp = window.decodeURI(result);
if ( tmp === result ) {
break;
}
result = tmp;
}
return result;
};
History.escapeHash = function(hash) {
var result = History.normalizeHash(hash);
result = window.encodeURI(result);
if ( !History.bugs.hashEscape ) {
result = result
.replace(/\%21/g,'!')
.replace(/\%26/g,'&')
.replace(/\%3D/g,'=')
.replace(/\%3F/g,'?');
}
return result;
};
</script>
Anyway, why not let user decide whether to unescape url passed to pushState
via pushState
's parameters or History.options
?
The problem with this approach is that at least History.getState().url
is already "unescaped" the moment I try to fix these functions, that is History.getState().url != location.href
. And probably there are other issues to come.