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

1168

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

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

escape("% +&=");

ИЛИ

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

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

encodeURIComponent("var1=value1&var2=value2");
  • 98
    Стоит отметить, что encodeURIComponent("var1=value1&var2=value2") не является типичным вариантом использования. Этот пример закодирует = и & , что, вероятно, не то, что предполагалось! encodeURIComponent обычно применяется отдельно только к значению в каждой паре ключ-значение (часть после каждого = ).
  • 3
    тебе нужно что-нибудь сделать с ключом? Что если в нем есть =? (это вообще возможно?)
Показать ещё 4 комментария
Теги:
encoding
query-string

12 ответов

1670
Лучший ответ

побег()

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

Шестнадцатеричная форма для символов, значение кодового блока которой равно 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

  • 30
    @Francois, в зависимости от принимающего сервера, может некорректно декодировать, как escape кодирует верхние символы ASCII или не-ASCII, такие как: • Например, класс Python FieldStorage не будет правильно декодировать указанную выше строку, если закодирован пока escape.
  • 21
    @Francois escape () кодирует нижние 128 символов ASCII, кроме букв, цифр и *@-_+./, тогда как unescape () является обратным к escape (). Насколько я могу судить, это унаследованные функции, предназначенные для кодирования URL-адресов и все еще реализованные только для обратной совместимости. Как правило, их не следует использовать, если они не взаимодействуют с приложением / веб-службой / и т. Д., Предназначенными для них.
Показать ещё 15 комментариев
345

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

Изображение 2164

Я легко сгенерировал эту таблицу с помощью 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);
  • 117
    +1 для ясности и еще один для console.table magic!
  • 0
    Разве этот браузер не зависит?
Показать ещё 5 комментариев
40

Я нашел эту статью просветляющей: 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!
  • 10
    Статья, на которую вы ссылаетесь, содержит много глупостей. Мне кажется, сам автор не понял, для чего правильно используются функции ...
  • 2
    @Christoph Все это выглядит разумно для меня. В частности, я согласен с ним, что encodeURI выглядит так, как будто он полезен только в довольно непонятном крайнем случае и действительно не должен существовать. У меня есть некоторые расхождения во мнениях с ним, но я не вижу в этом ничего откровенного или идиотского. Что именно вы считаете ерундой?
Показать ещё 3 комментария
36

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
    Это также не делает знак # (фунт / хэш / число), который является% 23.
  • 1
    @ xr280xr Что ты имеешь в виду? encodeURIComponent кодирует # в% 23 (может быть, не в 2014?)
Показать ещё 2 комментария
35

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

  • 0
    Если у меня есть такой URL: var url = "http://kuler-api.adobe.com/rss/get.cfm?startIndex=0&itemsPerPage=20&timeSpan=0&listType=rating" ... И я хочу получить к нему доступ через API Google Ajax, например: var gurl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q=" + url; ... тогда я должен использовать escape(url) . encodeURI(url) не работает с такими параметрами, как кажется.
  • 15
    вы должны использовать ecnodeURIComponent (url)
Показать ещё 1 комментарий
13

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

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

7

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

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

  • 1
    какой отличный ответ (если он совместим с Chrome и Firefox, не делая ошибок)
4

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

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

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

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

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

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

3

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

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

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

1

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

Обратите внимание, что 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"
1

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

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;
};
  • 2
    Побег не рекомендуется: w3schools.com/jsref/jsref_escape.asp
  • 4
    @ChristianVielma escape () устарела, но никогда не ссылается на w3schools.com. см. w3fools.com
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню