Encode URL in JavaScript?

1,727,259

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
Share:
1,727,259
nickf
Author by

nickf

Javascript nerd. Senior Software Engineer at Google. Ex-SoundClouder.

Updated on July 08, 2022

Comments

  • nickf
    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?

  • brady
    brady over 15 years
    The character encoding used with escape is variable. Stick with encodeURI and encodeURIComponent, which use UTF-8.
  • opteronn
    opteronn about 14 years
    Be careful. That escape converts non-ASCII characters into its Unicode escape sequences, like %uxxx.
  • kevzettler
    kevzettler over 13 years
    I am using encodeURIComponent and noticing it will not encode pipe characters |
  • nickf
    nickf about 13 years
    @kevzettler - why should it do that? The pipes aren't of semantic importance in a URI.
  • hitautodestruct
    hitautodestruct over 11 years
    How about adding the explanation @cms gave? escape is also a valid option.
  • Jochem Kuijpers
    Jochem Kuijpers over 11 years
    Please 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%20‌​has%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
    Ifnot about 11 years
    according to @CMS encodeURI is not really safe for URL encoding.
  • Buu
    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
    fiatjaf almost 11 years
    does anybody use non-ASCII characters in URIs?
  • Ryan Taylor
    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
    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
    fiatjaf over 10 years
    ah, ok, I thought you were talking about the domain/path parts, don't know why I thought this.
  • njzk2
    njzk2 almost 10 years
    I would replace in value rather than in the result of the encoding
  • Ryan Taylor
    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
    John N over 9 years
    encodeURIComponent() encoded the # and encodeURI() did not!
  • Thor84no
    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
    Maksym Kozlenko over 8 years
    I think that example provided is sufficient. If you need more information about $.param on api.jquery.com/jquery.param
  • Dzeimsas Zvirblis
    Dzeimsas Zvirblis over 8 years
    NOTE: 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
    Michał Perłakowski over 8 years
  • Brad Parks
    Brad Parks almost 8 years
    As mentioned in another answer on this page, this site nicely details the reason to use this method
  • node_saini
    node_saini over 7 years
    @BuuNguyen this does not work for me. I still see the my & as & in my terminal.
  • Venkaiah Yepuri
    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
    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 encode firstname then it will get resolved or not ? please suggest me something. Ty.
  • Cyril Duchon-Doris
    Cyril Duchon-Doris over 7 years
    Almost everyone uses jQuery and I feel more comfortable indeed with this instead of encoreURIComponent
  • germs12
    germs12 almost 7 years
    There are a lot of good sites out there that will let you play around with this: string-io.com is one.
  • xhienne
    xhienne about 5 years
    There 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
    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
    Gerard ONeill about 5 years
    Regardless 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
    Biiz almost 4 years
    i had to pass a +39123.. number with the plus symbol: the encodeURI() worked but my backend was not seeing it, while the encodeURIComponent() succeded (in angular 8 and asp.net core 3)
  • JohanTG
    JohanTG about 3 years
    qs great, compact and usefull package. Vote up for the qs on backend
  • Scotty Jamison
    Scotty Jamison almost 2 years
    NOTE: 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
    CodeToLife almost 2 years
    do 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 .