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

后端 未结 7 1147
别那么骄傲
别那么骄傲 2020-12-31 05:11

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

alert(decodeURI(\'%\'));

or

alert(encodeURIC         


        
相关标签:
7条回答
  • 2020-12-31 05:26

    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'
    
    0 讨论(0)
  • 2020-12-31 05:26

    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"
    
    0 讨论(0)
  • 2020-12-31 05:31

    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.

    0 讨论(0)
  • 2020-12-31 05:35

    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

    0 讨论(0)
  • 2020-12-31 05:37

    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") // ?
    0 讨论(0)
  • 2020-12-31 05:37

    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"
    
    0 讨论(0)
提交回复
热议问题