# How a Form Sends Data

A form turns each answer into a name=value pair and sends the pairs to the address in its action, inside the address itself with GET or inside the request with POST.

Apprentice · HTML · Web Development · Updated October 31, 2026

## After this lesson you can

- Explain how a form turns its fields into name=value pairs and where it sends them
- Predict the query string a GET form sends
- Choose between GET and POST for a form

## Key takeaways

- A form packs each answer as a name=value pair, using the field's name, and sends the pairs to the address its action names.
- With method="get", the pairs go in the address after a question mark, joined by ampersands, where anyone can see them.
- With method="post", the pairs travel in the request body instead, out of the address bar, history and shared links.
- A field with no name is not sent at all. It's the most common reason a form "sends nothing".
- Use GET for searches and filters, and POST for anything private or anything that changes data, such as a sign-up or an order.

Every sign-up, search box, pizza order and "contact us" page you've ever used is a **form**. When you build one, for a class project, a club's website or your first job, the question that matters is: when someone presses the button, what exactly gets sent, and where? And when a form "doesn't work", the answer is almost always in what it sent.

Think of a song request slip at a radio station's booth at the county fair. Each blank has printed words beside it ("Your name", "Song") so you know what to write. And whoever reads the slips later knows which answer is which, because each box has its own name. A web form works the same way: words for the person filling it in, and a name on every box for the computer that reads the answers.

This chapter builds the request line for **Radio Ridgeview 101.5**, a made-up local radio station.

## The form element

A form starts with the `<form>` element. Everything the visitor fills in, and the button they press, goes between its opening and closing tags. Two attributes say what happens to the answers:

- **`action`**: where the answers go: the address of the page or program that receives them.
- **`method`**: how they travel there: `get` or `post`.

```html
<form action="received.html" method="get">
  <!-- the boxes to fill in, and a button, go here -->
</form>
```

Read it as "a form that sends its answers to `received.html`, by GET".

Here is the station's request form. It has two boxes, made with `<input>`, each with words beside it, made with `<label>`. You'll meet both properly in the next lesson, *Text Inputs and Labels*, and the `<button>` in *Buttons*. For now, watch the `name` attributes.

```html
<form action="received.html" method="get">
  <label for="listener">Your name</label>
  <input type="text" id="listener" name="listener">

  <label for="song">Song</label>
  <input type="text" id="song" name="song">

  <button type="submit">Send my request</button>
</form>
```

## Each answer becomes a name=value pair

When the visitor presses the button, the browser goes through the form's boxes in order. For each one, it takes the box's `name` and whatever the visitor typed, the **value**, and joins them with `=` (read "equals"). That's a **name=value pair**. If Maya asks for "Yellow", the form makes these two pairs:

```text
listener=Maya
song=Yellow
```

The name is the box's label for the computer. A program on the other end reads `song` to find the song, so the name is a promise between your form and that program: change it, and the program can't find the answer anymore.

A box with **no `name` isn't sent at all**. When the song box above loses its `name`, the browser sends only `listener=Maya`, and the song quietly disappears. If a form ever "sends nothing" for one field, check its `name` first.

## GET: the answers ride in the address

With `method="get"`, the browser puts the pairs at the end of the `action` address and goes there. The station's full form has two more boxes, named `artist` and `shoutout`. Maya asked for "Here Comes the Sun" by The Beatles, with a shout-out for her grandpa, and a real run in Chrome went to this address:

```text
received.html?listener=Maya&song=Here+Comes+the+Sun&artist=The+Beatles&shoutout=Happy+birthday%2C+Grandpa%21
```

Read it piece by piece:

- **`?`** (read "question mark") marks where the address ends and the answers begin. Everything after it is the **query string**.
- **`&`** (read "ampersand", the symbol for "and") separates one pair from the next.
- **`+`** stands for a space, because an address can't hold spaces.
- **`%2C`** (read "percent two C") is a comma, and `%21` an exclamation mark. Characters that would confuse an address are written as `%` and a two-character code. That's called **percent-encoding**. It's why "Simon & Garfunkel" arrives as `Simon+%26+Garfunkel`: a bare `&` would look like the start of the next pair.

You've seen query strings before: search for "bike helmets" on a shopping site, and the address ends with something like `?q=bike+helmets`. Because the answers are in the address, you can bookmark that search or send the link to a friend.

**Try it.** Make a page with the request form above, but leave out the `action` attribute. A form with no `action` sends to its own page. Open it with Live Server, type a name and a song with spaces in it, and press the button. Look at the address bar: your answers are on the end, after the `?`.

