为什么decodeURIComponent('%')会锁定我的浏览器?

时间:2011-09-16 19:41:33

标签: javascript decodeuricomponent

我只是用AJAX测试一些东西,如果我发出警告,我发现成功了

alert(decodeURI('%'));

alert(encodeURIComponent('%'));

浏览器错误输出以下代码。

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

如果我使用任何其他字符串,它可以正常工作。
这是我错过的东西吗?

8 个答案:

答案 0 :(得分:15)

从控制台尝试时的Chrome barfs。它给出了一个URIError:URI格式错误。 %是一个转义字符,它不能单独使用。

答案 1 :(得分:7)

重点是,如果你使用单%,它会打破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"

答案 2 :(得分:3)

这里的问题是你试图解码 %。这不是有效的编码字符串。我想你想要编码 %

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

答案 3 :(得分:3)

最近,我的代码中有一个decodeURIComponent跳到了与号%上,谷歌搜索使我想到了这个问题。

这是我用来处理%的函数,该函数比Ili​​a的版本短:

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

  • 如果输入为空,则返回输入值不变
  • 将每个% NOT替换为%25后的两位数字(十六进制)
  • 返回解码后的字符串

它还可以与此处的其他示例一起使用:

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

答案 4 :(得分:1)

因为网址格式错误(%不是网址)

Uncaught URIError: URI malformed

encodeURIComponent()有效

答案 5 :(得分:0)

我遇到了与OP相同的问题,并发现了这个有用的主题。 在找到使用解码URIComponent()之前,必须找到一种方法来检查URI字符串是否包含百分号。

除了URI包含%C3之类的编码字符(其中百分号以[AF]开头)之外, Ilia Rostovtsev 的这段代码非常有效,因为所用的正则表达式无法处理它们(只有%,后跟一个小数)。

我替换了以下行:

   x = mod ? arr[i].replace(/%(?!\d+)/g, '%25') : arr[i];

作者

   x = mod ? arr[i].replace(/%(?!\d|[ABCDEF]+)/g, '%25') : arr[i];

现在,它正在运行,因为正则表达式将拒绝%1A到%9F以及%A1到%F9

答案 6 :(得分:0)

不幸的是这里的一些答案未能满足我的代码,所以我做了一个替代解决方案。如果有人遇到同样的问题。

您可以使用 try...catch 块来安全解码。如果字符串是可解码的,它将解码,否则,它返回与已解码的字符串相同的字符串。

function decodeURIComponentSafely(uri) {
    try {
        return decodeURIComponent(uri)
    } catch(e) {
        console.log('URI Component not decodable: ' + uri)
        return uri
    }
}

答案 7 :(得分:-7)

无限循环或锁定可能是由于jquery中的错误。

您可以在jquery中设置一个可能导致“锁定”的点的断点。

解码只提供%没有意义,因为percent-encoding后面跟着ASCII表中给定字符的字母数字,并且通常应该在Opera,Chrome,FF中产生URIError

如果您正在寻找百分号字符的'url-encoded'表示法,请使用内置函数encodeURI的浏览器:

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