JavaScript8 мин чтения

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());

Похожие статьи

Попробуйте наши бесплатные инструменты