Lesson 5

The Plus Sign in Form Data

Why `+` sometimes means space and `%20` vs `+` in query strings.

Spaces in URLs historically caused trouble, so application/x-www-form-urlencoded (used by default HTML <form method="GET">) encodes spaces as + in the serialized body or query substring:

<form>
  <input name="msg" value="hello world">
</form>
<!-- Submitted URL might contain: ?msg=hello+world -->

That is not the same rule as generic URI percent-encoding in every tooling path: many URI processors treat + as a literal plus unless explicitly using form-urlencoded semantics.

?msg=a+b           // Might decode to "a b" OR "a+b" depending on parser mode
?q=city%20hall     // Unambiguous URI percent-encoding for ASCII space (%20)

JavaScript helpers

URLSearchParams

const p = new URLSearchParams("a=b+c");
console.log(p.get("a")); // Likely interprets '+' as space in form mode

Creating from an object preserves form rules when stringifying:

new URLSearchParams({ tag: "a+b" }).toString(); // Might emit a%2Bb or tag=a%2Bb pattern depending on internals for '+'
console.log(String(new URLSearchParams({ expr: "1+2" })));

When you rely on interoperable literals, explicitly percent-encode plus signs (%2B) if they must survive as plus.

Manual decoding mistakes

Applying decodeURIComponent alone assumes percent sequences only—it does not convert '+':

decodeURIComponent('a+b');           // stays "a+b"
decodeURIComponent('a+b'.replace(/\+/g, " ")); // manual form-style fix—only when correct for your layer

Server frameworks

Popular stacks expose toggles (application/x-www-form-urlencoded parsers vs raw query parsers). Middleware order matters:

  1. Parse query as URI component semantics.
  2. Parse as HTML form semantics with + → space rules.

Misconfiguration causes bugs like hashed tokens breaking when '+' flips meanings between environments.

When to encode what

NeedRecommendation
Literal '+' in a form field value crossing URLEncode %2B at value layer
Human-readable '+' in JSON transportPrefer JSON bodies, not queries
Debug loggingCapture raw bytes (req.url) before parsers rewrite

Understanding + helps you classify bugs: duplicate decoding, mismatched parsers, versus genuine user input needing %2B. Pair this mindset with Lesson 4’s warning about brittle split('&') after partial decoding.

When you want to practice, use the related DevCove tool — optional, not part of this lesson.

Open related tool

Back to course overview