Avatar ·

Как правильно закодировать URL в JavaScript? Разница между encodeURI, encodeURIComponent и escape

Привет всем! Я новичок в JavaScript и столкнулся с проблемой при работе с URL. Мне нужно отправить GET-запрос на сервер с параметрами, которые содержат специальные символы, например, пробелы, кириллицу или знаки вопроса. Вот пример моего кода: ```javascript let baseUrl = "https://api.example.com/search"; let query = "JavaScript & HTML/CSS уроки"; let fullUrl = baseUrl + "?q=" + query; fetch(fullUrl) .then(response => response.json()) .then(data => console.log(data)); ``` Этот код не работает, потому что в URL есть пробелы и символ `&`. Я погуглил и нашёл три функции: `escape()`, `encodeURI()` и `encodeURIComponent()`. Но я запутался — какая из них правильная? Когда я использую `escape()`, вроде бы работает, но я слышал, что она устарела. А `encodeURI()` не кодирует всё подряд, а `encodeURIComponent()` кодирует даже слэши. Подскажите, пожалуйста, как правильно закодировать URL в JavaScript? В каких случаях использовать каждую из этих функций? И что делать, если нужно закодировать только часть URL, а не весь адрес? Заранее спасибо за помощь! <<>>

Правильный способ кодирования URL в JavaScript

Вы столкнулись с классической проблемой. Давайте разберёмся по порядку. В современном JavaScript используйте только encodeURI() и encodeURIComponent(). Функция escape() устарела и не должна применяться — она не кодирует символы в соответствии с RFC 3986 и некорректно обрабатывает Unicode.

Основные различия

  • encodeURI() — кодирует полный URL, но не трогает символы, которые являются частью синтаксиса URI (://?#[]@ и т.д.). Подходит для кодирования всего адреса целиком.
  • encodeURIComponent() — кодирует все символы, включая слэши, двоеточия и знаки вопроса. Используйте для кодирования значений параметров или фрагментов пути.

Правильное решение вашей задачи

В вашем случае нужно кодировать только значение параметра q, а не весь URL. Используйте encodeURIComponent():

let baseUrl = "https://api.example.com/search";
let query = "JavaScript & HTML/CSS уроки";
let encodedQuery = encodeURIComponent(query); // "JavaScript%20%26%20HTML%2FCSS%20%D1%83%D1%80%D0%BE%D0%BA%D0%B8"
let fullUrl = baseUrl + "?q=" + encodedQuery;

fetch(fullUrl)
  .then(response => response.json())
  .then(data => console.log(data));
// Результат: https://api.example.com/search?q=JavaScript%20%26%20HTML%2FCSS%20%D1%83%D1%80%D0%BE%D0%BA%D0%B8

Когда что использовать

  • encodeURIComponent() — для кодирования значений параметров (всё, что идёт после ? или #), а также для кодирования частей пути, которые могут содержать специальные символы.
  • encodeURI() — когда нужно закодировать весь URL, содержащий не-ASCII символы (например, кириллицу в домене), но при этом сохранить его структуру.

Наглядный пример разницы

const url = "https://example.com/путь?name=Иван & Петр#section";

console.log(encodeURI(url));
// https://example.com/%D0%BF%D1%83%D1%82%D1%8C?name=%D0%98%D0%B2%D0%B0%D0%BD%20&%20%D0%9F%D0%B5%D1%82%D1%80#section
// Слэши, ?, &, # остались нетронутыми

console.log(encodeURIComponent(url));
// https%3A%2F%2Fexample.com%2F%D0%BF%D1%83%D1%82%D1%8C%3Fname%3D%D0%98%D0%B2%D0%B0%D0%BD%20%26%20%D0%9F%D0%B5%D1%82%D1%80%23section
// Закодировано всё — такой URL не будет работать как адрес

Дополнительные советы

  • Для сборки URL с параметрами удобно использовать объект URL и URLSearchParams — они сами закодируют значения:
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "JavaScript & HTML/CSS уроки");
url.searchParams.set("page", "1");
console.log(url.toString());
// https://api.example.com/search?q=JavaScript+%26+HTML%2FCSS+%D1%83%D1%80%D0%BE%D0%BA%D0%B8&page=1
  • Никогда не используйте escape() — он не поддерживает Unicode корректно и удалён из стандарта.
  • Если вы кодируете данные для application/x-www-form-urlencoded (тело POST-запроса), используйте encodeURIComponent().

Запомните простое правило: всё, что является значением — кодируйте через encodeURIComponent(). Это убережёт вас от большинства ошибок.

<<>>

Альтернативный подход: использование URL и URLSearchParams

В современном JavaScript (ES6+) необязательно вручную вызывать encodeURIComponent(). Стандартные объекты URL и URLSearchParams берут кодирование на себя автоматически. Это более читаемый и надёжный способ:

// Создаём объект URL
const apiUrl = new URL('https://api.example.com/search');

// Добавляем параметры через searchParams
apiUrl.searchParams.append('query', 'JavaScript & HTML/CSS');
apiUrl.searchParams.append('page', '1');
apiUrl.searchParams.append('lang', 'ru');

console.log(apiUrl.toString());
// https://api.example.com/search?query=JavaScript+%26+HTML%2FCSS&page=1&lang=ru

Преимущества этого подхода:

  • Автоматическое кодирование — все специальные символы в значениях параметров будут закодированы корректно.
  • Читаемость — код выглядит чище и понятнее.
  • Безопасность — исключается риск случайно не закодировать какой-то параметр.
  • Гибкость — можно легко добавлять, изменять или удалять параметры.

Этот метод особенно полезен, когда у вас много параметров или когда URL динамически формируется из разных источников. Однако помните: если вам нужно закодировать только строку (например, для хеша или фрагмента пути), encodeURIComponent() всё ещё актуален и незаменим.