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