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

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

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

escape("% +&=");

ИЛИ

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

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

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

Ответы

Ответ 1

побег()

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

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

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

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

Ответ 2

Разница между 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);

Ответ 3

Я нашел эту статью просветляющей: 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!

Ответ 4

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

Например:
<xml><text x="100" y="150" value="It 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");
}

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

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 "";
}

Ответ 5

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

Ответ 6

Небольшая таблица сравнения 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

Ответ 7

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

Ответ 8

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

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

Ответ 9

В целях кодирования javascript дал три встроенные функции -

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

  • encodeURI() - не кодирует [email protected]#$&*()=:/,;?+' Он предполагает, что URI является полным URI, поэтому не кодирует зарезервированные символы, которые имеют особое значение в URI. Этот метод используется, когда целью является преобразование полного URL вместо некоторого особого сегмента URL. Пример - encodeURI('http://qaru.site/'); даст - /fooobar.com/...

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

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

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

Ответ 10

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

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

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

Ответ 11

У меня есть эта функция...

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;
};

Ответ 12

Принятый ответ хорош. Чтобы продолжить на последней части:

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

Если вы хотите быть в безопасности, процент кодирования безоговорочных символов также должен быть закодирован.

Вы можете использовать этот метод для их удаления (источник Mozilla)

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

// fixedEncodeURIComponent("'") --> "%27"