Why does HTML5 form-validation allow emails without a dot?

HtmlEmail Validation

Html Problem Overview


I'm writing a very simple mock-up to demonstrate some HTML5 form-validation. However, I noticed the email validation doesn't check for a dot in the address, nor does it check for characters following said dot.

In other words, "john@doe" is considered valid, when it's clearly not a valid email address; "doe" isn't a domain.

This is how I'm coding my email field:

<input type="email" required />

Is that not enough?

Check this fiddle to see what I mean.

Note: I know how to accomplish this via a RegEx pattern instead. I'm just wondering how someone could get away with using the email type instead.

Html Solutions


Solution 1 - Html

You can theoretically have an address without a "." in.

Since technically things such as:

user@com
user@localserver
user@[IPv6:2001:db8::1]

Are all valid emails.

So the standard HTML5 validation allows for all valid E-mails, including the uncommon ones.

For some easy to read explanations (Instead of reading through the standards): http://en.wikipedia.org/wiki/Email_address#Examples

Solution 2 - Html

Because a@b is a valid email address (eg localhost is a valid domain). See http://en.wikipedia.org/wiki/Email_address#Examples

Also, keep in mind that you should always do the input validation in server. The client side validation should be only for giving feedback to the user and not be relied on, since it can be easily bypassed.

Solution 3 - Html

Try adding this to the input

pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,63}$"

Fiddle

Solution 4 - Html

The RFC 822, chapter 6, gives the specification of an address in augmented Backus-Naur Form (BNF):

addr-spec   =  local-part "@" domain
local-part  =  word *("." word)
domain      =  sub-domain *("." sub-domain)

Using this specification a@b is a valid address.

UPDATE

To answer the comment of Trejkaz, I add the following definitions. We see that SPACE are allowed but only in quoted string.

word          =  atom / quoted-string
atom          =  1*<any CHAR except specials, SPACE and CTLs>
quoted-string = <"> *(qtext/quoted-pair) <">
SPACE         =  <ASCII SP, space>
CTL           =  <any ASCII control character and DEL> 
qtext         =  <any CHAR excepting <">, "\" & CR, and including linear-white-space>
quoted-pair   =  "\" CHAR  

Solution 5 - Html

This MDN page shows the regex browsers should use to validate the email:

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email#Validation

You can slightly change this regex to require at least one dot in the domain name: change the star * at the end of the regex to a plus +. Then use that regex as the pattern attribute:

<form>
  <input
    type="email"
    pattern="^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$"
    title="Valid e-mail address including top-level domain"
    required
  />
  <button type="submit">Test</button>
</form>

Solution 6 - Html

You can customize the pattern of the email field:

input:valid {
  border-color: green
}

input:invalid {
  border-color: red
}

Email:
<input type="email" required value="[email protected]" /><br>

Non-dots Email:
<input type="email" required pattern="[^.]+@[^.]+" value="[email protected]" />

Solution 7 - Html

Here is how you can do it with html5 using regex pattern. You can also include a custom message to display.

<form>
  <input type="email" value="paul@test" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,63}$" title="Hey, you are missing domain part in the email !!!"/>
  <button type="submit">Click Me</button>
</form>

Solution 8 - Html

PHP

Emails without a TLD are, technically, valid. That's why browser validation "fails", so to speak.

If you're processing your form data with PHP, here's a simple back-end validation set-up the covers both your email and required fields:

if (empty($required_field) OR empty($another_required_field) OR
    !filter_var($email_field, FILTER_VALIDATE_EMAIL)) {
    // error handling here
	exit;
	}

FILTER_VALIDATE_EMAIL doesn't allow for dotless domain names.

So while the "malformed" email may get passed the browser, it won't get passed the server.


References:

Solution 9 - Html

This pattern always works for me.

Text must in lowercase pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" but I think it covers more or less most emails.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWEFXView Question on Stackoverflow
Solution 1 - HtmlDBSView Answer on Stackoverflow
Solution 2 - HtmlAli AlaviView Answer on Stackoverflow
Solution 3 - HtmlAPAD1View Answer on Stackoverflow
Solution 4 - HtmlOrtomala LokniView Answer on Stackoverflow
Solution 5 - HtmlgitaarikView Answer on Stackoverflow
Solution 6 - HtmlDorianView Answer on Stackoverflow
Solution 7 - HtmlHari DasView Answer on Stackoverflow
Solution 8 - HtmlMichael BenjaminView Answer on Stackoverflow
Solution 9 - HtmlTSlegaitisView Answer on Stackoverflow