'Second unwanted call made to browser history in JS
In my application, I need to redirect using browserHistory created from this package. In order to pass some context, I need to add a query string to the URL. The format in which I receive these params is in JSON. So before being able to call history.push, I first need to stringify and encode the given JSON.
Here's an example:
import { createBrowserHistory } from 'history';
const browserHistory = createBrowserHistory({ window });
const given = { x: 1 };
browserHistory.push(`/foo?test-param=${encodeURIComponent(JSON.stringify(given))}`);
This redirection works...BUT it breaks the native browser back button (sort of). You see what happens is that encodeURIComponent(JSON.stringify(given)) outputs %7B%22x%22%3A1%7D. As soon as the browser sees the %3A part, it automatically changes it into a : in the URL bar. This causes an additional change in the browserHistory, meaning that two URL changes happened:
/foo?test-param=%7B%22x%22%3A1%7Dwhich is the wanted outcome generated by the above code/foo?test-param=%7B%22x%22:1%7Dwhich is automatically done by the browser (decoding%3A)
The issue now is that when I press the browser's back button, it tries to go to the second last URL which is the one given in step 1 above and not the original referrer URL. This then re-triggers a conversion to step 2. So the only way to get back to the referral URL is to hit the back button 2 times in quick succession.
Has anybody encountered this before?
PS: If I opt for encodeURI instead of encodeURIComponent above, it works. The reason for this is that encodeURI does not encode : to begin with.
Solution 1:[1]
If this is going in Emails, and the URL want to have JSON embeded somehow, I would use Hex. This should avoid any conflicts with special chars..
eg..
const given = { x: 1 };
const toHex = s => [...new TextEncoder().encode(s)].map(m => m.toString(16)).join('');
const fromHex = h =>
(new TextDecoder()).decode(
new Uint8Array(
h.match(/.{1,2}/g).map(v => parseInt(v, 16))));
const url = `/foo?testparam=${toHex(JSON.stringify(given))}`;
console.log(url);
console.log(JSON.parse(fromHex('7b2278223a317d')));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Keith |