In *Exercise: A Song Request Form*, the starter has a ready-made page, `received.html`, that shows what a GET form sent as a table: one row per name=value pair, with the `+` and `%` codes turned back into the characters you typed.

![The received.html page after Maya's request: a table with four rows, listener Maya, song Here Comes the Sun, artist The Beatles and shoutout Happy birthday, Grandpa!, showing that each box's name and its answer arrived as a pair](https://www.ask-codey.com/lessons/TODO)

## POST: the answers ride inside the request

When you press a form's button, your browser sends a **request** to the server, the message that says "give me this page" (the lesson *How a Browser Shows a Page* explains requests). A request can carry a **body**: a part after the address and the headers, like the letter inside an envelope.

With `method="post"`, the pairs go in the body, and the address stays clean. The same form, sent by POST in a real run, went to plain `received.html` and carried this body:

```text
listener=Maya&song=Here+Comes+the+Sun&artist=The+Beatles&shoutout=Happy+birthday%2C+Grandpa%21
```

It's the same pairs in the same format. Only the place changed: they're no longer in the address bar, the browser's history, or a link someone copies.

POST isn't a lock, though. Anyone who opens the developer tools can read the body, and a program could read it on the way if the page weren't using `https://`. What keeps data safe on the way is the `s` in `https://`, which scrambles both the address and the body. POST keeps the answers out of sight; HTTPS keeps them secret.

## Seeing it in the Network panel

The developer tools show exactly what a form sent. In Chrome or Edge, press **F12** (on a Mac, **Cmd+Option+I**) and open the **Network** panel. Then send the form and click the request for `received.html` in the list.

- **Payload** shows the pairs: under **Query String Parameters** for GET, and under **Form Data** for POST. Click **view source** to see them as one line, exactly as they were sent.
- **Headers** shows the **Request Method**, GET or POST.

Firefox shows the same pairs on the request's **Request** tab, and Safari on its **Headers** tab, under *Query String Parameters* or *Request Data*.

**Try it.** Change your form to `method="post"`, open the Network panel, and send it. With Live Server, Chrome shows *This page isn't working* and *HTTP ERROR 405*, which means "method not allowed". That's expected: Live Server only hands out files, and nothing on your computer is waiting to read posted answers. Your answers still left the browser. Find them under **Payload**, in **Form Data**.

![Chrome's Network panel after a POST: the received.html request is selected, its status is 405, and the Payload tab lists listener, song, artist and shoutout under Form Data, showing that the answers were sent even though the page answered with an error](https://www.ask-codey.com/lessons/TODO)

## GET or POST?

Ask what the form does with the answers:

- **GET** is for asking: searches, filters, "show me bus times for Route 9". Nothing changes on the server, and the answers in the address let people bookmark and share the results.
- **POST** is for sending something that changes data or is private: a sign-up, an order, a message, a song request added to the station's list, and every login.

**Never send a password by GET.** Here's what a login form sent with GET puts in the address bar:

```text
received.html?user=dj_maya&password=not-a-real-one
```

That address goes into the browser's history, into the server's logs, and onto the screen for anyone standing behind you.

If a form has no `method` attribute, it sends by GET, and if it has no `action`, it sends to its own page. Writing both every time means nobody has to remember the defaults.

## Check yourself

2 questions to try on the lesson page.

## So what

Every form on the web, from a search box to a checkout, comes down to name=value pairs sent somewhere by GET or POST. Once you can read those pairs in the address or the Network panel, a form that "doesn't work" stops being a mystery.

## Key terms

- [Form](https://www.ask-codey.com/glossary/form)
- [Form action](https://www.ask-codey.com/glossary/form-action)
- [Form method](https://www.ask-codey.com/glossary/form-method)
- [GET form](https://www.ask-codey.com/glossary/get-form-submission)
- [POST form submission](https://www.ask-codey.com/glossary/post-form-submission)
- [Query String](https://www.ask-codey.com/glossary/query-string)

## Cheat sheets

- [How a Form Sends Data](https://www.ask-codey.com/cheat-sheets/html-forms-how-a-form-sends-data-cheat-sheet)

## Related

- [Text Inputs and Labels](https://www.ask-codey.com/lessons/html-forms-text-inputs-and-labels)
- [Buttons](https://www.ask-codey.com/lessons/html-forms-buttons)

Source: https://www.ask-codey.com/lessons/html-forms-how-a-form-sends-data
