Why the Server Checks Again

The browser's checks help people fill in a form, but anyone can switch them off, so the server that receives the answers must check every one again.

Journeyman · HTML · Web Development · Updated

After this lesson you can

  • Explain why the server must check a form's answers again, even when the browser already checked them
  • Choose where a check belongs, in the browser to help people, on the server to protect the business, or both

Key takeaways

  • Client-side validation runs in the browser and helps people fix mistakes right away. Server-side validation runs where the answers arrive, and protects the business.
  • Anyone can remove required or pattern in the developer tools, or send answers with no page at all, so the browser's checks are never the last word.
  • novalidate on a form, or formnovalidate on one button, turns the browser's checks off on purpose.
  • Some checks only the server can make, such as whether an email already belongs to a member.

You've added required and pattern to the Peak Fitness sign-up form, and the browser now refuses a missing email. It's tempting to think the answers that arrive are safe. They aren't, and the first time someone signs up for the free week with a plan that doesn't exist, you'll want to know why. It's a question that comes up in web job interviews, and a hole that shows up in many class projects.

Two checks, two jobs

At a grocery store, the cashier counts your items, and the store's system still checks every price when the sale goes through. The cashier's count is quick and friendly. The system's check is the one the store relies on.

A form gets checked in two places too. The client is the browser on the person's phone or computer. The server is the computer that receives the form's answers and does something with them: saves the new member, charges the card, sends the welcome email.

  • Client-side validation checks the answers in the browser, before they're sent. Everything in Built-in Validation is client-side.
  • Server-side validation checks them again on the server, when they arrive.
<!-- Client-side: the browser checks this before sending. -->
<input type="email" id="email" name="email" required>

The server's checks are written in whatever language the server runs (C#, Java, Python, JavaScript and many more), so they aren't in the HTML at all. The HTML only decides what the browser checks.

Anyone can switch the browser's checks off

The page lives on the visitor's computer, so the visitor can change it. Try this on any form with a required field:

  1. Open the page with Live Server and press F12 to open the developer tools.
  2. In the Elements panel, find the <input> with required.
  3. Double-click required, delete it, and press Enter.
  4. Leave the field empty and send the form.

It goes through. The browser checked the page as it was, and you changed the page. The same works for pattern, min, maxlength and the rest.

You don't even need the page. A form only sends name and value pairs, and anyone can send those to the server from a script or a tool, with whatever values they like:

https://peakfitness.example/join?fullName=&email=not-an-email&plan=platinum

The developer tools beside the Peak Fitness form: the required attribute is being deleted from the email field's input element in the Elements panel

Turning the checks off on purpose: novalidate

Sometimes you want the browser to skip its checks. novalidate on the <form> turns them off for the whole form; formnovalidate on one button turns them off only when that button sends it.

<form action="received.html" novalidate>
  ...
</form>

<button type="submit" formnovalidate>Save and finish later</button>

A Save and finish later button is the classic use of formnovalidate: a half-finished form should be saved even with empty required fields. novalidate on a whole form is used when a page's JavaScript shows its own messages instead of the browser's, and by developers who want to test what their server does with bad answers.

Try it. Add novalidate to a form of yours that has a required field, send it empty, and look at what arrives. Then take novalidate out again.

What each side is for

Client-side checks help people: the message appears at once, beside the field, while the person still remembers what they typed. Server-side checks protect the business: they're the one check nobody can skip.

So every rule the browser checks, the server checks again. And some checks only the server can make, because only the server has the information:

Check In the browser On the server
The email has an @ Yes, to help Yes, to protect
The ZIP code is five digits Yes, to help Yes, to protect
This email doesn't already belong to a member No: the browser doesn't have the member list Yes
The plan is Basic, Plus or Premium, at its real price No: anyone can change the page Yes
The promo code hasn't expired No: the browser doesn't know the codes Yes

A form with only server-side checks works, but it's slow and annoying: people find out about every mistake after waiting for a new page. A form with only client-side checks is friendly, and wide open. Good forms have both.

Where JavaScript comes in

HTML's built-in checks look at one field at a time. A page's JavaScript can add checks across fields ("the end date is after the start date", "both passwords match") and write messages in the site's own words; the JavaScript in Depth course teaches that, if you want to go further. Those checks are client-side too, so the server still checks again.

Check yourself

2 questions to try on the lesson page.

So what

The browser's checks are a kindness to the person filling in the form, not a lock on the door. Whenever you build a form, ask what the server does when the browser's checks are gone.

Key terms

Cheat sheets

Related