Encode URL in JavaScript?
Solution 1
Check out the built-in function encodeURIComponent(str) and encodeURI(str).
In your case, this should work:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
Solution 2
You have three options:
-
escape()
will not encode:@*/+
-
encodeURI()
will not encode:~!@#$&*()=:/,;?+'
-
encodeURIComponent()
will not encode:~!*()'
But in your case, if you want to pass a URL into a GET
parameter of other page, you should use escape
or encodeURIComponent
, but not encodeURI
.
See Stack Overflow question Best practice: escape, or encodeURI / encodeURIComponent for further discussion.
Solution 3
Stick with encodeURIComponent()
. The function encodeURI()
does not bother to encode many characters that have semantic importance in URLs (e.g. "#", "?", and "&"). escape()
is deprecated, and does not bother to encode "+" characters, which will be interpreted as encoded spaces on the server (and, as pointed out by others here, does not properly URL-encode non-ASCII characters).
There is a nice explanation of the difference between encodeURI()
and encodeURIComponent()
elsewhere. If you want to encode something so that it can safely be included as a component of a URI (e.g. as a query string parameter), you want to use encodeURIComponent()
.
Solution 4
The best answer is to use encodeURIComponent
on values in the query string (and nowhere else).
However, I find that many APIs want to replace " " with "+" so I've had to use the following:
const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value
escape
is implemented differently in different browsers and encodeURI
doesn't encode many characters (like # and even /) -- it's made to be used on a full URI/URL without breaking it – which isn't super helpful or secure.
And as @Jochem points out below, you may want to use encodeURIComponent()
on a (each) folder name, but for whatever reason these APIs don't seem to want +
in folder names so plain old encodeURIComponent
works great.
Example:
const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
Solution 5
I would suggest to use qs npm package
qs.stringify({a:"1=2", b:"Test 1"}); // gets a=1%3D2&b=Test+1
it is easier to use with JS object and it gives you proper URL encoding for all parameters
If you are using jQuery I would go for $.param
method. It URL encodes an object mapping fields to values, which is easier to read than calling an escape method on each value.
$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1
nickf
Javascript nerd. Senior Software Engineer at Google. Ex-SoundClouder.
Updated on July 08, 2022Comments
-
nickf almost 2 years
How do you safely encode a URL using JavaScript such that it can be put into a GET string?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2"; var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
I assume that you need to encode the
myUrl
variable on that second line?-
Shoaib over 15 yearsTry looking into encodeURI() and decodeURI().
-
Yanni almost 13 years
-
phillihp over 11 yearsYou can use this tool here: phillihp.com/toolz/url-encode-decode
-
Andrew about 6 yearsencodeURIComponent()
-
iron9 almost 3 yearsPlease go see this answer as it is the only one using modern javascript features (supported in anything but Internet Explorer).
-
-
brady over 15 yearsThe character encoding used with escape is variable. Stick with encodeURI and encodeURIComponent, which use UTF-8.
-
opteronn about 14 yearsBe careful. That escape converts non-ASCII characters into its Unicode escape sequences, like
%uxxx
. -
kevzettler over 13 yearsI am using encodeURIComponent and noticing it will not encode pipe characters |
-
nickf about 13 years@kevzettler - why should it do that? The pipes aren't of semantic importance in a URI.
-
hitautodestruct over 11 yearsHow about adding the explanation @cms gave?
escape
is also a valid option. -
Jochem Kuijpers over 11 yearsPlease note, you should only replace %20 with + symbols after the first question mark (which is the 'query' part of the URL). Let's say I want to browse to
http://somedomain/this dir has spaces/info.php?a=this has also spaces
. It should be converted to:http://somedomain/this%20dir%20has%spaces/info.php?a=this%20has%20also%20spaces
but many implementations allow '%20' in the querystring to be replaced by '+'. Nevertheless, you cannot replace '%20' with '+' in the path-section of the URL, this will result in a Not Found error unless you have a directory with a+
instead of a space. -
Ifnot about 11 yearsaccording to @CMS
encodeURI
is not really safe for URL encoding. -
Buu about 11 years@AnaelFavre because it is meant to encode the whole URL, which doesn't allow characters such as
:
,/
,@
etc. These 2 methods are not to be used interchangeable, you must know what you are encoding to use the right method. -
fiatjaf almost 11 yearsdoes anybody use non-ASCII characters in URIs?
-
Ryan Taylor almost 11 years@Jochem Kuijpers, definitely, you wouldn't put "+" in a directory. I'd only apply this to the query parameter values themselves (or keys if needed), not the entire URL, or even the entire query string.
-
Tseng over 10 years@GiovanniP: People who allow German, French, Japanese, Chinese, Arabic characters as input and pass theses parameters via GET or POST.
-
fiatjaf over 10 yearsah, ok, I thought you were talking about the domain/path parts, don't know why I thought this.
-
njzk2 almost 10 yearsI would replace in value rather than in the result of the encoding
-
Ryan Taylor almost 10 years@njzk2 unfortunately
encodeURIComponent('+')
would give you%2B
, so you'd have to use two regular expressions... which I suppose is kinda why this works, because '+' are ' ' are encoded differently in the end. -
John N over 9 years
encodeURIComponent()
encoded the#
andencodeURI()
did not! -
Thor84no over 9 years@fiatjaf Non-ASCII characters are perfectly legitimate in domains as well, though there will be an ASCII version stored in the DNS system. en.wikipedia.org/wiki/Internationalized_domain_name
-
Maksym Kozlenko over 8 yearsI think that example provided is sufficient. If you need more information about $.param on api.jquery.com/jquery.param
-
Dzeimsas Zvirblis over 8 yearsNOTE: as of JavaScript version 1.5 escape() has been deprecated. Stick with either encodeURI() or encodeComponent(). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
Michał Perłakowski over 8 years
-
Brad Parks almost 8 yearsAs mentioned in another answer on this page, this site nicely details the reason to use this method
-
node_saini over 7 years@BuuNguyen this does not work for me. I still see the my & as & in my terminal.
-
Venkaiah Yepuri over 7 years@BuuNguyen : Hi BuuNguyen, thanks for useful solution. can please confirm me ? may I use encodeURIComponent() method for plain string encoding becuase in my application I am appending string content directly as a value to query string key then its leading XSS issue. its my code
var mywindow = window .open( "https://" + window.location.host + "center/js/cal.html?context=" + conString + "&date=" + dateString + "&firstName=" + firstName);
-
Venkaiah Yepuri over 7 years@BuuNguyen : Now its saying
&firstName
could be cause the XSS issue. Now what I have to do ? if I do encodefirstname
then it will get resolved or not ? please suggest me something. Ty. -
Cyril Duchon-Doris over 7 yearsAlmost everyone uses jQuery and I feel more comfortable indeed with this instead of encoreURIComponent
-
germs12 almost 7 yearsThere are a lot of good sites out there that will let you play around with this: string-io.com is one.
-
xhienne about 5 yearsThere is no reason to translate %20 to "+". The valid escape sequence for ASCII space is %20, not "+" which is not mentioned in RFC 3986 (tools.ietf.org/html/rfc3986). "+" was used in the 1990s; it is obsolete now and is only supported for legacy reasons. Don't use it.
-
Ryan Taylor about 5 years@xhienne for sure, it's just something i've noticed in the real world on a few APIs, it would always make more sense to use
encodeURIComponent
when that works – would be nice if people could stick to one standard! And preferably the RFC spec. -
Gerard ONeill about 5 yearsRegardless if its a + or a %20, decoding the component should know how to interpret either value and produce a space. It is only specs such as oauth that require encoded strings within its spec where it makes a difference.
-
Biiz almost 4 yearsi had to pass a
+39123..
number with the plus symbol: theencodeURI()
worked but my backend was not seeing it, while theencodeURIComponent()
succeded (in angular 8 and asp.net core 3) -
JohanTG about 3 yearsqs great, compact and usefull package. Vote up for the qs on backend
-
Scotty Jamison almost 2 yearsNOTE: encodeURIComponent is only intended to be used on a URL's path. Query parameters follow an older percent-encoding specification which expects spaces to be encoded as "+" instead of "%20". See this S.O. question to learn more. Some servers may be lenient with this incorrect encoding, but your mileage may vary. In modern JavaScript, I would recommend encoding via URL or URLSearchParams as this answer recommends.
-
CodeToLife almost 2 yearsdo not listen to misleading comments and dont waste your time >-( ,
escape()
is, as it turns out, just perfect ! Have only manually filtered those 4 chars .