Когда вы должны использовать escape вместо encodeURI / encodeURIComponent?

При кодировании строки запроса для отправки на веб-сервер - когда вы используете escape()и когда вы используете encodeURI()или encodeURIComponent():

Используйте escape:

escape("% +&=");

ИЛИ

используйте encodeURI () / encodeURIComponent ()

encodeURI("http://www.google.com?var1=value1&var2=value2");

encodeURIComponent("var1=value1&var2=value2");
16.09.2008 19:24:34
Стоит отметить, что encodeURIComponent("var1=value1&var2=value2")это не типичный вариант использования. Этот пример закодирует =и &, что, вероятно, не то, что предполагалось! encodeURIComponentобычно применяется отдельно только к значению в каждой паре ключ-значение (часть после каждого =).
Timothy Shields 14.03.2014 20:45:44
тебе нужно что-нибудь сделать с ключом? Что если в нем есть =? (это вообще возможно?)
Mala 9.06.2014 21:49:05
@Mala Я все еще новичок в веб-программировании в целом, но то, что я использовал в своем ограниченном опыте, заключается в том, чтобы кодировать ключ и значение отдельно, гарантируя, что '=' остается: var params = encodeURIComponent(key) + '=' + encodeURIComponent(value);- Возможно, кто-то другой знает лучший способ.
nedshares 28.06.2014 21:17:44
@nedshares Я играл с этим, но, насколько я могу судить, ключ, кажется, не закодирован ... по крайней мере, не так. Может быть, против спецификации иметь = в ключе?
Mala 1.07.2014 20:08:53
Также стоит отметить, что последние реализации JavaScript предоставляют интерфейсы более высокого уровня URL и URLSearchParams для управления URL-адресами и их строками запроса.
Bart Robinson 6.12.2017 00:07:58
14 ОТВЕТОВ
РЕШЕНИЕ

побег()

Не используйте это! escape()определено в разделе В.2.1.2 побег, а во вводном тексте Приложения В говорится:

... 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

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 + "&param2=99";

And you will get this complete URL:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=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).

Для получения дополнительной информации об этом типе кодировки вы можете проверить: http://en.wikipedia.org/wiki/Percent-encoding

1909
6.08.2018 06:36:54
@Francois, в зависимости от принимающего сервера, может некорректно декодировать, как escape кодирует верхние символы ASCII или не-ASCII, такие как: • Например, класс Python FieldStorage не будет правильно декодировать вышеуказанную строку, если закодирован пока escape.
Ray 20.04.2011 23:22:40
@Francois escape () кодирует нижние 128 символов ASCII, кроме букв, цифр и *@-_+./, тогда как unescape () является обратным к escape (). Насколько я могу судить, это унаследованные функции, предназначенные для кодирования URL-адресов и все еще реализованные для обратной совместимости. Как правило, их не следует использовать, если они не взаимодействуют с приложением / веб-службой / и т. Д., Предназначенными для них.
Anthony DiSanti 12.07.2011 19:03:26
Если, конечно, вы не пытаетесь передать URL как компонент URI, в этом случае вызовите encodeURIComponent.
tom 12.12.2012 19:41:31
Почему он не обрабатывает одинарные кавычки?
Eric 15.10.2013 22:46:24
@Eric It does not encode single-quote, because single-quote is a completely valid character to occur within a URI (RFC-3986). The problem occurs when you embed a URI within HTML, where single-quote is not a valid character. It follows then, that URIs should also be "HTML-encoded" (which would replace ' with ') before being placed into an HTML document.
Lee 26.06.2014 03:02:08

encodeURI() - the escape() function is for javascript escaping, not HTTP.

38
16.09.2008 19:26:22
If i have a url like this: var url = "http://kuler-api.adobe.com/rss/get.cfm?startIndex=0&itemsPerPage=20&timeSpan=0&listType=rating"... And I want to access it via the Google Ajax API, like this: var gurl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q=" + url;... then I have to use escape(url). encodeURI(url) doesn't work with parameters like that it seems.
Lance Pollard 11.07.2010 00:47:35
u should use ecnodeURIComponent(url)
Ustaman Sangat 2.05.2012 17:22:34
All the 3 functions have their issues. It's better to create your own function which does the job.
Jerry Joseph 23.04.2014 16:59:16

Также помните, что все они кодируют разные наборы символов, и выберите тот, который вам нужен. encodeURI () кодирует меньше символов, чем encodeURIComponent (), который кодирует меньше (и отличается от точки Данипа) символов, чем escape ().

10
16.09.2008 19:40:32

Я нашел эту статью поучительной: Javascript Madness: запрос разбора строк

Я обнаружил это, когда пытался понять, почему decodeURIComponent неправильно декодировал «+». Вот выдержка:

String:                         "A + B"
Expected Query String Encoding: "A+%2B+B"
escape("A + B") =               "A%20+%20B"     Wrong!
encodeURI("A + B") =            "A%20+%20B"     Wrong!
encodeURIComponent("A + B") =   "A%20%2B%20B"   Acceptable, but strange

Encoded String:                 "A+%2B+B"
Expected Decoding:              "A + B"
unescape("A+%2B+B") =           "A+++B"       Wrong!
decodeURI("A+%2B+B") =          "A+++B"       Wrong!
decodeURIComponent("A+%2B+B") = "A+++B"       Wrong!
46
9.10.2012 09:26:43
Статья, на которую вы ссылаетесь, содержит много глупостей. Мне кажется, сам автор не понял, для чего эти функции должным образом используются ...
Christoph 24.07.2013 10:09:55
@Christoph Все это выглядит разумно для меня. В частности, я согласен с ним, что encodeURIкажется, что это полезно только в довольно непонятном крайнем случае и действительно не должно существовать. У меня есть некоторые расхождения во мнениях с ним, но я не вижу в этом ничего откровенного или идиотского. Что именно вы считаете ерундой?
Mark Amery 10.09.2013 20:32:29
enctypeАтрибут FORMэлемент определяет тип содержимого , используемый для кодирования набора данных формы для представления на сервер. application / x-www-form-urlencoded Это тип содержимого по умолчанию. Формы, представленные с этим типом содержимого, должны быть закодированы следующим образом: [...] Пробельные символы заменяются на `` + ', а [...] не буквенно-цифровые символы заменяются на `% HH', [...] Ссылка: HTML4 Sepc
cychoi 30.09.2013 23:40:57
encodeURIComponent ('A + B'). replace (/ \% 20 / g, '+') + '\ n' + decodeURIComponent ("A +% 2B + B" .relace (/ \ + / g, "% 20") ));
Zlatin Zlatev 5.10.2015 08:30:55

encodeURIComponent не кодирует -_.!~*'(), вызывая проблему при публикации данных в php в строке xml.

Например:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Общий побег с encodeURI
%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E

Как видите, одинарные кавычки не закодированы. Чтобы решить проблему, я создал две функции для решения проблемы в своем проекте для URL кодирования:

function encodeData(s:String):String{
    return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}

Для декодирования URL:

function decodeData(s:String):String{
    try{
        return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")"));
    }catch (e:Error) {
    }
    return "";
}
39
3.07.2013 06:53:11
Это также не делает знак # (фунт / хэш / число), который является% 23.
xr280xr 9.04.2014 21:58:54
@xr280xr What do you mean? encodeURIComponent does encode # to %23 (maybe it did not in 2014?)
David Balažic 15.10.2018 09:17:01

I have this function...

