Why does decodeURIComponent('%') lock up my browser?

痞子三分冷 提交于 2019-12-18 20:01:11

问题


I was just testing something with AJAX and I found that on success if I alert

alert(decodeURI('%'));

or

alert(encodeURIComponent('%'));

the browser errors out with the following code.

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

If I use any other string it works just fine.
Is it something that I missed?


回答1:


Chrome barfs when trying from the console. It gives an URIError: URI malformed. The % is an escape character, it can't be on its own.




回答2:


The point is that if you use single % it breaks the logic of decodeURIComponent() function as it expects two-digit data-value followed right after it, for example %20 (space).

There is a hack around. We need to check first if the decodeURIComponent() actually can run on given string and if not return the string as it is.

Example:

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;
}

Running:

decodeURIComponent("%Directory%20Name%")

will result in Uncaught URIError: URI malformed error

while:

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

will return the initial string.

In case you would want to have a fixed/proper URI and have % turned into %25 you would have to pass 1 as additional parameter to the custom function:

decodeURIComponentSafe("%Directory%20Name%", 1) // "%25Directory%20Name%25"



回答3:


The problem here is you're trying to decode the %. This is not a valid encoded string. I think you want to encode the % instead.

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



回答4:


Recently a decodeURIComponent in my code tripped over the ampersand % and googling led me to this question.

Here's the function I use to handle % which is shorter than the version of Ilia:

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

It

  • returns the input value unchanged if input is empty
  • replaces every % NOT followed by a two-digit (hex) number with %25
  • returns the decoded string

It also works with the other samples around here:

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



回答5:


Both decodeURI('%') and decodeURIcomponent('%') cannot work because the URL is malformed (a single % is not valid as a url or url component)

Uncaught URIError: URI malformed

encodeURIComponent() works




回答6:


The endless-loop or lock up may be due to a bug in jquery.

You can set a breakpoint in jquery at a point which is likely causing the 'lock-up'.

Decode doesn't make sense with just % provided, as percent-encoding is followed by alphanumericals referring to a given character in the ASCII table, and should normally yield an URIError in Opera, Chrome, FF.

Use the browser built in function encodeURI if you are looking for the 'url-encoded' notation of the percent-character:

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


来源:https://stackoverflow.com/questions/7449588/why-does-decodeuricomponent-lock-up-my-browser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!