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

CristiC picture CristiC · Sep 16, 2011 · Viewed 31.2k times · Source

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?

Answer

Heinrich Ulbricht picture Heinrich Ulbricht · Jan 22, 2019

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") // ?