Когда вы должны использовать escape вместо encodeURI / encodeURIComponent? - PullRequest
1342 голосов
/ 16 сентября 2008

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

Использовать escape:

escape("% +&=");

OR

использовать encodeURI () / encodeURIComponent ()

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

encodeURIComponent("var1=value1&var2=value2");

Ответы [ 14 ]

1865 голосов
/ 31 августа 2010

побег ()

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

... Все языковые функции и поведения, указанные в этом приложении, имеют одну или несколько нежелательных характеристик, и при отсутствии устаревшего использования будут удалены из этой спецификации. ...
... Программисты не должны использовать или предполагать существование этих функций и поведения при написании нового кода ECMAScript ....

Поведение:

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

Специальные символы кодируются, за исключением: @ * _ + -. /

Шестнадцатеричная форма для символов, значение кодовой единицы которых равно 0xFF или меньше, представляет собой двузначную escape-последовательность: %xx.

Для символов с большей кодовой единицей используется четырехзначный формат %uxxxx. Это недопустимо в строке запроса (как определено в RFC3986 ):

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

Знак процента разрешен только в том случае, если за ним сразу следуют две шестнадцатеричные цифры, процент с последующим u не допускается.

encodeURI ()

Используйте encodeURI, когда вы хотите рабочий URL. Сделайте этот звонок:

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

чтобы получить:

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

Не вызывайте encodeURIComponent, так как он уничтожит URL и вернет

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

encodeURIComponent ()

Используйте encodeURIComponent, если вы хотите закодировать значение параметра URL.

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

Затем вы можете создать нужный вам URL:

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

И вы получите полный URL-адрес:

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

Обратите внимание, что encodeURIComponent не экранирует символ '. Распространенной ошибкой является использование ее для создания атрибутов html, таких как href='MyUrl', что может привести к ошибке внедрения. Если вы строите html из строк, либо используйте " вместо ' для кавычек атрибутов, либо добавьте дополнительный уровень кодирования (' можно кодировать как% 27).

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

416 голосов
/ 24 мая 2014

Разница между encodeURI() и encodeURIComponent() составляет ровно 11 символов, закодированных с помощью encodeURIComponent, но не с помощью encodeURI:

Table with the ten differences between encodeURI and encodeURIComponent

Я сгенерировал эту таблицу легко с помощью console.table в Google Chrome с этим кодом:

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);
46 голосов
/ 09 октября 2012

Я нашел эту статью поучительной: 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!
40 голосов
/ 08 мая 2013

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 "";
}
38 голосов
/ 16 сентября 2008

encodeURI () - функция escape () предназначена для экранирования JavaScript, а не HTTP.

17 голосов
/ 08 октября 2015

Маленькая таблица сравнения Java против JavaScript против 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
11 голосов
/ 23 апреля 2014

Я рекомендую не использовать один из этих методов как есть. Напишите свою собственную функцию, которая делает правильные вещи.

MDN привел хороший пример кодировки URL, показанный ниже.

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 голосов
/ 16 сентября 2008

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

7 голосов
/ 21 апреля 2017

Для целей кодирования javascript предоставил три встроенные функции -

  1. escape () - не кодирует @*/+ Этот метод считается устаревшим после ECMA 3, поэтому его следует избегать.

  2. encodeURI () - не кодирует ~!@#$&*()=:/,;?+' Предполагается, что URI является полным URI, поэтому не кодирует зарезервированные символы, которые имеют особое значение в URI. Этот метод используется, когда целью является преобразование полного URL-адреса вместо какого-либо специального сегмента URL-адреса. Пример - encodeURI('http://stackoverflow.com'); даст - http://stackoverflow.com

  3. encodeURIComponent () - не кодирует - _ . ! ~ * ' ( ) Эта функция кодирует компонент универсального идентификатора ресурса (URI), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа. Этот метод должен использоваться для преобразования компонента URL. Например, некоторые пользовательские данные должны быть добавлены Пример - encodeURI('http://stackoverflow.com'); даст - http% 3A% 2F% 2Fstackoverflow.com

Все это кодирование выполняется в UTF 8, т. Е. Символы будут преобразованы в формат UTF-8.

encodeURIComponent отличается от encodeURI тем, что он кодирует зарезервированные символы и знак числа # encodeURI

3 голосов
/ 08 августа 2013

Я обнаружил, что экспериментирование с различными методами является хорошей проверкой работоспособности даже после того, как они хорошо разбираются в их различных применениях и возможностях.

С этой целью я нашел этот сайт чрезвычайно полезным, чтобы подтвердить мои подозрения, что я что-то делаю надлежащим образом. Это также оказалось полезным для декодирования строки encodeURIComponent, которую может быть довольно сложно интерпретировать. Отличная закладка, чтобы иметь:

http://www.the -art-of-web.com / JavaScript / бежать /

...