- I have some legacy code (pre-React) that encodes part of a URL with
encodeURIComponent
before callinghistory.push()
on the https://www.npmjs.com/package/history module in order to navigate to that URL. history.push()
insidehistory.js
then usesdecodeURI
to decode the entire URL partially (decodeURI
only decodes the same characters thatencodeURI
encodes)- this partially decoded location.pathname ends up in ReactRouter where
useParams()
gives me the partially decoded URL component back again.
Now I'm stuck with a partially decoded URL component which I cannot use. I need it fully decoded.
I can't use decodeURIComponent
on the partially decoded string, because the original string might contain a %
, in which case this %
will already be decoded in the partially decoded string and this would cause decodeURIComponent
to crash with a Uncaught URIError: URI malformed
.
My options seem to be:
- use
unescape
to fully decode the partially decoded string (it doesn't complain about the single%
) even though its use is discouraged (why?) - manually re-encode any
%
(that isn't followed by a digit and a subsequent hex character) back to%25
and then run the result throughdecodeURIComponent
Are there any less ugly solutions that I haven't thought of yet ?
EDIT : I was asked for examples of what I meant by partially decided string
const original = 'A-Za-z0-9;,/?:@&=+$-_.!~*()#%';
const encodedURIComponent = encodeURIComponent(original); // "A-Za-z0-9%3B%2C%2F%3F%3A%40%26%3D%2B%24-_.!~*()%23%25"
console.log(decodeURIComponent(encodedURIComponent)); // "A-Za-z0-9;,/?:@&=+$-_.!~*()#%"
const partiallyUnescaped = decodeURI(encodedURIComponent); // "A-Za-z0-9%3B%2C%2F%3F%3A%40%26%3D%2B%24-_.!~*()%23%" - notice the '%25' at the end was decoded back to '%'
console.log(unescape(partiallyUnescaped)); // "A-Za-z0-9;,/?:@&=+$-_.!~*()#%"
//console.log(decodeURIComponent(partiallyUnescaped)); // error
EDIT 2: In case it can be of any help, here's a more realistic example of some of the characters our URL might contain, but because it's user generated, it could be anything really:
console.log( encodeURIComponent('abcd+%;- efgh')) ; // "abcd%2B%25%3B-%20efgh"
console.log( decodeURI(encodeURIComponent('abcd+%; -efgh'))) ; // "abcd%2B%%3B- efgh"
//console.log(decodeURIComponent(decodeURI(encodeURIComponent('abcd+%; -efgh')))); // Error: URI malformed