Отладка7 мин. чтения

Как исправить ошибки "URI Malformed" в JavaScript

Разбираемся, как диагностировать и устранить распространённую ошибку "URIError: URI malformed" в JavaScript с помощью практических решений.

Что означает ошибка URIError: URI Malformed

Ошибка URIError: URI malformed возникает в JavaScript, когда вы пытаетесь декодировать строку, содержащую недопустимые percent-encoded последовательности. Эта ошибка выбрасывается функциями decodeURI() или decodeURIComponent(), когда они встречают некорректно закодированный символ.

Распространённые причины

1. Одиночные знаки процента

Знак процента (%), за которым не следуют ровно две шестнадцатеричные цифры, недопустим. Например, %, %G или %2 (неполная последовательность) — все они приведут к этой ошибке.

// Эти вызовы выбросят URIError
decodeURIComponent('%');        // Одиночный %
decodeURIComponent('%2');       // Неполная последовательность
decodeURIComponent('%GH');      // Недопустимые шестнадцатеричные цифры
decodeURIComponent('100%');     // % в конце без шестнадцатеричных цифр

2. Недопустимые UTF-8 последовательности

Когда percent-encoded байты не образуют корректную последовательность символов UTF-8, декодер не может преобразовать их в строку. Это может произойти, если данные повреждены или были закодированы с использованием другой кодировки символов.

3. Двойное кодирование

Двойное кодирование происходит, когда уже закодированная строка кодируется повторно. Например, %20 (закодированный пробел) превращается в %2520. При попытке декодировать исходную строку последовательности могут оказаться недопустимыми.

Как это исправить

Решение 1. Используйте try-catch

function safeDecode(str) {
  try {
    return decodeURIComponent(str);
  } catch (e) {
    // Возвращаем исходную строку, если декодирование не удалось
    console.warn('Failed to decode:', str, e.message);
    return str;
  }
}

Решение 2. Проверяйте перед декодированием

function isValidEncodedURI(str) {
  try {
    decodeURIComponent(str);
    return true;
  } catch {
    return false;
  }
}

function fixMalformedURI(str) {
  // Заменяем одиночный % на %25 (закодированный процент)
  return str.replace(/%(?![0-9A-Fa-f]{2})/g, '%25');
}

Решение 3. Предотвращайте двойное кодирование

function smartEncode(str) {
  // Сначала пробуем декодировать — если получилось, строка
  // уже закодирована
  try {
    const decoded = decodeURIComponent(str);
    // Если декодирование изменило строку, значит она была закодирована
    if (decoded !== str) {
      return str; // Уже закодирована, возвращаем как есть
    }
  } catch {
    // Строка не является корректно закодированной, кодируем её
  }
  return encodeURIComponent(str);
}

Рекомендации по предотвращению ошибок

  • Всегда используйте try-catch при декодировании URL, полученных от пользователя или из внешних источников
  • Проверяйте URL перед их обработкой
  • Будьте осторожны, чтобы не закодировать значения дважды
  • По возможности используйте API URL и URLSearchParams — они обрабатывают кодирование корректно
  • Очищайте значения строки запроса перед кодированием
  • Логируйте некорректные URL для отладки

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

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