Как правильно закодировать URL в JavaScript? encodeURI vs encodeURIComponent
Разница между encodeURI и encodeURIComponent
Отличный вопрос! Это одна из самых частых ловушек для начинающих разработчиков. Давайте разберемся раз и навсегда.
encodeURI предназначен для кодирования целого URL. Он сохраняет символы, которые являются частью синтаксиса URI (например, ://, ?, #, /, &). Именно поэтому в вашем примере & и ? остались незакодированными — encodeURI считает их допустимыми разделителями.
encodeURIComponent предназначен для кодирования отдельных компонентов URL (например, значений параметров запроса). Он кодирует ВСЕ символы, кроме букв, цифр и -_.!~*'(). Это гарантирует, что ваше значение не будет интерпретировано как часть синтаксиса URL.
Правило простое:
- encodeURI — для всего URL целиком (если URL уже сформирован, но содержит не-ASCII символы)
- encodeURIComponent — для каждого значения параметра отдельно
Правильное решение вашей задачи
Вот как нужно собирать URL с параметрами:
const baseUrl = "https://api.example.com/search";
const query = "кофе & чай / рецепты?";
// Правильный подход:
// 1. Кодируем ТОЛЬКО значение параметра
const encodedQuery = encodeURIComponent(query);
// encodedQuery = "%D0%BA%D0%BE%D1%84%D0%B5%20%26%20%D1%87%D0%B0%D0%B9%20%2F%20%D1%80%D0%B5%D1%86%D0%B5%D0%BF%D1%82%D1%8B%3F"
// 2. Собираем URL
const fullUrl = baseUrl + "?q=" + encodedQuery;
// Результат: https://api.example.com/search?q=%D0%BA%D0%BE%D1%84%D0%B5%20%26%20%D1%87%D0%B0%D0%B9%20%2F%20%D1%80%D0%B5%D1%86%D0%B5%D0%BF%D1%82%D1%8B%3F
console.log(fullUrl);
// Сервер получит: ?q=кофе & чай / рецепты?
// (сервер автоматически декодирует)
Современный подход с URLSearchParams
В современном JavaScript лучше использовать URL и URLSearchParams — это безопаснее и читаемее:
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "кофе & чай / рецепты?");
url.searchParams.set("page", "1");
url.searchParams.set("lang", "ru");
console.log(url.toString());
// https://api.example.com/search?q=%D0%BA%D0%BE%D1%84%D0%B5+%26+%D1%87%D0%B0%D0%B9+%2F+%D1%80%D0%B5%D1%86%D0%B5%D0%BF%D1%82%D1%8B%3F&page=1&lang=ru
// Обратите внимание: пробелы кодируются как + (application/x-www-form-urlencoded)
Декодирование
Для обратного преобразования используйте:
decodeURI()— для декодирования всего URLdecodeURIComponent()— для декодирования отдельных компонентов
const encoded = "%D0%BA%D0%BE%D1%84%D0%B5%20%26%20%D1%87%D0%B0%D0%B9";
console.log(decodeURIComponent(encoded)); // "кофе & чай"
Важные нюансы
- Никогда не применяйте
encodeURIк значениям параметров — это сломает URL, если в значении есть&или# - Не кодируйте уже закодированные значения — это приведет к двойному кодированию
- Для отправки форм используйте
new FormData()— он сам правильно кодирует данные - Старый метод
escape()не используйте — он устарел и работает некорректно с Unicode
Запомните золотое правило: кодируйте каждую часть URL отдельно, как можно ближе к моменту её использования. Если вы собираете URL вручную — используйте encodeURIComponent для каждого параметра. Если используете URL API — он сделает всё за вас.
Дополнительные методы и старый браузерный подход
Если вы работаете с очень старыми браузерами (IE < 10) или нужна полная совместимость, можно написать свою функцию-обертку:
function safeEncodeURIComponent(str) {
return encodeURIComponent(str)
.replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase();
});
}
// Использование:
const query = "кофе & чай (рецепты)";
console.log(safeEncodeURIComponent(query));
// %D0%BA%D0%BE%D1%84%D0%B5%20%26%20%D1%87%D0%B0%D0%B9%20%28%D1%80%D0%B5%D1%86%D0%B5%D0%BF%D1%82%D1%8B%29
Также стоит упомянуть btoa() и atob() — они кодируют в Base64, но это не для URL, а для передачи бинарных данных в текстовом виде (например, для авторизации).
И еще один полезный трюк: если вы работаете с Node.js, используйте встроенный модуль querystring:
const querystring = require('querystring');
const params = { q: "кофе & чай", page: 1 };
const queryString = querystring.stringify(params);
console.log(queryString); // q=%D0%BA%D0%BE%D1%84%D0%B5%20%26%20%D1%87%D0%B0%D0%B9&page=1
Главное помните: encodeURIComponent — ваш лучший друг для значений параметров, а URLSearchParams — для современных проектов.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги