What the URL decoder does
Links copied from a browser, a log file, an email or an API often look like q%3Dcaf%C3%A9%20%26%20tea. The decoder reads each %XX code, joins the bytes and converts them from UTF-8 back to characters, so you see q=café & tea. Letters that were never encoded stay as they are.
Example
https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dcaf%C3%A9%20%26%20tea%26lang%3Den%23top
decodes to:
https://example.com/search?q=café & tea&lang=en#top
Options
- Treat + as a space. On by default, because form data and most query strings use
+for a space. Turn it off for paths and for text where+is a real plus sign (a phone number such as+971..., orC++). A real plus that was encoded as%2Bis always decoded as+. - Decode repeatedly. If the text still contains
%25, it was encoded twice (%2520is a space encoded twice). This option decodes up to five times, until nothing is left to decode. - Decode line by line. Keeps the line breaks when you paste a list of encoded values.
Why a decoder can fail, and what this one does
The built-in decodeURIComponent() function of JavaScript throws a URIError: URI malformed error when it sees a lone % or bytes that are not valid UTF-8. This page does not stop. It decodes everything that is valid, leaves the broken parts as they are, and tells you how many there were. Typical causes:
- A literal percent sign that was not encoded, as in
50% off. It should have been50%25 off. - Text encoded in an old charset such as Windows-1252 or ISO-8859-1. The letter
ébecomes%E9there, which is not valid UTF-8. This decoder reads UTF-8 only, which is what modern URLs use. - A link cut short, so that a sequence like
%C3lost its second half.
Decode in code
// JavaScript
decodeURIComponent('caf%C3%A9%20%26%20tea'); // "café & tea"
// PHP
rawurldecode('caf%C3%A9%20%26%20tea'); // keeps +
urldecode('caf%C3%A9+%26+tea'); // + becomes a space
# Python
from urllib.parse import unquote, unquote_plus
unquote('caf%C3%A9%20%26%20tea') # 'café & tea'
unquote_plus('caf%C3%A9+%26+tea') # + becomes a space
A note on security
Attackers hide paths and scripts in encoded text, for example %2e%2e%2f for ../. Decoding here is a good way to see what a suspicious link really contains. In your own code, decode once, then validate, and never decode a second time after checking.
See also the URL encoder, the percent-encoding byte breakdown, the query string parser, and the URL encoding guide. For page text with & and similar codes, use HTML decode.