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
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:getorpost.
<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.
<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:
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:
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%21an 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 asSimon+%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.
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:
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.
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:
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.