Почему decodeURIComponent ('%') блокирует мой браузер?

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

alert(decodeURI('%'));

или

alert(encodeURIComponent('%'));

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

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

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

Ответ 1

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

Ответ 2

Дело в том, что если вы используете одиночный %, он прерывает логику функции 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

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

decodeURI('%') // URIError
encodeURI('%') // '%25'

Ответ 4

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

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

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

It

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

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

  • decodeURIComponentSafe("%%20Visitors") // % Visitors
  • decodeURIComponentSafe("%Directory%20Name%") // %Directory Name%
  • decodeURIComponentSafe("%") // %
  • decodeURIComponentSafe("%1") // %1
  • decodeURIComponentSafe("%3F") // ?

Ответ 5

И decodeURI('%'), и decodeURIcomponent('%') не могут работать, потому что URL имеет неправильный формат (один% недопустим в качестве URL или компонента URL)

Uncaught URIError: URI malformed

encodeURIComponent() работает

Ответ 6

Вы можете закодировать строку перед декодированием: decodeURI(encodeURI(yourString))

let str = "100% success!"
let transform = encodeURI(str)
console.log('transform first', transform)
let result = decodeURI(transform);
console.log('result ', result)
console.log('-----------------')
console.log('decode directly: ')
console.log(decodeURI(str))

Ответ 7

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

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

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

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

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