Почему decodeURIComponent ('%') блокирует мой браузер? - PullRequest
9 голосов
/ 16 сентября 2011

Я просто что-то тестировал с AJAX и обнаружил, что в случае успеха, если я предупреждаю

alert(decodeURI('%'));

или

alert(encodeURIComponent('%'));

браузер выдает ошибку со следующим кодом.

$.ajax({
   type: "POST",
   url: "some.php",
   data: "",
   success: function(html){
         alert(decodeURIComponent('%'));
//           alert(decodeURI('%'));
   }
 });

Если я использую любую другую строку, она прекрасно работает.
Это то, что я пропустил?

Ответы [ 6 ]

15 голосов
/ 16 сентября 2011

Chrome barfs при попытке с консоли. Это дает URIError: URI искажен. % Является escape-символом, он не может быть сам по себе.

7 голосов
/ 15 апреля 2017

Дело в том, что если вы используете одиночный %, это нарушает логику функции decodeURIComponent(), так как ожидает двухзначное значение данных, следующее сразу после него, например, %20 (пробел).

Вокруг есть взлом. Сначала нам нужно проверить, действительно ли decodeURIComponent() может работать с данной строкой, а если нет, вернуть строку такой, какая она есть.

Пример:

function decodeURIComponentSafe(uri, mod) {
    var out = new String(),
        arr,
        i = 0,
        l,
        x;
    typeof mod === "undefined" ? mod = 0 : 0;
    arr = uri.split(/(%(?:d0|d1)%.{2})/);
    for (l = arr.length; i < l; i++) {
        try {
            x = decodeURIComponent(arr[i]);
        } catch (e) {
            x = mod ? arr[i].replace(/%(?!\d+)/g, '%25') : arr[i];
        }
        out += x;
    }
    return out;
}

Запуск:

decodeURIComponent("%Directory%20Name%")

приведет к Uncaught URIError: URI malformed ошибке

в то время как:

decodeURIComponentSafe("%Directory%20Name%") // %Directory%20Name%

вернет исходную строку.

Если вы хотите иметь фиксированный / правильный URI и превратить % в %25, вам нужно будет передать 1 в качестве дополнительного параметра пользовательской функции:

decodeURIComponentSafe("%Directory%20Name%", 1) // "%25Directory%20Name%25"
3 голосов
/ 22 января 2019

Недавно decodeURIComponent в моем коде споткнулся об амперсанде %, и поиск в Google привел меня к этому вопросу.

Вот функция, которую я использую для обработки %, которая короче, чем версия Ilia:

function decodeURIComponentSafe(s) {
    if (!s) {
        return s;
    }
    return decodeURIComponent(s.replace(/%(?![0-9][0-9a-fA-F]+)/g, '%25'));
}

It

  • возвращает входное значение без изменений, если вход пустой
  • заменяет каждый % NOT, за которым следует двузначный (шестнадцатеричный)число с %25
  • возвращает декодированную строку

Здесь также работает с другими образцами:

  • decodeURIComponentSafe("%%20Visitors") // % Visitors
  • decodeURIComponentSafe("%Directory%20Name%") // %Directory Name%
  • decodeURIComponentSafe("%") // %
  • decodeURIComponentSafe("%1") // %1
  • decodeURIComponentSafe("%3F") // ?
3 голосов
/ 17 сентября 2011

Проблема здесь в том, что вы пытаетесь декодировать %.Это недопустимая закодированная строка.Я думаю, что вы хотите кодировать % вместо.

decodeURI('%') // URIError
encodeURI('%') // '%25'
1 голос
/ 16 сентября 2011

Поскольку URL имеет неправильный формат (% не является URL)

Uncaught URIError: URI malformed

encodeURIComponent() работает

0 голосов
/ 16 сентября 2011

Бесконечный цикл или блокировка могут быть вызваны ошибкой в ​​jquery.

Вы можете установить точку останова в jquery в точке, которая, вероятно, вызывает «блокировку».

Декодирование не имеет смысла только с предоставленным %, так как percent-encoding сопровождается буквенно-цифровыми цифрами, относящимися к заданному символу в таблице ASCII, и обычно должно приводить к ошибке URIError в Opera, Chrome, FF.

Используйте встроенную в браузер функцию encodeURI, если вы ищете «кодированную в URL» нотацию процента:

encodeURI('%')
//>"%25"
...