Cách xác thực địa chỉ email trong JavaScript

Có rất nhiều cách để xác thực một địa chỉ email. Tìm hiểu cách chính xác và cũng tìm ra tất cả các tùy chọn bạn có, sử dụng JavaScript thuần túy

Xác thực địa chỉ email là một trong những thao tác phổ biến mà người ta thực hiện khi xử lý biểu mẫu.

Nó hữu ích trong các biểu mẫu liên hệ, biểu mẫu đăng ký và đăng nhập, v.v.

Một số người gợi ý rằngbạn không nên xác thực emailở tất cả. Tôi nghĩ rằng một chút xác nhận, không cần cố gắng quá sốt sắng, sẽ tốt hơn.

Các quy tắc xác thực email phải tuân theo là gì?

Một địa chỉ email được cấu tạo bởi 2 phần là phần cục bộ và phần miền.

Phần cục bộ có thể chứa

  • bất kỳ ký tự chữ và số nào:a-zA-Z0-9
  • chấm câu:"(),:;<>@[\]
  • ký tự đặc biệt:!#$%&'*+-/=?^_{|}~
  • một dấu chấm., nếu nó không phải là ký tự đầu tiên hoặc cuối cùng. Ngoài ra, nó không thể được lặp lại

Phần miền có thể chứa

  • bất kỳ ký tự chữ và số nào:a-zA-Z0-9
  • dấu gạch nối-, nếu nó không phải là ký tự đầu tiên hoặc cuối cùng. Nó có thể được lặp lại

Sử dụng Regex

Tùy chọn tốt nhất để xác thực địa chỉ email là sử dụngBiểu hiện thông thường.

Không cóphổ cậpkiểm tra email regex. Mọi người dường như sử dụng một cái khác và hầu hết các regex bạn tìm thấy trực tuyến sẽ không thành công trong các tình huống email cơ bản nhất, do không chính xác hoặc thực tế là họ không tính toán các miền mới hơn được giới thiệu hoặc các địa chỉ email được quốc tế hóa

Đừng sử dụng bất kỳ biểu thức chính quy nào một cách mù quáng, nhưng hãy kiểm tra nó trước.

tôi đã làmví dụ này trên Glitchđiều đó sẽ kiểm tra danh sách các địa chỉ email được coi là hợp lệ so với regex. Bạn có thể thay đổi regex và so sánh nó với các regex khác mà bạn muốn sử dụng.

Cái hiện được thêm vào là cái mà tôi cho là chính xác nhất mà tôi tìm thấy, đã được chỉnh sửa một chút để khắc phục sự cố có nhiều dấu chấm.

Lưu ý: Tôi đã không nghĩ ra nó. Tôi đã tìm thấy nó trong một câu trả lời Quora nhưng tôi không chắc đó là nguồn gốc.

Đây là một hàm xác thực bằng cách sử dụng regex đó:

const validate = (email) => {
  const expression = /(?!.*\.{2})^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i

return expression.test(String(email).toLowerCase()) }

Tất cả các trường hợp phổ biến đều được thỏa mãn, người ta có thể cho rằng 99,9% địa chỉ email mọi người sẽ thêm được xác thực thành công.

Mã của trục trặc nàychứa các biểu thức chính quy khác mà bạn có thể dễ dàng thử bằng cách phối lại dự án.

Mặc dù khá chính xác, có một số vấn đề với một số trường hợp cạnh với regex này, bạn có thể sống chung với (hoặc không) tùy thuộc vào nhu cầu của mình.

Phủ định sai cho các địa chỉ kỳ lạ như

"very.(),:;<>[]".VERY."[email protected]\ "very".unusual"@strange.example.com

one.“more\ long”@example.website.place

Phủ định sai cho các địa chỉ địa phương:

[email protected]
[email protected]

of little use in publicly accessible websites (actually a plus in publicly accessible websites to have those denied)

Also, false negative for IP-based emails:

[email protected][2001:DB8::1]
[email protected]

There is a false positive for addresses with the local part too long:

123[email protected]example.com

Do you want a simpler regex?

The above regex is very complicated, to the point I won’t even try to understand it. Regular expressions masters created it, and it spread through the Internet until I found it.

Using it at this point is a matter of copy/pasting it.

A much simpler solution is just to check that the address entered contains something, then an @ symbol, and then something else.

In this case, this regex will do the trick:

const expression = /\[email protected]\S+/
expression.test(String('[email protected]').toLowerCase())

This will cause many false positives, but after all the ultimate test on an email address validity happens when you ask the user to click something in the email to confirm the address, and I’d rather try to send to an invalid email than reject a valid email because of an error in my regex.

This is listed in the above Glitch, so you can easily try it.

Validate the HTML field directly

HTML5 provided us the email field type, so don’t forget you can also validate emails using that:

<input type="email" name="email" placeholder="Your email" />

Depending on the browser implementation also this validation will give you different results.

This Glitch shows the same emails I tested the regex with, and their result when validated through the HTML form.

The results are interesting, and here as well we have invalid emails that pass, and valid emails that don’t. Our regex actually does a more accurate job than the HTML filtering built into the browser.

Validate server-side

If your app has a server, the server needs to validate the email as well, because you can never trust client code, and also JavaScript might be disabled on the user browser.

Using Node.js you have the advantage of being able to reuse the frontend code as-is. In this case the function that validates can work both client-side and server-side.

You can also use pre-made packages like isemail, but also in this case results vary. Here is the isemail benchmark on the same emails we used above: https://glitch.com/edit/#!/flavio-email-validation-node-isemail


More js tutorials: