Кодирование и декодирование

В работе с библиотекой Navigo правильная обработка маршрутов напрямую связана с пониманием кодирования и декодирования URL. Navigo опирается на стандартные механизмы браузера для управления историей и адресной строкой, поэтому любые параметры, содержащие специальные символы, пробелы или юникод, должны корректно кодироваться при генерации ссылок и декодироваться при их обработке.


Кодирование URL-параметров

encodeURIComponent и encodeURI — стандартные функции JavaScript, которые используются для кодирования частей URL:

  • encodeURIComponent кодирует любой символ, кроме букв, цифр и некоторых специальных (- _ . ! ~ * ' ( )). Применяется для параметров маршрута.
  • encodeURI кодирует полный URL, не затрагивая символы, которые имеют специальное значение в URL (: / ? # &).

В контексте Navigo чаще используется encodeURIComponent, потому что параметры маршрута могут содержать пробелы, слэши и юникодные символы.

Пример создания маршрута с параметром:

import Navigo from 'navigo';

const router = new Navigo('/');

router.on('/user/:name', ({ data }) => {
  console.log('Имя пользователя:', decodeURIComponent(data.name));
});

// Переход на маршрут с кодированием имени
const username = "Иван Иванов";
router.navigate(`/user/${encodeURIComponent(username)}`);

Здесь важно, что при навигации используется encodeURIComponent, а при получении параметра — decodeURIComponent, чтобы восстановить исходное значение.


Декодирование URL-параметров

Navigo автоматически извлекает параметры из URL и передает их в обработчик маршрута через объект data. Если параметры содержат специальные символы или пробелы, они приходят в закодированном виде и требуют декодирования.

router.on('/search/:query', ({ data }) => {
  const query = decodeURIComponent(data.query);
  console.log('Поисковый запрос:', query);
});

Применение decodeURIComponent гарантирует корректное отображение всех символов, включая кириллицу и символы, не поддерживаемые в стандартном ASCII.


Кодирование маршрутов с несколькими параметрами

При маршрутах с несколькими динамическими сегментами каждый параметр необходимо кодировать отдельно:

router.on('/product/:category/:id', ({ data }) => {
  const category = decodeURIComponent(data.category);
  const id = decodeURIComponent(data.id);
  console.log(`Категория: ${category}, ID: ${id}`);
});

const category = "электроника/смартфоны";
const id = "123/456";
router.navigate(`/product/${encodeURIComponent(category)}/${encodeURIComponent(id)}`);

Если не использовать кодирование, слэши внутри параметров будут интерпретироваться как разделители маршрута, что приведет к неправильной навигации.


Особенности кодирования query-параметров

Navigo поддерживает работу с query-параметрами через объект query при навигации. Для правильного кодирования всех значений можно использовать функцию URLSearchParams:

const params = new URLSearchParams();
params.set('q', 'тестирование');
params.set('page', '1');

router.navigate(`/search?${params.toString()}`);

При обработке маршрута query-параметры извлекаются вручную:

router.on('/search', ({ query }) => {
  const q = query.get('q'); 
  const page = query.get('page'); 
  console.log(`Запрос: ${q}, Страница: ${page}`);
});

URLSearchParams автоматически выполняет кодирование и декодирование значений, что упрощает работу с кириллицей и специальными символами.


Проблемы с двойным кодированием

Частой ошибкой является двойное кодирование. Например, если параметр уже закодирован, повторный вызов encodeURIComponent приведет к появлению %25 вместо %. Это нарушает маршрутизацию и вызывает некорректное отображение параметров.

Правильный подход — кодировать только при создании URL и декодировать только при чтении из data:

const param = "тест/пример";
const encoded = encodeURIComponent(param); // кодируем один раз
router.navigate(`/path/${encoded}`);

В обработчике маршрута:

router.on('/path/:param', ({ data }) => {
  const decoded = decodeURIComponent(data.param);
  console.log(decoded); // "тест/пример"
});

Рекомендации по безопасности

  • Всегда использовать кодирование для динамических сегментов маршрута и query-параметров.
  • Никогда не вставлять пользовательские данные в URL без кодирования.
  • Декодировать параметры только после извлечения из data или URLSearchParams, чтобы избежать XSS-уязвимостей.

Интеграция с History API

Navigo использует History API для изменения URL без перезагрузки страницы. Параметры маршрута, закодированные через encodeURIComponent, корректно обрабатываются pushState и replaceState, что обеспечивает прозрачное управление навигацией и сохранение возможности использования кнопок “назад” и “вперед” в браузере.

router.navigate(`/profile/${encodeURIComponent('Пётр Петров')}`, { updateBrowserURL: true });

В этом примере URL в адресной строке корректно отобразится как /profile/%D0%9F%D1%91%D1%82%D1%80%20%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2, а в обработчике маршрута можно получить исходное значение через decodeURIComponent.


Заключение по кодированию и декодированию в Navigo

Правильное кодирование и декодирование — фундаментальная часть маршрутизации в Navigo. Оно обеспечивает корректную работу динамических сегментов маршрута, query-параметров и предотвращает ошибки, связанные с неправильной интерпретацией символов. Использование encodeURIComponent и decodeURIComponent совместно с URLSearchParams обеспечивает надежность, совместимость с юникодом и безопасность при работе с URL.