Когда следует использовать escape вместо encodeURI / encodeURIComponent?
Описание проблемы:
При кодировании строки запроса для отправки на веб-сервер у меня возникли сомнения относительно выбора между функциями 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 ответ(ов)
Проблема, с которой вы столкнулись, заключается в том, что 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
не подходит для ваших нужд.
Функция encodeURI()
в JavaScript предназначена для кодирования URI, поскольку она заменяет специальные символы на их кодированные эквиваленты, сохраняющие при этом значения, которые имеют особое значение в URI (например, :
, /
, ?
, &
и т.д.). Это важно для корректного формирования URL-адресов.
В отличие от этого, функция escape()
используется для экранирования символов в строках, но она не является стандартным методом для работы с URL. Она может не корректно обработать некоторые символы, как, например, +
и другие, что делает её менее подходящей для работы с HTTP-запросами и URI.
Таким образом, для кодирования URL всегда рекомендуется использовать encodeURI()
или encodeURIComponent()
, которые больше подходят для HTTP-контекста и обеспечивают корректное представление символов в URL.
Чтобы провести небольшое сравнение кодирования 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 в различных языках программирования, чтобы избежать ошибок в передачах данных.
Я рекомендую не использовать один из существующих методов в их исходном виде. Лучше написать свою функцию, которая будет делать все правильно.
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
В JavaScript для кодирования строк предусмотрены три встроенные функции:
escape()
- не кодирует символы@*/+
. Этот метод устарел после ECMA 3, поэтому его следует избегать.encodeURI()
- не кодирует символы~!@#$&*()=:/,;?+'
. Он предполагает, что переданный URI является полным URI и не кодирует зарезервированные символы, имеющие специальное значение в URI. Этот метод используется, когда нужно закодировать весь URL, а не его отдельный сегмент. Пример:encodeURI('http://stackoverflow.com');
Возвращаемое значение:
http://stackoverflow.com
.encodeURIComponent()
- не кодирует символы- _ . ! ~ * ' ( )
. Эта функция кодирует компонент УРЛ, заменяя каждый из определённых символов на одну, две, три или четыре escape-последовательности, представляющие кодировку UTF-8 этого символа. Этот метод следует использовать для кодирования компонента URL, когда, например, необходимо добавить пользовательский ввод. Пример:encodeURIComponent('http://stackoverflow.com');
Возвращаемое значение:
http%3A%2F%2Fstackoverflow.com
.
Все эти функции выполняют кодирование в формате UTF-8, то есть символы будут преобразованы в UTF-8.
Главное отличие между encodeURIComponent
и encodeURI
заключается в том, что первый кодирует зарезервированные символы и символ решётки #
, которые не кодируются в encodeURI
.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"