Kiedy należy użyć escape zamiast encodeURI / encodeURIComponent?

Podczas kodowania łańcucha zapytania do wysłania na serwer WWW-kiedy używasz escape() i kiedy używasz encodeURI() lub encodeURIComponent():

Użyj ucieczki:

escape("% +&=");

Lub

Użyj encodeURI () / encodeURIComponent ()

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

encodeURIComponent("var1=value1&var2=value2");
Author: Braiam, 2008-09-16

13 answers

Escape ()

Nie używaj go! escape() jest zdefiniowany w sekcji B. 2.1.2 escape , a tekst wprowadzający załącznika B mówi:

... Wszystkie cechy i zachowania języka określone w niniejszym załączniku mają jedną lub więcej niepożądanych cech i w przypadku braku dotychczasowego użycia zostaną usunięte z niniejszej specyfikacji. ...
... Programiści nie powinni używać lub zakładać istnienia tych funkcji i zachowań podczas pisania nowego ECMAScript kod....

Zachowanie:

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape

Znaki specjalne są kodowane z wyjątkiem:@*_+ -./

Postać szesnastkowa dla znaków, których wartość jednostki kodu wynosi 0xFF lub mniej, jest dwucyfrową sekwencją ucieczki: %xx.

Dla znaków z większą jednostką kodu stosuje się czterocyfrowy format %uxxxx. Nie jest to dozwolone w ciągu zapytania (jako zdefiniowany w RFC3986):

query       = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

Znak procentowy jest dozwolony tylko wtedy, gdy następuje bezpośrednio po nim dwa znaki heksowe, procent po którym następuje u nie jest dozwolony.

EncodeURI ()

Użyj encodeURI, gdy chcesz mieć działający adres URL. Wykonaj ten telefon:

encodeURI("http://www.example.org/a file with spaces.html")

Aby uzyskać:

http://www.example.org/a%20file%20with%20spaces.html

Nie wywołaj encodeURIComponent, ponieważ zniszczy on Adres URL i zwróci

http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html

EncodeURIComponent ()

Użyj encodeURIComponent, gdy chcesz zakodować wartość parametru URL.

var p1 = encodeURIComponent("http://example.org/?a=12&b=55")

Następnie możesz utworzyć adres URL, którego potrzebujesz:

var url = "http://example.net/?param1=" + p1 + "&param2=99";

I otrzymasz ten pełny URL:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=99

Zauważ, że encodeURIComponent nie ucieka znakowi '. Częstym błędem jest używanie go do tworzenia atrybutów html, takich jak href='MyUrl', które mogą cierpieć na błąd iniekcji. Jeśli tworzysz html z łańcuchów znaków, użyj " zamiast ' dla cudzysłowów atrybutów, lub dodaj dodatkową warstwę kodowania (' mogą być kodowane jako %27).

Aby uzyskać więcej informacji na temat tego typu kodowania, możesz sprawdzić: http://en.wikipedia.org/wiki/Percent-encoding

 1828
Author: Arne Evertsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-06 06:36:54

Różnica między encodeURI() i encodeURIComponent() to dokładnie 11 znaków zakodowanych przez encodeURIComponent, ale nie przez encodeURI:

Tabela z dziesięcioma różnicami między encodeURI i encodeURIComponent

Wygenerowałem tę tabelę z łatwością za pomocą console.Tabela W Google Chrome o tym kodzie:

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);
 394
Author: Johann Echavarria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-14 13:52:19

Znalazłem ten artykuł : Javascript Madness: Query String Parsing

Znalazłem go, gdy próbowałem Understanding i dlaczego decodeURIComponent nie dekoduje ' + ' poprawnie. Oto Wyciąg:

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!
 43
Author: Damien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-09 09:26:43

EncodeURIComponent nie koduje -_.!~*'(), powodując problem w wysyłaniu danych do php w XML string.

Na przykład:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Ogólna Ucieczka z 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

Widzisz, pojedynczy cytat nie jest zakodowany. Aby rozwiązać problem, stworzyłem dwie funkcje do rozwiązania problemu w moim projekcie, dla kodowania 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");
}

Do dekodowania 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 "";
}
 37
