When are you supposed to use escape instead of encodeURI / encodeURIComponent?
escape()
Don't use it!escape()
is defined in section B.2.1.2 escape and the introduction text of Annex B says:
... All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. ...
... Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code....
Behaviour:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape
Special characters are encoded with the exception of: @*_+-./
The hexadecimal form for characters, whose code unit value is 0xFF or less, is a two-digit escape sequence: %xx
.
For characters with a greater code unit, the four-digit format %uxxxx
is used. This is not allowed within a query string (as defined in RFC3986):
query = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
A percent sign is only allowed if it is directly followed by two hexdigits, percent followed by u
is not allowed.
encodeURI()
Use encodeURI when you want a working URL. Make this call:
encodeURI("http://www.example.org/a file with spaces.html")
to get:
http://www.example.org/a%20file%20with%20spaces.html
Don't call encodeURIComponent since it would destroy the URL and return
http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html
Note that encodeURI, like encodeURIComponent, does not escape the ' character.
encodeURIComponent()
Use encodeURIComponent when you want to encode the value of a URL parameter.
var p1 = encodeURIComponent("http://example.org/?a=12&b=55")
Then you may create the URL you need:
var url = "http://example.net/?param1=" + p1 + "¶m2=99";
And you will get this complete URL:
http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55¶m2=99
Note that encodeURIComponent does not escape the '
character. A common bug is to use it to create html attributes such as href='MyUrl'
, which could suffer an injection bug. If you are constructing html from strings, either use "
instead of '
for attribute quotes, or add an extra layer of encoding ('
can be encoded as %27).
For more information on this type of encoding you can check: http://en.wikipedia.org/wiki/Percent-encoding
Should I use encodeURI or encodeURIComponent for encoding URLs?
It depends on what you are actually wanting to do.
encodeURI assumes that the input is a complete URI that might have some characters which need encoding in it.
encodeURIComponent will encode everything with special meaning, so you use it for components of URIs such as
var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);
encodeURI doesn't escape `equals` - why?
encodeURI
encodes a full URI, and URIs can contain =
characters. For instance, if a user types in a URI, a first step to resolve it would be to call encodeURI
on it.
If on the other hand you are the one constructing the URI, and the input just determines one field (for instance a search query, when given E=mc²
you want to resolve https://www.google.com/search?q=E%3Dmc%C2%B2
), then you are not encoding a full URI, but a URI component. Use encodeURIComponent
for that:
> encodeURIComponent('= ')
'%3D%20'
javascript escape vs urlencode of non-ascii strings
escape()
will not encode:@*/+
encodeURI()
will not encode:~!@#$&*()=:/,;?+'
encodeURIComponent()
will not encode:~!*()'
For more information, have a look at these questions:
Encode URL in JavaScript?
When are you supposed to use escape instead of encodeURI / encodeURIComponent?
Using encodeURI() vs. escape() for utf-8 strings in JavaScript
Hi!
When it comes to escape
and unescape
, I live by two rules:
- Avoid them when you easily can.
- Otherwise, use them.
Avoiding them when you easily can:
As mentioned in the question, both escape
and unescape
have been deprecated. In general, one should avoid using deprecated functions.
So, if encodeURIComponent
or encodeURI
does the trick for you, you should use that instead of escape
.
Using them when you can't easily avoid them:
Browsers will, as far as possible, strive to achieve backwards compatibility. All major browsers have already implemented escape
and unescape
; why would they un-implement them?
Browsers would have to redefine escape
and unescape
if the new specification requires them to do so. But wait! The people who write specifications are quite smart. They too, are interested in not breaking backwards compatibility!
I realize that the above argument is weak. But trust me, ... when it comes to browsers, deprecated stuff works. This even includes deprecated HTML tags like <xmp>
and <center>
.
Using escape
and unescape
:
So naturally, the next question is, when would one use escape
or unescape
?
Recently, while working on CloudBrave, I had to deal with utf8
, latin1
and inter-conversions.
After reading a bunch of blog posts, I realized how simple this was:
var utf8_to_latin1 = function (s) {
return unescape(encodeURIComponent(s));
};
var latin1_to_utf8 = function (s) {
return decodeURIComponent(escape(s));
};
These inter-conversions, without using escape
and unescape
are rather involved. By not avoiding escape
and unescape
, life becomes simpler.
Hope this helps.
Related Topics
How to Append Something to an Array
Pretty-Print Json Using JavaScript
Selecting Text in an Element (Akin to Highlighting With Your Mouse)
How Does Data Binding Work in Angularjs
How to Detect Page Zoom Level in All Modern Browsers
Cloud Functions For Firebase Trigger on Time
How to Replace a Character At a Particular Index in JavaScript
JavaScript or (||) Variable Assignment Explanation
Origin Is Not Allowed by Access-Control-Allow-Origin
How to Make Setinterval Also Work When a Tab Is Inactive in Chrome
Insert HTML into View from Angularjs Controller
How to Deep Merge Instead of Shallow Merge
Calling Functions With Settimeout()