Topic 4.1
How Forms Work
In one line
A <form> collects the values of its named controls and, when submitted, sends them to the URL in action using the HTTP method in method: GET puts them in the URL, POST puts them in the request body.
Think of it like this
Filling in a paper form at the post office. Each box has a printed label ("Name", "Address"). You write in the boxes, then hand the whole sheet to the clerk at a particular counter. The form is the sheet, each box is a control, the printed box name is the name attribute, and the counter you hand it to is the action URL.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Form
- The
<form>element: a group of controls whose values are sent together. - Control
- Something a person fills in or chooses, such as an
<input>,<select>,<textarea>or<button>. - Submit
- To send the form: the browser gathers the values and makes a request to the server.
- action
- The form attribute that holds the URL the data is sent to.
- method
- The form attribute that picks how data is sent:
get(in the URL) orpost(in the request body). - name attribute
- The label a control's value is sent under. No name means the value is not sent.
- Query string
- The part of a URL after
?, made ofname=valuepairs joined by&. - Percent-encoding
- Writing special characters as
%plus a code, like%26for&, so they can travel safely in a URL. - Request body
- The data part of an HTTP request, sent after the headers. POST forms put their pairs here.
Step by step
01A form with one field
Here is the smallest useful form: a search box and a button. The <input> has name="q" (short for query), so its value is sent as q=.... The button submits the form when clicked.
<form action="/search" method="get">
<input name="q">
<button>Search</button>
</form>02Submitting with GET
Type cats & dogs and press the button. The browser builds the query string q=cats+%26+dogs (the space became +, the & became %26) and goes to /search?q=cats+%26+dogs.
The server reads the query string, finds the results and sends back a new page. You can bookmark that URL and get the same search later.
GET /search?q=cats+%26+dogs HTTP/1.1
Host: example.com03Submitting with POST
Change the form to method="post" and add a password field. Now the URL is only /login, and the pairs travel in the body. The Content-Type header tells the server how the body is packed.
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
user=asha&password=s3cret04What decides what gets sent
The browser walks the form's controls in page order and keeps a pair for each one that has a name, is not disabled, and (for checkboxes and radio buttons) is ticked. Everything else is left out. The button that was clicked is also sent if it has a name.
05The round trip
After a normal submit, the browser leaves the page and shows whatever the server answers. That is why, later in the JavaScript course, you'll learn to stop the default submit with event.preventDefault() and send the data with fetch instead, so the page can stay put.
Try it yourself
- 1
Predict the query string
In the first example, change the
qvalue to100% cotton. Before you run it, write down what you think the query string will be. Then run it. (The%itself must be encoded, as%25, and the space becomes+:q=100%25+cotton.) - 2
Give the nameless field a name
Add
name="note"to the third input in the first example. Predict where the new pair appears in the query string, then run it. Pairs follow the order of the fields in the page. - 3
Enable the disabled field
In the second example, remove
disabledfrom therefinput. Run it:ref = homenow appears in the console and in the body.
Code & diagrams
`FormData` collects exactly what the browser would send. Press Search too: the preview logs the submitted pairs instead of leaving the page.
Preview
Console
Nothing logged yet.Expected console output
Method: get
Action: /search
Query string: q=cats+%26+dogs&lang=en
Full URL: /search?q=cats+%26+dogs&lang=enThe disabled `ref` field is not sent. `requestSubmit()` submits the form the same way a click on the button does.
Preview
Console
Nothing logged yet.Expected console output
Method: post
user = asha
password = s3cret
Body would be: user=asha&password=s3cretBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Forget the name attributes
In the second example, delete the form.requestSubmit(); line and remove name="user" and name="password", then click Log in.
Break #2
Send a password with GET
Change a login form to method="get" and submit it on a real site you run locally.
Myth vs fact
Myth
POST is secure and GET is not.
Fact
Both are sent in plain text unless the page uses HTTPS. POST only keeps the data out of the URL, history and logs; HTTPS is what encrypts it.
Myth
Every input in the form is sent.
Fact
Only controls with a name that are not disabled are sent, and checkboxes and radio buttons only when ticked.
Myth
You need JavaScript to send a form.
Fact
HTML forms submit on their own. JavaScript is optional, used when you want to stay on the page or check things first.
Myth
The id attribute is what the server receives.
Fact
The server receives the name. id is for labels, CSS and JavaScript inside the page.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
When
method="get", the browser replaces any query string already inaction:action="/s?x=1"losesx=1. Put fixed values in hidden inputs instead (Topic 4.5). - ▸
Reloading a page that was the answer to a POST asks "Confirm form resubmission", because repeating it could, say, place an order twice. Servers avoid this with Post/Redirect/Get: answer the POST with a
303 See Otherredirect to a normal GET page. See the System Design course (/system-design) for idempotency and HTTP methods. - ▸
FormDatais the browser's own algorithm for "what would be submitted" (it is the spec's form data set).new FormData(form, submitter)also includes the clicked button's pair.URLSearchParamsproduces the sameapplication/x-www-form-urlencodedstring the browser sends. - ▸
There is no fixed URL length limit in the HTML spec, but servers and proxies often reject URLs over about 8 KB, so large or many fields belong in a POST body.
Remember this
- 1
A form is the
<form>element plus the controls inside it. A control is anything a person can fill in or choose:<input>,<select>,<textarea>,<button>. When the form is submitted (sent), the browser gathers the controls' values and makes an HTTP request to a server, just like clicking a link, except it carries data with it. - 2
The
actionattribute is the URL the data is sent to, for exampleaction="/search". If you leave it out, the form is sent to the address of the current page. Themethodattribute is the HTTP method:get(the default) orpost. (There's alsomethod="dialog", which closes a<dialog>instead of sending anything; you met<dialog>in Topic 2.6.) - 3
Only controls with a **
nameattribute are sent. Each one becomes a name/value pair** such asq=cats. A control without anameis still shown and can be typed into, but its value never leaves the page. Disabled controls, unticked checkboxes and unselected radio buttons are skipped too. The browser builds this list in the order the controls appear in the page. - 4
With GET, the pairs are joined with
&and added to the URL after a?. That part of the URL is the query string:/search?q=cats&lang=en. Spaces become+and characters with special meaning, like&or=, are percent-encoded (&becomes%26) so the server can split the pairs correctly. GET results can be bookmarked, shared and cached, which is perfect for searches and filters. - 5
With POST, the same pairs travel in the request body, the part of the HTTP request after the headers, and the URL stays clean. Use POST for anything that changes something on the server (sign up, place an order, post a comment) and for anything private, like passwords, which must never end up in a URL, browser history or server logs. POST is not encryption: only HTTPS protects the data on the way.
- 6
How the pairs are packed is set by
enctype(encoding type). The default,application/x-www-form-urlencoded, is thename=value&name=valueformat. File uploads needenctype="multipart/form-data", which sends each field as a separate part (Topic 4.5). Whatever the format, the server receives plain text it must check: the browser never guarantees what arrives (Topic 4.7).
Explain it without notes
Walk through what happens when someone presses Submit on a form with method="get".
When would you choose GET and when POST for a form? Give an example of each.
Which controls in a form are included in the submitted data, and which are skipped?
Why do spaces and & signs need encoding in a query string?
Practice
Write a GET form that sends a product search to /products with two fields: q (the search text) and sort with the value price. What URL does searching for red shoes produce?
Write a POST form that sends a comment to /comments with fields author and text, and log what it would send using FormData.
Trade-offs
- ↔
GET makes results shareable and cacheable but exposes data in the URL and limits size; POST hides data from the URL and handles large bodies but can't be bookmarked and warns on reload.
- ↔
A plain HTML submit works without JavaScript and is very robust, but reloads the page; submitting with
fetchkeeps the page in place but needs JavaScript and your own error handling.
Done when you can
I can write a form with
actionandmethod.I can say which controls are sent and which are skipped.
I can predict the query string a GET form produces, including encoding.
I can choose between GET and POST and explain why.
I can inspect what a form would send with
FormData.