15

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

12

Описание проблемы:

При кодировании строки запроса для отправки на веб-сервер у меня возникли сомнения относительно выбора между функциями escape(), encodeURI() и encodeURIComponent().

В каких случаях следует использовать escape(), а когда лучше применять encodeURI() или encodeURIComponent()?

Например, я знаю, что escape() можно использовать следующим образом:

escape("% +&=");

Но когда следует использовать encodeURI() или encodeURIComponent()? Я пробовал такие примеры:

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

Могу ли я получить разъяснение по этому вопросу? Как правильно выбирать между этими методами для кодирования строк запроса?

5 ответ(ов)

0

Проблема, с которой вы столкнулись, заключается в том, что encodeURIComponent не кодирует некоторые символы, такие как одиночная кавычка ('), что может привести к ошибкам при передаче данных на сервер, особенно если вы передаете 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");
}

И функция для декодирования данных:

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

Эти функции обеспечивают правильное кодирование и декодирование всех необходимых символов в вашей строке, что помогает избежать проблем с отправкой XML-данных на сервер. Это хороший подход к решению проблемы, когда стандартное поведение encodeURIComponent не подходит для ваших нужд.

0

Функция encodeURI() в JavaScript предназначена для кодирования URI, поскольку она заменяет специальные символы на их кодированные эквиваленты, сохраняющие при этом значения, которые имеют особое значение в URI (например, :, /, ?, & и т.д.). Это важно для корректного формирования URL-адресов.

В отличие от этого, функция escape() используется для экранирования символов в строках, но она не является стандартным методом для работы с URL. Она может не корректно обработать некоторые символы, как, например, + и другие, что делает её менее подходящей для работы с HTTP-запросами и URI.

Таким образом, для кодирования URL всегда рекомендуется использовать encodeURI() или encodeURIComponent(), которые больше подходят для HTTP-контекста и обеспечивают корректное представление символов в URL.

0

Чтобы провести небольшое сравнение кодирования URL в Java, JavaScript и PHP, можно использовать следующие методы и их отличия в обработке различных символов.

Вот краткая таблица, показывающая, как разные языки кодируют одни и те же символы:

1. Java: URLEncoder.encode (используя кодировку UTF-8)
2. JavaScript: encodeURIComponent 
3. JavaScript: escape
4. PHP: urlencode
5. PHP: rawurlencode

| Символ      | Java     | JavaScript | PHP     |
|-------------|----------|------------|---------|
| [space]     | +        | %20        | +       |
| [!]         | %21      | %21        | %21     |
| [*]         | *        | *          | %2A     |
| [']         | %27      | %27        | %27     |
| [(]         | %28      | %28        | %28     |
| [)]         | %29      | %29        | %29     |
| [;]         | %3B      | %3B        | %3B     |
| [:]         | %3A      | %3A        | %3A     |
| [@]         | %40      | %40        | %40     |
| [&]         | %26      | %26        | %26     |
| [=]         | %3D      | %3D        | %3D     |
| [+]         | %2B      | %2B        | +       |
| [$]         | %24      | %24        | %24     |
| [,]         | %2C      | %2C        | %2C     |
| [/]         | %2F      | %2F        | /       |
| [?]         | %3F      | %3F        | %3F     |
| [#]         | %23      | %23        | %23     |
| [[]         | %5B      | %5B        | %5B     |
| []]         | %5D      | %5D        | %5D     |
| [~]         | %7E      | ~          | %7E     |
| [-]         | -        | -          | -       |
| [_]         | _        | _          | _       |
| [%]         | %25      | %25        | %25     |
| [\]         | %5C      | %5C        | %5C     |

| Символ      | Java         | JavaScript   | PHP          |
|-------------|--------------|---------------|--------------|
| [ä]         | %C3%A4       | %C3%A4        | %E4          |
| [ф]         | %D1%84       | %D1%84        | %u0444       |

Замечания:

  • Обратите внимание, что символ пробела кодируется как + в Java и PHP, в то время как в JavaScript используется %20.
  • Некоторые символы кодируются одинаково на всех языках, например, !, * и т.д.
  • Также, существуют различия в кодировании специальных символов, таких как ä и ф, в зависимости от используемой кодировки.

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

0

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

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

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

console.log(header); 
// выводит "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"

function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Обратите внимание, что хотя RFC3986 резервирует "!", RFC5987 этого не делает,
        // поэтому нам не нужно его экранировать
        replace(/['()]/g, escape). // т.е., %27 %28 %29
        replace(/\*/g, '%2A').
            // Следующие символы не требуются для процентного кодирования согласно RFC5987, 
            // поэтому мы можем позволить немного лучшее читаемость в передаваемых данных: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

Вы можете ознакомиться с дополнительной информацией на сайте MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

0

В JavaScript для кодирования строк предусмотрены три встроенные функции:

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

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

    encodeURI('http://stackoverflow.com');
    

    Возвращаемое значение: http://stackoverflow.com.

  3. encodeURIComponent() - не кодирует символы - _ . ! ~ * ' ( ). Эта функция кодирует компонент УРЛ, заменяя каждый из определённых символов на одну, две, три или четыре escape-последовательности, представляющие кодировку UTF-8 этого символа. Этот метод следует использовать для кодирования компонента URL, когда, например, необходимо добавить пользовательский ввод. Пример:

    encodeURIComponent('http://stackoverflow.com');
    

    Возвращаемое значение: http%3A%2F%2Fstackoverflow.com.

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

Главное отличие между encodeURIComponent и encodeURI заключается в том, что первый кодирует зарезервированные символы и символ решётки #, которые не кодируются в encodeURI.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь