47

I entered the following in Chrome's console:

decodeURIComponent('a%AFc');

Instead of resulting to a0xAFc, it caused a URIError exception (malformed uri).

I've heard several excuses why this may be possible, but what I don't understand is why?

The decodeURIComponent() function in particular is supposed to decode data, not verify the URI.

Community
  • 1
  • 1
Christian
  • 27,509
  • 17
  • 111
  • 155

2 Answers2

55

%AF is not a character on his own but part of Unicode sequence (MACRON - %C2%AF).

%AF wasn't produced by encodeURIComponent but something like escape, so it can be decoded by unescape.

What you probably need is decodeURIComponent('%C2%AF')

Juicy Scripter
  • 25,778
  • 6
  • 72
  • 93
  • 3
    I made it up after I tried decoding a load of encoded text, failed and noticed it would choke on that particular character. Perhaps `unescape` is what I need. – Christian Jan 30 '12 at 13:45
  • 1
    @ChristianSciberras `encodeURIComponent()` is usually a better choice because it works with UTF-8. However, `0xAF` on its own is not valid UTF-8-encoded character sequence. This is why your code doesn't work. I hope it's clearer now. – duri Jan 30 '12 at 13:47
  • 3
    So what if I need to handle ASCII / iso-8859-1 percent-encoded inputs? `unescape` is deprecated, and there is also no `unescapeURI` – felixfbecker Dec 12 '16 at 11:51
  • A man like you deserves a special place in heaven. You solved my problem. Thanks – Harsh Patel Apr 28 '21 at 12:58
  • escape has been Deprecated :( – Alireza Bagheri Oct 16 '22 at 11:57
12

This may or may not apply to someone else's situation but this is what did it for me so I thought I would share. I upload and download lots of text files to a custom CMS.
the '%' sign in the source code was wreaking havoc for me.

// send to server
content = content.toString().replace(/%/g,'~~pct~~');       // ~~pct~~ <-made up replacement
content = encodeURI(content);

// get back from server / database
content = decodeURI(content);
content = content.toString().replace(/~~pct~~/g,'%');    // globally restore '%'
Michael Nelles
  • 5,426
  • 8
  • 41
  • 57