HTML Form Methods: GET and POST
When a visitor presses Submit, the browser sends the form's data to a server. But how it sends the data is your choice, and it matters. The method attribute decides between two ways: GET and POST.
Choose well, and your forms are easy to bookmark, safe to refresh, and careful with private data. Choose badly, and you can leak passwords into web addresses, or double-charge a customer. This lesson explains both methods clearly, with a simple rule for choosing.
What You Will Learn
- What the
methodattribute does, and its default - How GET and POST differ, with the data visible in a live demo
- How URL encoding works
- When to use GET, and when to use POST
- The Post, Redirect, Get pattern
method="dialog", and why HTML forms cannot send PUT or DELETE- Privacy and security notes, including CSRF
The Basics
- HTML Code
- Browser Output
<!-- A search form: GET -->
<form action="/search" method="get">
<label for="q">Search</label>
<input type="search" id="q" name="q" />
<button type="submit">Search</button>
</form>
<!-- A sign-up form: POST -->
<form action="/signup" method="post">
<label for="email">Email address</label>
<input type="email" id="email" name="email" required />
<button type="submit">Join</button>
</form>
Both forms look the same to the visitor. The difference is what happens behind the scenes.
- If you leave out
method, the default isget. - The value is not case-sensitive (
POSTandpostboth work), but lowercase is the usual style. - Any other value is treated as
get.
GET: Data in the URL
With GET, the browser adds the form data to the end of the address, after a ?. This is called the query string.
If a visitor types html forms into the search box above, the browser goes to:
https://example.com/search?q=html+forms
Each field becomes name=value, and several fields are joined with &:
/search?q=html+forms&page=2&sort=newest
| About GET | What it means |
|---|---|
| Data is visible in the URL | Anyone looking at the screen, the history, or the logs can read it |
| The page can be bookmarked and shared | The whole search is saved in the link |
| The back button and refresh are safe | Repeating a GET should change nothing |
| Browsers and servers may cache it | Fast, but not for private or changing data |
| The URL has a length limit | Around 2,000 characters is a safe maximum |
| Cannot send files | File uploads need POST |
What URL Encoding Does
A web address can only hold a small set of safe characters. So the browser encodes everything else. A space becomes + (or %20), and special characters become % followed by a code.
Type something below, and see how it would travel:
- HTML Code
- Browser Output
<form action="/search" method="get">
<label for="name">Type text with spaces, accents, and symbols</label>
<input type="text" id="name" name="name" value="Zoë & Ana = 100% #1?" />
<button type="submit">Send</button>
</form>
const params = new URLSearchParams();
params.append("name", "Zoë & Ana = 100% #1?");
console.log(params.toString());
// name=Zo%C3%AB+%26+Ana+%3D+100%25+%231%3F
You never have to do this yourself. The browser encodes on the way out, and your server framework decodes on the way in. It matters in two places: when you build links by hand (use encodeURIComponent in JavaScript), and when you wonder why a URL looks strange. The & and = inside the value are encoded, so they cannot be mistaken for separators.
POST: Data in the Body
With POST, the data is placed in the body of the request, not in the address. The URL stays clean:
POST /signup HTTP/1.1
Content-Type: application/x-www-form-urlencoded
email=ada%40example.com
| About POST | What it means |
|---|---|
| Data is not in the URL | It stays out of the history, bookmarks, and most address logs |
| It is meant to change something | Create an account, place an order, send a message |
| Refreshing asks "Resubmit the form?" | Repeating it may do the action twice |
| Not cached, cannot be bookmarked | Each submission is a new action |
| No practical size limit (the server sets one) | Good for long text and files |
| Can send files | With enctype="multipart/form-data" |
Keeping data out of the URL does not make it secret. The body can still be read by anyone on the network if the site uses plain http. Always serve forms over HTTPS, whichever method you use.
Try It: See the Request
Choose a method and press the button. The demo does not send anything; it shows what the browser would send.
- HTML Code
- Browser Output
<form action="/search" method="get" id="f">
<input type="text" name="q" value="café & tea" />
<input type="number" name="page" value="1" min="1" />
<button type="submit">Send</button>
</form>
// Show what a GET and a POST would carry (nothing is sent here)
const form = document.getElementById("f");
const params = new URLSearchParams(new FormData(form));
console.log("GET /search?" + params.toString());
console.log("POST /search body: " + params.toString());
The same data is sent in both cases. Only the place changes: the address for GET, the body for POST.
Which One Should You Use?
A simple rule: GET asks, POST does.
| Use GET when... | Use POST when... |
|---|---|
| The form looks something up: search, filter, sort, paginate | The form changes something: sign up, order, comment, delete |
| Repeating it is harmless | Repeating it could cause harm (a double charge) |
| The result is worth bookmarking or sharing | The data is private (passwords, personal details) |
| The data is short and not sensitive | The data is long, or includes files |
Real examples:
| Form | Method | Why |
|---|---|---|
| Site search | get | Shareable results page |
Filters on a shop (?color=red&size=m) | get | Bookmarkable, back button works |
| Log in | post | Password must stay out of the URL |
| Sign up | post | Creates an account, private data |
| Checkout | post | Creates an order |
| Contact form | post | Sends a message, private |
| Upload a photo | post | Files need a body |
| Change password | post | Changes state, sensitive |
Post, Redirect, Get
After a POST, never answer with a normal page, or refreshing will resubmit the form. Instead, the server should answer with a redirect to a new page (usually "Thank you"), which is loaded with GET:
1. Visitor submits the form POST /order
2. Server saves the order and replies "redirect to /order/123/thanks"
3. Browser loads the new page GET /order/123/thanks
Now refreshing only reloads the thank-you page. The order is not placed twice. This is called Post, Redirect, Get (PRG), and it is good practice for every form that changes something.
For extra safety against double clicks and network retries, servers can also use a unique token per form, so the same submission is only accepted once.
Forms and Other Methods
method="dialog"
Inside a <dialog>, a form with method="dialog" closes the dialog instead of sending anything to a server:
<dialog id="confirm">
<form method="dialog">
<p>Delete this file?</p>
<button value="cancel">Cancel</button>
<button value="ok">Delete</button>
</form>
</dialog>
The dialog's returnValue becomes the value of the button that was pressed.
PUT, PATCH, and DELETE
HTML forms can only send GET and POST. Any other value in method (such as put or delete) is treated as get. For other methods, you have two options:
- Use JavaScript:
fetch("/items/5", { method: "DELETE" }). - Use a method override: a hidden field such as
<input type="hidden" name="_method" value="delete">, which many server frameworks understand and turn into the real method on the server. This is a framework feature, not part of HTML.
Changing the method for one button
A submit button can override the form's method with formmethod:
<form action="/items" method="post">
<button type="submit">Save</button>
<button type="submit" formmethod="get" formaction="/preview">Preview</button>
</form>
Accessibility at a Glance
- Warn about resubmission if your server does not use PRG, or better, use PRG so the question never appears.
- Make results pages shareable for search and filter forms (GET), so keyboard and screen reader users can bookmark and return to them.
- Keep the visitor's input when the server sends the form back with errors, whichever method is used.
- Tell visitors when something is sent, with a clear confirmation page or message, and move focus to it.
- Do not make a GET request do a destructive action (like a "delete" link). Browser tools such as prefetching and search bots can follow links, and so can accidentally trigger it.
Security Notes
- Never put secrets in a GET form. Passwords, tokens, and personal details in the URL end up in browser history, server logs, proxy logs, bookmarks, and the
Refererheader sent to other sites. A login form withmethod="get"is a serious mistake. - GET must never change data. Browsers, link checkers, and crawlers assume GET is safe to repeat. A "delete account" link or a "like" button that works by GET can be triggered by accident, or by an attacker.
- POST forms need CSRF protection. A malicious page can make a visitor's browser submit a POST to your site while they are signed in. Defend with a CSRF token in a hidden field,
SameSitecookies, and checks on theOriginheader. (See Hidden.) - Use HTTPS for every form, so data is encrypted in transit, whichever method is used.
- Validate on the server whichever method is used. Both GET parameters and POST fields can be changed by anyone.
- Limit sizes on the server, for both URLs and bodies.
- Watch for user input shown back on the page. Escape it, to prevent cross-site scripting.
See Secure Form Design.
Global Audience Notes
- Encoding handles every language. Browsers send text as UTF-8, so names and messages in any script travel safely, but your server must read them as UTF-8, too. A mismatch gives garbled characters.
- Long URLs are a problem in some regions and networks. Avoid putting large amounts of text in GET.
- Shared links from GET forms may contain the visitor's language, filters, and search terms. Think about whether that is appropriate to share.
- Slow and unreliable connections make double submits more likely. PRG and server-side duplicate checks protect your visitors.
- Mobile browsers may cache GET results heavily. Set sensible cache headers for pages that change.
Common Mistakes to Avoid
- Using GET for login or any private data. Passwords end up in URLs and logs.
- Using POST for search, so results cannot be bookmarked or shared.
- Forgetting
method, and being surprised that data appears in the URL (the default isget). - Responding to a POST with a normal page, so refreshing resubmits the form.
- Changing data with a GET link, such as
/delete?id=5. - Expecting
method="put"or"delete"to work. HTML forms only send GET and POST. - Assuming POST is secure without HTTPS.
- No CSRF protection on forms that change data.
- Sending files without
method="post"andenctype="multipart/form-data". - Building URLs by hand without
encodeURIComponent. - Putting huge text in a GET form, hitting URL length limits.
- Not reading the data as UTF-8 on the server.
Practice Time
Try these in your editor:
- Build a search form with
method="get"and look at the address after submitting. - Change it to
method="post"and see what changes in the address bar. - Remove
methodaltogether, and check what the default does. - Add a second field and see how the query string joins them with
&. - Type an accent, a space, and an
&in a field, and read the encoded URL. - Build a filter form (colour and size) that works as a bookmarkable link.
- Use
URLSearchParamsandFormDatato print what a form would send. - Make a
<dialog>with amethod="dialog"form and readreturnValue. - Add a "Preview" button with
formmethod="get"to a POST form. - Bonus: describe the Post, Redirect, Get steps for a checkout in your own words.
Quick Recap
Click a question to check your answer.
1. What is the default form method, and what does it do?
The default is get. The browser adds the form data to the URL as a query string (?name=value&name2=value2).
2. How does POST differ from GET?
POST sends the data in the request body, not in the URL. It is meant for actions that change something, it is not bookmarked or cached, it has no practical size limit, and it can carry files.
3. What is a simple rule for choosing?
GET asks and POST does. Use GET for lookups that are safe to repeat (search, filters). Use POST for actions that change data or send private information (sign up, login, checkout, uploads).
4. What is Post, Redirect, Get?
After a POST is handled, the server answers with a redirect to a new page loaded by GET. Refreshing then reloads that page and does not submit the form again.
5. Can an HTML form send PUT or DELETE?
No. Forms only send GET or POST, and any other value is treated as GET. Use fetch in JavaScript, or a framework's method override with a hidden field.
6. Does POST make data secure?
No. It only keeps data out of the URL. You still need HTTPS, CSRF protection, and server-side validation.
Key Takeaways
methodacceptsget(the default) orpost. Forms cannot send other HTTP methods, exceptdialogfor closing a<dialog>.- GET puts the data in the URL: visible, bookmarkable, cacheable, length-limited, and safe to repeat. Use it for searching and filtering.
- POST puts the data in the body: not in the URL, no practical limit, able to carry files. Use it for actions and private data.
- The browser URL-encodes values for you (spaces, accents, and symbols).
- Use Post, Redirect, Get so refreshing never repeats an action.
- Never send secrets by GET, never change data with GET, and protect POST forms against CSRF.
- Use HTTPS, and validate on the server, whichever method you choose.
Next, learn where the data goes, in Form Action, or return to the Forms overview.