Author: Kirankumar Sripati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-03 06:53:11

EncodeURI () - funkcja escape () służy do JavaScript, a nie HTTP.

 36
Author: Daniel Papasian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 19:26:22

Mała tabela porównawcza 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
 15
Author: 30thh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-16 13:31:36

Pamiętaj również, że wszystkie kodują różne zestawy znaków i odpowiednio wybierają ten, którego potrzebujesz. encodeURI() koduje mniej znaków niż encodeURIComponent (), która koduje mniej (a także różni się, do punktu dannypa) znaków niż escape ().

 10
Author: Pseudo Masochist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 19:40:32

Zalecam, aby nie używać żadnej z tych metod, jak jest. Napisz własną funkcję, która działa dobrze.

MDN podał dobry przykład kodowania url pokazanego poniżej.

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

 10
Author: Jerry Joseph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-23 16:54:17

Na potrzeby kodowania javascript podał trzy wbudowane funkcje -

  1. Escape () - nie koduje @*/+ Ta metoda jest przestarzała po ECMA 3, więc należy jej unikać.

  2. EncodeURI () - nie koduje ~!@#$&*()=:/,;?+' Zakłada ona, że URI jest kompletnym URI, więc nie koduje zastrzeżonych znaków, które mają specjalne znaczenie w URI. Ta metoda jest używana, gdy intencją jest przekonwertowanie całego adresu URL zamiast jakiegoś specjalnego segmentu adresu URL. Przykład - encodeURI('http://stackoverflow.com'); da - http://stackoverflow.com

  3. EncodeURIComponent () - nie koduje - _ . ! ~ * ' ( ) Ta funkcja koduje komponent Uniform Resource Identifier (URI), zastępując każdą instancję pewnych znaków jedną, dwiema, trzema lub czterema sekwencjami escape reprezentującymi kodowanie UTF-8 tego znaku. Ta metoda powinna być użyta do konwersji składnika adresu URL. Na przykład niektóre dane wejściowe użytkownika muszą być dołączone Przykład - encodeURI('http://stackoverflow.com'); da - http%3A%2F%2Fstackoverflow.com

całe to kodowanie jest wykonywane w UTF 8 tzn. znaki będą konwertowane w formacie UTF-8.

encodeURIComponent różni się od encodeURI tym, że koduje zastrzeżone znaki i znak liczby # encodeURI

 5
Author: Gaurav Tiwari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-21 07:55:51

Odkryłem, że eksperymentowanie z różnymi metodami jest dobrym sprawdzeniem zdrowego rozsądku, nawet po tym, jak dobrze radzą sobie z ich różnymi zastosowaniami i możliwościami.

W tym celu znalazłem ta strona niezwykle przydatna, aby potwierdzić moje podejrzenia, że robię coś odpowiednio. Okazało się również przydatne do dekodowania encodeURIComponent'ed string, który może być dość trudne do interpretacji. Świetna zakładka do mieć:

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

 3
Author: veeTrain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 12:34:09

Mam tę funkcję...

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
Author: molokoloco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 12:56:02

Przyjęta odpowiedź jest dobra. Aby rozszerzyć na ostatnią część:

Zauważ, że encodeURIComponent nie ucieka przed znakiem'. Często błędem jest użycie go do tworzenia atrybutów html takich jak href= 'MyUrl', które może ucierpieć pluskwa iniekcyjna. Jeśli konstruujesz html z ciągi, albo użyj "zamiast" dla cudzysłowów atrybutów, albo Dodaj dodatkowa warstwa kodowania ('można zakodować jako %27).

Jeśli chcesz być po bezpiecznej stronie, kodowanie procentowe znaki bezwarunkowe powinny być również zakodowane.

Możesz użyć tej metody, aby uciec od nich (źródło Mozilla )

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

// fixedEncodeURIComponent("'") --> "%27"
 1
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 06:56:16

Nowoczesne przepisanie odpowiedzi @ johann-echavarria:

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

Lub jeśli możesz użyć tabeli, zamień console.log na console.table (dla ładniejszego wyjścia).

 0
Author: ryanpcmcquen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-09 01:45:03