Comparison

URL Encoding vs HTML Encoding

They protect against different things. URL encoding replaces characters that have meaning in a URL — spaces, ampersands, question marks — with percent escapes such as %20. HTML encoding replaces characters that have meaning in markup with entities such as & and <. A value going into a link inside a page needs both, applied in that order.

URL Encoder and Decoder

Percent-encode text for URLs, or decode it back.

Open the tool

The two are confused because both turn an ampersand into something longer. They are answering different questions: URL encoding asks how a value survives being part of a URL, and HTML encoding asks how a value survives being part of a document.

The case that trips people is a value that has to do both — a search term placed into an href. It is percent-encoded because it is inside a URL, and the resulting URL is then entity-encoded because it is inside an HTML attribute.

What URL encoding is for

Percent-encoding exists so that a value cannot be mistaken for URL structure. Without it, an ampersand inside a search term starts a new query parameter and a question mark starts the query string early.

  • Space becomes %20, or + inside a query string.
  • Ampersand becomes %26 so it does not separate parameters.
  • Question mark becomes %3F so it does not begin the query.
  • Slash becomes %2F so it does not create a path segment.
  • Applied per value, never to a whole assembled URL.

What HTML encoding is for

Entity encoding exists so that a value cannot be mistaken for markup. Without it, a less-than sign starts a tag, and user-supplied text becomes executable — the mechanism behind most cross-site scripting.

  • Less-than becomes < so it cannot open a tag.
  • Greater-than becomes > so it cannot close one.
  • Ampersand becomes & so it does not begin an entity.
  • Double quote becomes " so it cannot end an attribute.
  • Applied when text is written into a document, not when it is stored.

What happens when you pick the wrong one

The failures are asymmetric. Using HTML encoding where URL encoding belongs produces a broken link; using URL encoding where HTML encoding belongs produces a security hole, because percent-encoding does not neutralise a less-than sign in a document.

  • HTML-encoding a URL sends the literal text & to the server, so the parameter name gains "amp;".
  • URL-encoding a page value leaves %3Cscript%3E, which is inert as markup but displays as gibberish.
  • Neither is a substitute for the other, and neither protects a SQL query.
  • Double-encoding is its own bug: %2520 is an encoded percent sign, not a space.

The order when a value needs both

Encode for the innermost context first and work outwards. A search term inside a link is percent-encoded because it sits in a URL, and the finished URL is then entity-encoded because it sits in an attribute. Reversing the order corrupts the value.

Example

The search term "tea & coffee" placed into a link. Both encodings apply, in order.

Raw value

tea & coffee

In an href

percent-encoded:  tea%20%26%20coffee
then in markup:  <a href="/s?q=tea%20%26%20coffee">

Frequently asked questions

What is the difference between URL encoding and HTML encoding?
URL encoding uses percent escapes to stop a value being read as URL structure. HTML encoding uses entities to stop a value being read as markup. Different destinations, different reserved characters, and neither substitutes for the other.
Which do I use for a query string value?
URL encoding, applied to each value individually. If that URL is then written into a page, entity-encode the finished URL as well — the two steps are separate and both are needed.
Does URL encoding prevent XSS?
No. Percent-encoding is about URL structure, not markup. Text written into a page must be HTML-encoded, or a less-than sign will still open a tag. Using the wrong one here is a security bug rather than a cosmetic one.
Why does my parameter name have "amp;" in it?
Because the URL was HTML-encoded when it should not have been, so &amp; was sent literally and the server read the next parameter as amp;name. Encode the values, not the separators.
Is + the same as %20?
Only inside a query string, where both mean a space by convention. In a path segment + is a literal plus sign, which is why encoding a whole URL rather than its individual values causes such confusing bugs.

Tools used in this guide

All tools →
All guides →

Last reviewed .