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 themyUrl variable on that second line?
- 36Try looking intoencodeURI() anddecodeURI().Zack The Human– Zack The Human2008-12-02 02:39:29 +00:00CommentedDec 2, 2008 at 2:39
- 1SeeJavaScript urlencode function.Yanni– Yanni2011-06-30 16:40:38 +00:00CommentedJun 30, 2011 at 16:40
- 1You can use this tool here:phillihp.com/toolz/url-encode-decodephillihp– phillihp2012-09-18 02:13:19 +00:00CommentedSep 18, 2012 at 2:13
- 4
- 1Please go seethis answer as it is the only one using modern javascript features (supported in anything but Internet Explorer).iron9– iron92021-06-02 09:44:12 +00:00CommentedJun 2, 2021 at 9:44
22 Answers22
Check out the built-in functionencodeURIComponent(str) andencodeURI(str).
In your case, this should work:
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);13 Comments
escape is also a valid option.encodeURI is not really safe for URL encoding.:,/,@ etc. These 2 methods are not to be used interchangeable, you must know what you are encoding to use the right method.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 aURL into aGET parameter of other page, you should useescape orencodeURIComponent, but notencodeURI.
See Stack Overflow questionBest practice: escape, or encodeURI / encodeURIComponent for further discussion.
10 Comments
%uxxx.Stick withencodeURIComponent(). The functionencodeURI() 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 niceexplanation of the difference betweenencodeURI() andencodeURIComponent() 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 useencodeURIComponent().
Comments
The best answer is to useencodeURIComponent onvalues in the query string (and nowhere else).
However, I find that many older APIs want to replace " " with "+" so I've had to use the following:
const value = encodeURIComponent(value).replaceAll('%20','+');const url = 'http://example.com?lang=en&key=' + valueescape is implemented differently in different browsers andencodeURI 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 useencodeURIComponent() on a (each) folder name, but for whatever reason these APIs don't seem to want+ in folder names so plain oldencodeURIComponent works great.
Example:
const escapedValue = encodeURIComponent(value).replaceAll('%20','+');const escapedFolder = encodeURIComponent('My Folder'); // no replaceconst url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;8 Comments
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.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.Modern solution (2021)
Since the other answers were written, theURLSearchParams API has been introduced. It can be used like this:
const queryParams = { param1: 'value1', param2: 'value2' }const queryString = new URLSearchParams(queryParams).toString()// 'param1=value1¶m2=value2'It also encodes non-URL characters.
For your specific example, you would use it like this:
const myUrl = "http://example.com/index.html?param=1&anotherParam=2";const myOtherUrl = new URL("http://example.com/index.html");myOtherUrl.search = new URLSearchParams({url: myUrl});console.log(myOtherUrl.toString());
1 Comment
%20 instead of+) was solved by using.toString() on the URLSearchParamsI would suggest to use theqs npm package:
qs.stringify({a:"1=2", b:"Test 1"}); // gets a=1%3D2&b=Test+1It is easier to use with a JavaScript object and it gives you the proper URL encoding for all parameters.
If you are using jQuery, I would go for the$.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+13 Comments
I think now in 2022 to be really safe, you should always consider constructing your URLs using theURL() interface. It'll do most of the job for you. So coming to your code,
const baseURL = 'http://example.com/index.html';const myUrl = new URL(baseURL);myUrl.searchParams.append('param', '1');myUrl.searchParams.append('anotherParam', '2');const myOtherUrl = new URL(baseURL);myOtherUrl.searchParams.append('url', myUrl.href);console.log(myUrl.href);// Outputs: http://example.com/index.html?param=1&anotherParam=2console.log(myOtherUrl.href);// Outputs: http://example.com/index.html?url=http%3A%2F%2Fexample.com%2Findex.html%3Fparam%3D1%26anotherParam%3D2console.log(myOtherUrl.searchParams.get('url'));// Outputs: http://example.com/index.html?param=1&anotherParam=2Or...
const params = new URLSearchParams(myOtherUrl.search);console.log(params.get('url'));// Outputs: http://example.com/index.html?param=1&anotherParam=2Something like this is assured not to fail.
Comments
encodeURIComponent() is the way to go.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);But you should keep in mind that there are small differences from PHP versionurlencode() and as @CMS mentioned, it will not encode every character. Guys athttp://phpjs.org/functions/urlencode/ made JavaScript equivalent tophpencode():
function urlencode(str) { str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. return encodeURIComponent(str) .replace('!', '%21') .replace('\'', '%27') .replace('(', '%28') .replace(')', '%29') .replace('*', '%2A') .replace('%20', '+');}Comments
To encode a URL, as has been said before, you have two functions:
encodeURI()and
encodeURIComponent()The reason both exist is that the first preserves the URL with the risk of leaving too many things unescaped, while the second encodes everything needed.
With the first, you could copy the newly escaped URL into address bar (for example) and it would work. However your unescaped '&'s would interfere with field delimiters, the '='s would interfere with field names and values, and the '+'s would look like spaces. But for simple data when you want to preserve the URL nature of what you are escaping, this works.
The second is everything you need to do to make sure nothing in your string interfers with a URL. It leaves various unimportant characters unescaped so that the URL remains as human readable as possible without interference. A URL encoded this way will no longer work as a URL without unescaping it.
So if you can take the time, you always want to use encodeURIComponent() -- before adding on name/value pairs encode both the name and the value using this function before adding it to the query string.
I'm having a tough time coming up with reasons to use the encodeURI() -- I'll leave that to the smarter people.
Comments
What is URL encoding:
A URL should be encoded when there are special characters located inside the URL. For example:
console.log(encodeURIComponent('?notEncoded=&+'));We can observe in this example that all characters except the stringnotEncoded are encoded with % signs. URL encoding is also known aspercentage encoding because it escapes all special characters with a %. Then after this % sign every special character has a unique code
Why do we need URL encoding:
Certain characters have a special value in a URL string. For example, the ? character denotes the beginning of a query string. In order to successfully locate a resource on the web, it is necessary to distinguish between when a character is meant as a part of string or part of the URL structure.
How can we achieve URL encoding in #"js" data-hide="false" data-console="true" data-babel="false">// for a whole URI don't use encodeURIComponent it will transform// the / characters and the URL won't fucntion properlyconsole.log(encodeURIComponent("http://www.random.com/specials&char.html"));// instead use encodeURI for whole URL'sconsole.log(encodeURI("http://www.random.com/specials&char.html"));
// for a whole URI don't use encodeURIComponent it will transform// the / characters and the URL won't fucntion properlyconsole.log(encodeURIComponent("http://www.random.com/specials&char.html"));// instead use encodeURI for whole URL'sconsole.log(encodeURI("http://www.random.com/specials&char.html"));We can observe f we put the whole URL inencodeURIComponent that the forward slashes (/) are also converted to special characters. This will cause the URL to not function properly anymore.
Therefore (as the name implies) use:
encodeURIComponenton a certain part of a URL which you want to encode.encodeURIon a whole URL which you want to encode.
Comments
To prevent double encoding, it's a good idea to decode the URL before encoding (if you are dealing with user entered URLs for example, which might be already encoded).
Let’s say we haveabc%20xyz 123 as input (one space is already encoded):
encodeURI("abc%20xyz 123") // Wrong: "abc%2520xyz%20123"encodeURI(decodeURI("abc%20xyz 123")) // Correct: "abc%20xyz%20123"Comments
You should not useencodeURIComponent() directly.
Take a look at RFC3986: Uniform Resource Identifier (URI): Generic Syntax
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"/ "*" / "+" / "," / ";" / "="
The purpose of reserved characters is to provide a set of delimiting characters that are distinguishable from other data within a URI.
These reserved characters from the URI definition in RFC3986 ARE NOT escaped byencodeURIComponent().
MDN Web Docs: encodeURIComponent()
To be more stringent in adhering to RFC 3986 (which reserves !, ', (, ), and *), even though these characters have no formalized URI delimiting uses, the following can be safely used:
Use the MDN Web Docs function...
function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); });}Comments
A similar kind of thing I tried with normal #"dateCreated" datetime="2013-05-14 06:48:44Z">














