encodeURIComponent и encodeURI: что и когда использовать
Подробное сравнение JavaScript-функций encodeURIComponent() и encodeURI() с примерами и рекомендациями по применению.
Две функции URL-кодирования в JavaScript
В JavaScript есть две встроенные функции для URL-кодирования: encodeURI() и encodeURIComponent(). Они кажутся похожими, но выбор неправильной из них может привести к сломанным URL, уязвимостям в безопасности или повреждению данных. Понимание разницы между ними критично для веб-разработчика.
encodeURI() — для полных URI
Функция encodeURI() предназначена для кодирования целого URI. Она кодирует все символы, кроме тех, что имеют специальное значение в структуре URI. В частности, она НЕ кодирует:
- Зарезервированные символы:
; , / ? : @ & = + $ # - Незарезервированные символы: буквы, цифры,
- _ . ! ~ * ' ( )
// encodeURI сохраняет структуру URI
encodeURI('https://example.com/path?q=hello world&lang=en')
// "https://example.com/path?q=hello%20world&lang=en"
// Обратите внимание: символы :, /, ?, =, & НЕ кодируются
encodeURIComponent() — для компонентов URI
Функция encodeURIComponent() предназначена для кодирования отдельного компонента URI (например, значения параметра запроса). Она кодирует ВСЕ символы, кроме:
- Незарезервированных символов: буквы, цифры,
- _ . ! ~ * ' ( )
// encodeURIComponent кодирует всё, кроме незарезервированных символов
encodeURIComponent('hello world & goodbye')
// "hello%20world%20%26%20goodbye"
// Обратите внимание: & кодируется, потому что это зарезервированный символ
// Использование для значения параметра запроса
const url = 'https://example.com/search?q=' +
encodeURIComponent('cats & dogs');
// "https://example.com/search?q=cats%20%26%20dogs"
Распространённые ошибки
Ошибка 1: использование encodeURI для значений запроса
Если применить encodeURI() для кодирования значения параметра запроса, содержащего амперсанд, этот амперсанд не будет закодирован и будет воспринят как разделитель параметров, что сломает ваш URL.
// НЕПРАВИЛЬНО: амперсанд в значении ломает URL
const badUrl = 'https://api.example.com/search?q=' +
encodeURI('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20&%20Jerry"
// Сервер видит: q="Tom " и параметр " Jerry" без значения
// ПРАВИЛЬНО: используйте encodeURIComponent
const goodUrl = 'https://api.example.com/search?q=' +
encodeURIComponent('Tom & Jerry');
// "https://api.example.com/search?q=Tom%20%26%20Jerry"
// Сервер корректно видит: q="Tom & Jerry"
Ошибка 2: использование encodeURIComponent для полных URL
Если применить encodeURIComponent() к целому URL, она закодирует двоеточия, слэши, знаки вопроса и другие структурные символы, полностью сделав URL непригодным к использованию.
Что и когда использовать: простое правило
- Используйте
encodeURI(), когда у вас есть полный URI, который может содержать пробелы или не-ASCII символы, но структура при этом корректна - Используйте
encodeURIComponent(), когда вы кодируете отдельный фрагмент данных, который будет вставлен в URI (значения параметров запроса, сегменты пути и т. д.)
Альтернатива: URLSearchParams
Современный JavaScript предоставляет API URLSearchParams, который выполняет кодирование автоматически. Часто это лучший подход для построения строк запроса:
const params = new URLSearchParams({
q: 'Tom & Jerry',
category: 'cartoons & animation',
page: '1'
});
const url = 'https://example.com/search?' + params.toString();
// "https://example.com/search?q=Tom+%26+Jerry&category=cartoons+%26+animation&page=1"
// Или используйте URL API
const url2 = new URL('https://example.com/search');
url2.searchParams.set('q', 'Tom & Jerry');
console.log(url2.toString());