var escapeURIparam = function(url) {
    if (encodeURIComponent) url = encodeURIComponent(url);
    else if (encodeURI) url = encodeURI(url);
    else url = escape(url);
    url = url.replace(/\+/g, '%2B'); // Force the replacement of "+"
    return url;
};
1
21.06.2013 12:56:02
@ChristianVielma escape() is deprecated but never refer w3schools.com. see w3fools.com
Jerry Joseph 23.04.2014 16:39:07
@Christian Vielma - Some find the reference material at W3Schools to be less controversial and useful. Not everyone agrees that W3Schools shouldn't ever be referenced.
DavidRR 12.11.2014 16:54:05
W3Schools does get a bad rap. Sure they aren't always accurate, but then again i've come across many a blog post that is downright wrong as well. For me its sometimes a great starting point just to learn some of the terminology and then I dive a little deeper with other resources. Most important is that a single resource should never be biblical when it comes to this kind of stuff.
ryandlf 6.12.2015 15:25:04
It seems @molokoloco wrote this function as a fallback to versions where encodeURI does not exist but escape exists.
SOFe 23.10.2016 05:33:36

I've found that experimenting with the various methods is a good sanity check even after having a good handle of what their various uses and capabilities are.

Towards that end I have found this website extremely useful to confirm my suspicions that I am doing something appropriately. It has also proven useful for decoding an encodeURIComponent'ed string which can be rather challenging to interpret. A great bookmark to have:

http://www.the-art-of-web.com/javascript/escape/

3
8.08.2013 12:34:09

I recommend not to use one of those methods as is. Write your own function which does the right thing.

MDN has given a good example on url encoding shown below.

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);

console.log(header); 
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"


function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            //  so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

12
23.04.2014 16:54:17
what a great answer (if its compatible across chrome edge and firefox while not making any mistakes)
yan bellavance 29.07.2016 19:00:28

The difference between encodeURI() and encodeURIComponent() are exactly 11 characters encoded by encodeURIComponent but not by encodeURI:

Table with the ten differences between encodeURI and encodeURIComponent

I generated this table easily with console.table in Google Chrome with this code:

var arr = [];
for(var i=0;i<256;i++) {
  var char=String.fromCharCode(i);
  if(encodeURI(char)!==encodeURIComponent(char)) {
    arr.push({
      character:char,
      encodeURI:encodeURI(char),
      encodeURIComponent:encodeURIComponent(char)
    });
  }
}
console.table(arr);

439
14.11.2014 13:52:19
Isn't this browser dependent?
Pacerier 27.09.2014 23:08:38
@bladnman encodeURI and encodeURIComponent should work this way in all major browsers. You can test the above code in Chrome and Firefox as both support console.table. In other browsers (including Firefox and Chrome) you can use the following code: var arr=[]; for(var i=0;i<256;i++){var char=String.fromCharCode(i); if(encodeURI(char)!==encodeURIComponent(char)) console.log("character: "+char + " | encodeURI: " +encodeURI(char) + " |encodeURIComponent: " + encodeURIComponent(char) ) }
Johann Echavarria 27.09.2014 23:41:44
I meant @Pacerier :)
Johann Echavarria 27.09.2014 23:48:07
@Pacerier should be identical in various browsers unless the original spec is too ambiguous... also see stackoverflow.com/questions/4407599/…
Christophe Roussy 13.06.2016 08:32:13
I NEED TO UPVOTE THIS SEVERAL TIMES! Unfortunately can only upvote once.
Ramazan Polat 5.10.2016 19:44:08

Small comparison table Java vs. JavaScript vs. PHP.

1. Java URLEncoder.encode (using UTF8 charset)
2. JavaScript encodeURIComponent
3. JavaScript escape
4. PHP urlencode
5. PHP rawurlencode

char   JAVA JavaScript --PHP---
[ ]     +    %20  %20  +    %20
[!]     %21  !    %21  %21  %21
[*]     *    *    *    %2A  %2A
[']     %27  '    %27  %27  %27 
[(]     %28  (    %28  %28  %28
[)]     %29  )    %29  %29  %29
[;]     %3B  %3B  %3B  %3B  %3B
[:]     %3A  %3A  %3A  %3A  %3A
[@]     %40  %40  @    %40  %40
[&]     %26  %26  %26  %26  %26
[=]     %3D  %3D  %3D  %3D  %3D
[+]     %2B  %2B  +    %2B  %2B
[$]     %24  %24  %24  %24  %24
[,]     %2C  %2C  %2C  %2C  %2C
[/]     %2F  %2F  /    %2F  %2F
[?]     %3F  %3F  %3F  %3F  %3F
[#]     %23  %23  %23  %23  %23
[[]     %5B  %5B  %5B  %5B  %5B
[]]     %5D  %5D  %5D  %5D  %5D
----------------------------------------
[~]     %7E  ~    %7E  %7E  ~
[-]     -    -    -    -    -
[_]     _    _    _    _    _
[%]     %25  %25  %25  %25  %25
[\]     %5C  %5C  %5C  %5C  %5C
----------------------------------------
char  -JAVA-  --JavaScript--  -----PHP------
[ä]   %C3%A4  %C3%A4  %E4     %C3%A4  %C3%A4
[ф]   %D1%84  %D1%84  %u0444  %D1%84  %D1%84
17
16.10.2015 13:31:36

For the purpose of encoding javascript has given three inbuilt functions -

  1. escape() - does not encode @*/+ This method is deprecated after the ECMA 3 so it should be avoided.

  2. encodeURI() - does not encode ~!@#$&*()=:/,;?+' It assumes that the URI is a complete URI, so does not encode reserved characters that have special meaning in the URI. This method is used when the intent is to convert the complete URL instead of some special segment of URL. Example - encodeURI('http://stackoverflow.com'); will give - http://stackoverflow.com

  3. encodeURIComponent() - does not encode - _ . ! ~ * ' ( ) This function encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. This method should be used to convert a component of URL. For instance some user input needs to be appended Example - encodeURIComponent('http://stackoverflow.com'); will give - http%3A%2F%2Fstackoverflow.com

All this encoding is performed in UTF 8 i.e the characters will be converted in UTF-8 format.

encodeURIComponent differ from encodeURI in that it encode reserved characters and Number sign # of encodeURI

8
11.04.2020 09:12:59

The accepted answer is good. To extend on the last part:

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).

If you want to be on the safe side, percent encoding unreserved characters should be encoded as well.

You can use this method to escape them (source Mozilla)

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

// fixedEncodeURIComponent("'") --> "%27"
2
27.09.2017 06:56:16

Modern rewrite of @johann-echavarria's answer:

console.log(
    Array(256)
        .fill()
        .map((ignore, i) => String.fromCharCode(i))
        .filter(
            (char) =>
                encodeURI(char) !== encodeURIComponent(char)
                    ? {
                          character: char,
                          encodeURI: encodeURI(char),
                          encodeURIComponent: encodeURIComponent(char)
                      }
                    : false
        )
)

Or if you can use a table, replace console.log with console.table (for the prettier output).

1
9.02.2018 01:45:03

Inspired by Johann's table, I've decided to extend the table. I wanted to see which ASCII characters get encoded.

screenshot of console.table

Table shows only the encoded characters. Empty cells mean that the original and the encoded characters are the same.


Just to be extra, I'm adding another table for urlencode() vs rawurlencode(). The only difference seems to be the encoding of space character.

screenshot of console.table

<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 1);
$encoded = [];
foreach ($ascii as $char) {
    $obj = ["char" => $char];
    if ($char != urlencode($char))
        $obj["urlencode"] = urlencode($char);
    if ($char != rawurlencode($char))
        $obj["rawurlencode"] = rawurlencode($char);
    if (isset($obj["rawurlencode"]) || isset($obj["rawurlencode"]))
        $encoded[] = $obj;
}
echo "var encoded = " . json_encode($encoded) . ";";
?>
console.table(encoded);
</script>
2
11.02.2019 12:47:01