devkult_
tools30converters34
home/mime/application/x-www-form-urlencoded

application/x-www-form-urlencoded

URL-encoded form datarequest body

application/x-www-form-urlencoded

The default encoding for HTML form posts: fields joined as key=value pairs with &, in the same format as a URL query string.

MIME typeapplication/x-www-form-urlencoded
Used forRequest body
ParametersNone — non-ASCII characters are always UTF-8 percent-encoded
SpecificationWHATWG URL Standard

What it looks like on the wire

POST /comment HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

name=Ada&comment=c%C3%A0t+%26+dog&notify=on
Content-Type: application/x-www-form-urlencoded

Send it

HTML form (the default enctype)
<form action="/comment" method="post">
  <input name="name">
  <textarea name="comment"></textarea>
  <input type="checkbox" name="notify">
  <button>Send</button>
</form>
fetch with URLSearchParams
// URLSearchParams encodes the body and sets the Content-Type for you.
const body = new URLSearchParams({ name: "Ada", comment: "càt & dog" });
await fetch("/comment", { method: "POST", body });
curl
curl -d name=Ada --data-urlencode "comment=càt & dog" https://example.com/comment

Receive it

Express
app.use(express.urlencoded({ extended: false }));

app.post("/comment", (req, res) => {
  // req.body.name, req.body.comment
});
Web standard Request
const form = await req.formData(); // parses urlencoded and multipart bodies
const name = form.get("name");
Python (Flask)
name = request.form["name"]
tags = request.form.getlist("tag")
PHP
$name = $_POST['name'];

Good to know

  • Spaces become + in form bodies but %20 with encodeURIComponent(). A decoder that doesn't treat + as a space — plain decodeURIComponent() — turns "càt & dog" into "càt+&+dog".
  • An unchecked checkbox isn't sent at all; a checked one without a value sends on.
  • Parsers disagree on repeated keys (tag=a&tag=b): Node returns an array, PHP keeps the last value unless the name ends in [], and Flask's request.form["tag"] returns the first (use getlist).
  • Every non-ASCII byte becomes three characters, so it's a poor fit for binary data. Use multipart/form-data for files.

Useful here: URL encoder · URL encoding explained

Frequently asked questions

Is application/x-www-form-urlencoded the same as a query string?

Same format, different place. A GET form puts the encoded fields in the URL's query string; a POST form sends them as the request body with this Content-Type. One detail differs from encodeURIComponent(): the form encoding writes spaces as +.

Do I need a charset parameter?

No. The WHATWG spec defines the type without parameters, and the bytes are always UTF-8 percent-encoded. Browsers' fetch adds ;charset=UTF-8 anyway, and servers ignore it.

How do I send x-www-form-urlencoded with fetch?

Pass a URLSearchParams object as the body. fetch encodes it and sets the Content-Type. Sending a JSON string with this header gives the server one garbled field instead.

Related types

Headers that go with it: Content-Type