Reputation: 4605
I am encoding a string that will be passed in a URL (via GET). But if I use escape
, encodeURI
or encodeURIComponent
, &
will be replaced with %26amp%3B
, but I want it to be replaced with %26
. What am I doing wrong?
Upvotes: 309
Views: 443393
Reputation: 61401
There is HTML and URI encodings. &
is &
encoded in HTML while %26
is &
in URI encoding.
So before URI encoding your string you might want to HTML decode and then URI encode it :)
var div = document.createElement('div');
div.innerHTML = '&AndOtherHTMLEncodedStuff';
var htmlDecoded = div.firstChild.nodeValue;
console.log('htmlDecoded: '+htmlDecoded);
var urlEncoded = encodeURIComponent(htmlDecoded);
console.log('urlEncoded: '+urlEncoded);
result %26AndOtherHTMLEncodedStuff
Hope this saves you some time
Upvotes: 8
Reputation: 344575
Without seeing your code, it's hard to answer other than a stab in the dark. I would guess that the string you're passing to encodeURIComponent()
, which is the correct method to use, is coming from the result of accessing the innerHTML
property. The solution is to get the innerText/textContent property value instead:
var str,
el = document.getElementById("myUrl");
if ("textContent" in el)
str = encodeURIComponent(el.textContent);
else
str = encodeURIComponent(el.innerText);
If that isn't the case, you can usethe replace() method to replace the HTML entity:
encodeURIComponent(str.replace(/&/g, "&"));
Upvotes: 450
Reputation: 20881
Just to be clear, you should never be using encodeURI()
and encodeURIComponent()
. If you disagree, just look at its results...
console.log(encodeURIComponent('@#$%^&*'));
Input:
^&*
.Output:
%40%23%24%25%5E%26*
.
That's not right, is it? *
did not get converted! I hope you're not using this as a server-side cleansing function, because *
will not be treated as input but as commands, i.e., imagine deleting a user's alleged file with rm *
. Well, I hope you're not using encodeURI() or encodeURIComponent()!
TLDR: You actually want fixedEncodeURIComponent()
and fixedEncodeURI()
.
MDN encodeURI() Documentation...
function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); }
MDN encodeURIComponent() Documentation...
function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }
With these functions, use fixedEncodeURI()
to encode a single URL piece, whereas fixedEncodeURIComponent()
will encode URL pieces and connectors; or, more simply, fixedEncodeURI()
will not encode +@?=:#;,$&
(as &
and +
are common URL operators), but fixedEncodeURIComponent()
will.
Upvotes: -1
Reputation: 630429
If you did literally this:
encodeURIComponent('&')
Then the result is %26
, you can test it here. Make sure the string you are encoding is just &
and not &
to begin with...otherwise it is encoding correctly, which is likely the case. If you need a different result for some reason, you can do a .replace(/&/g,'&')
before the encoding.
Upvotes: 104