Một trong những cách sử dụng JavaScript phổ biến nhất trong các ứng dụng web là xác thực biểu mẫu. Xác thực biểu mẫu phía máy khách cung cấp cho người dùng phản hồi gần như ngay lập tức về việc liệu dữ liệu đầu vào của họ có hợp lệ hay không. Các nhà phát triển có xu hướng tiếp cận một trong nhiều thư viện xác thực biểu mẫu xuất sắc, đặc biệt nếu họ đang làm việc trong ngữ cảnh của một khung như React hoặc Angular, nơi có nhiều giải pháp như vậy
Các thư viện này bổ sung giá trị cho ứng dụng của bạn, nhưng ngay cả khi bạn có thể chỉ cần một phần nhỏ chức năng của thư viện, thì chúng cũng phải trả giá, đặc biệt là với kích thước gói của bạn
Nếu nó phù hợp với trường hợp sử dụng của bạn, có thể có một cách đơn giản hơn. Trong bài viết này, chúng ta sẽ đi sâu tìm hiểu mọi thứ về xác thực biểu mẫu HTML, bao gồm
Các tính năng xác thực biểu mẫu HTML5
HTML5 và API DOM hiện đại đã được trang bị để xác thực biểu mẫu. HTML5 xuất hiện vào năm 2008 và mang theo nhiều cải tiến, bao gồm thẻ <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>0, đã nhận được một số cập nhật về xác thực biểu mẫu
thuộc tính xác thực
HTML5 đã thêm các thuộc tính mới đặt quy tắc xác thực một cách khai báo cho một trường nhập nhất định. Những thuộc tính mới này bao gồm
- <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>1. Chỉ định rằng trường không được để trống
- <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>2/<form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>3. Chỉ định phạm vi giá trị được phép cho đầu vào số
- <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>4/<form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>5. Chỉ định phạm vi độ dài cho phép đối với kiểu nhập văn bản
- <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>6. Đối với một bước của <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>7, một giá trị nhập số chỉ hợp lệ nếu nó là bội số của <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>7
- <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>9. Chỉ định một biểu thức chính quy mà một kiểu nhập văn bản phải khớp
bộ chọn CSS
HTML5 cũng giới thiệu một số bộ chọn CSS mới, bao gồm hai lớp giả mới — function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }0 và function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }1. Chúng khớp với bất kỳ đầu vào nào có giá trị đã qua hoặc không xác thực tương ứng
Ví dụ: chúng tôi có thể tự động đánh dấu các trường không hợp lệ bằng đường viền màu đỏ
input:invalid { border: 2px solid red; } input:valid { border: 2px solid green; }Trước khi nhập một giá trị vào trường bắt buộc này, nó sẽ tự động được đánh dấu là không hợp lệ
Khi một giá trị được nhập vào, bộ chọn function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }1 không còn khớp nữa và thay vào đó, bộ chọn function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }0 sẽ khớp
Thông báo xác nhận sẵn có
Nếu bạn cố gắng gửi biểu mẫu chứa thông tin đầu vào có giá trị không hợp lệ, thì quá trình gửi biểu mẫu sẽ bị hủy và thông báo lỗi do trình duyệt cung cấp sẽ hiển thị (bên dưới hiển thị như trong Chrome)
Điều này có thể không lý tưởng cho ứng dụng của bạn. Giao diện của thông báo khác nhau giữa các trình duyệt và có thể không phù hợp nhất quán với phần còn lại của giao diện người dùng của bạn
Vì lý do này, các thông báo xác thực này là tùy chọn. Bạn có thể chọn không tham gia bằng cách đặt thuộc tính function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }4 trên biểu mẫu chứa thông tin đầu vào
<form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>Điều này chỉ vô hiệu hóa hành vi xác thực — các quy tắc vẫn được áp dụng. Nếu biểu mẫu chứa đầu vào không hợp lệ, nó sẽ vẫn được gửi. Nếu bạn đặt thuộc tính function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }4, biểu mẫu sẽ không còn tự động xác thực các trường của nó khi gửi. Bạn sẽ phải thực hiện việc này theo cách thủ công trong trường hợp như vậy bằng cách gọi số checkValidity trên biểu mẫu và ngừng gửi biểu mẫu nếu biểu mẫu không hợp lệ
Ưu điểm là bạn có toàn quyền kiểm soát quá trình xác thực và hành vi của nó. Các quy tắc xác thực và trạng thái xác thực hiện tại vẫn được cung cấp cho bạn thông qua API xác thực ràng buộc
API xác thực ràng buộc
API DOM này đi đôi với các thuộc tính xác thực HTML5 mà chúng ta đã thảo luận ở trên. Nó cung cấp một số đối tượng, phương thức và sự kiện cho phép bạn xây dựng hành vi xác thực mà không phải lo lắng về việc tự kiểm tra các quy tắc xác thực
Kiểm tra tính hợp lệ với ValidityState
Các thẻ đầu vào trong biểu mẫu có thuộc tính function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }8, là đối tượng ValidityState và phản ánh trạng thái xác thực hiện tại của đầu vào. Giá trị được cập nhật theo thời gian thực;
ValidityState có một loạt cờ boolean. Cái chính chỉ đơn giản là async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }1 — đây là async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }2 nếu phần tử vượt qua tất cả các kiểm tra trạng thái hiện hành. Ngay khi đầu vào hợp lệ trở nên không hợp lệ do giá trị của nó thay đổi, cờ này ngay lập tức trở thành async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }3
Nếu thuộc tính async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }4 của một phần tử là async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }3, có thể kiểm tra các cờ bổ sung trong ValidityState để xác định quy tắc xác thực nào đang bị vi phạm. Các nhóm cờ khác nhau áp dụng cho các loại quy tắc xác thực khác nhau
Hơn 200 nghìn nhà phát triển sử dụng LogRocket để tạo ra trải nghiệm kỹ thuật số tốt hơn
cờ ValidityState
Quy tắc xác thựcCờ hiệu lực được liên kết_______0_______1- async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }9. Đầu vào có giá trị trống
- form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });1. Giá trị nhỏ hơn giá trị tối thiểu được phép
- form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });1. Giá trị vượt quá giá trị tối đa cho phép
- form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });4. Độ dài của giá trị đầu vào nhỏ hơn giá trị tối thiểu
- form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });4. Độ dài của giá trị đầu vào vượt quá giá trị tối đa
- form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });7. Giá trị đầu vào nằm ngoài khoảng thời gian bước cho phép
- form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });9. Giá trị đầu vào không khớp với mẫu đã cho
- form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });1. Giá trị đầu vào không khớp với loại đã chỉ định. Ví dụ: một đầu vào có form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });2 của form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });3 có giá trị không phải là địa chỉ email hợp lệ
Xác thực theo yêu cầu với checkValidity
Biểu mẫu được kiểm tra tính hợp lệ khi người dùng cố gắng gửi biểu mẫu đó, nhưng bạn có thể muốn biểu mẫu của mình gắn cờ các trường không hợp lệ sớm hơn (có thể do mờ hoặc thậm chí khi thay đổi)
Điều này có thể được thực hiện bằng cách gọi phương thức checkValidity trên một đầu vào cụ thể hoặc trên phần tử biểu mẫu kèm theo
Khi checkValidity được gọi trên một biểu mẫu, nó sẽ trả về async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }2 nếu tất cả các trường đều hợp lệ. Nếu bất kỳ trường nào không hợp lệ, biểu mẫu sẽ trả về async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }3 và mỗi trường không hợp lệ sẽ kích hoạt riêng một sự kiện form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });9. Nó hoạt động tương tự khi được gọi trên một đầu vào duy nhất, ngoại trừ việc nó kiểm tra và có khả năng kích hoạt sự kiện chỉ cho đầu vào đó
Xem cây bút
Mã xác thực tùy chỉnh của Joe Attardi (@thinksInCode)
trên CodePen
Trong CodePen ở trên, chúng tôi kích hoạt xác thực theo cách thủ công bất cứ khi nào trường thay đổi. Nếu biểu mẫu được gửi với trường trống, nó sẽ hiển thị lỗi xác thực, nhưng ngay khi bạn nhập một ký tự, thông báo lỗi sẽ biến mất. Nếu bạn xóa nội dung của trường, lỗi xác thực sẽ xuất hiện lại ngay lập tức
Logic xác thực tùy chỉnh
Bạn có thể gặp phải tình huống không có kiểm tra xác thực sẵn có nào áp dụng được cho các quy tắc xác thực của bạn. Ví dụ: bạn có thể có các trường xác nhận mật khẩu và mật khẩu trong biểu mẫu đăng ký của mình. Nếu những mật khẩu này không khớp, các trường sẽ được đánh dấu là không hợp lệ
Để hỗ trợ trường hợp sử dụng này, tất cả các đầu vào đều có phương thức ValidityState0. Thao tác này sẽ gắn cờ trường là không hợp lệ và đặt thông báo đã chỉ định là lỗi xác thực
Lưu ý rằng điều này chỉ đặt trạng thái xác thực thành không hợp lệ. Nó không thực hiện bất kỳ loại kiểm tra nào đối với giá trị; . Đây là một ví dụ đơn giản
function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }Khi ValidityState0 được gọi trên đầu vào ValidityState2 ở trên
- Cờ async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }4 của đầu vào trở thành async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }3
- Cờ ValidityState5 của đầu vào trở thành async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }2
- Thuộc tính ValidityState7 của đầu vào trở thành “Mật khẩu không khớp”
Xác thực tùy chỉnh không đồng bộ
Hãy xem xét một ví dụ phức tạp hơn cho biểu mẫu đăng ký. Sẽ rất tuyệt nếu cung cấp phản hồi cho người dùng mới về việc tên người dùng đã chọn của họ đã được sử dụng hay chưa. Điều này có thể được thực hiện không đồng bộ và kết quả được đặt với ____58_______0
Các bài viết hay khác từ LogRocket
- Đừng bỏ lỡ một khoảnh khắc nào với The Replay, một bản tin được tuyển chọn từ LogRocket
- Tìm hiểu cách Galileo của LogRocket loại bỏ tiếng ồn để chủ động giải quyết các sự cố trong ứng dụng của bạn
- Sử dụng useEffect của React để tối ưu hóa hiệu suất ứng dụng của bạn
- Chuyển đổi giữa nhiều phiên bản của Node
- Khám phá cách tạo hoạt ảnh cho ứng dụng React của bạn với AnimXYZ
- Khám phá Tauri, một khuôn khổ mới để xây dựng các tệp nhị phân
- So sánh NestJS với. Thể hiện. js
Thông báo xác thực tùy chỉnh và checkValidity
Trong ví dụ trên, nếu mật khẩu không khớp, việc gọi checkValidity trên biểu mẫu sẽ vẫn trả về async function checkUsername() { // We only should make the async check if the username field has a // value, otherwise we will skip this and the blank username field // will be handled when the built-in validation runs (assuming the // username field has the `required` attribute set. if (usernameField.value) { // Use the Fetch API to call our endpoint to validate the username. // The response will contain a `valid` property. const response = await fetch(`/api/checkUsername/${usernameField.value}`); const { valid } = await response.json(); if (!valid) { usernameField.setCustomValidity('This username is already taken.'); } } }2 và không có sự kiện không hợp lệ nào được kích hoạt. Bạn sẽ cần kiểm tra các trường theo cách thủ công và đặt hiệu lực tùy chỉnh
Tuy nhiên, sau khi đầu vào có lỗi tùy chỉnh được đặt, bất kỳ lệnh gọi nào tiếp theo tới checkValidity sẽ thấy lỗi tùy chỉnh, quá trình xác thực sẽ không thành công và đầu vào bị ảnh hưởng sẽ kích hoạt sự kiện form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });9
Điều này có thể được gói gọn trong một trình xử lý gửi biểu mẫu
form.addEventListener('submit', event => { // first check any custom validation logic if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });Tích hợp xác thực không đồng bộ
API xác thực ràng buộc là đồng bộ. Khi gọi checkValidity trên một biểu mẫu hoặc đầu vào, nó sẽ đặt kết quả xác thực ngay lập tức. Nếu biểu mẫu của bạn chứa đầu vào yêu cầu logic xác thực không đồng bộ, chẳng hạn như ví dụ kiểm tra tên người dùng ở trên, bạn sẽ cần trì hoãn lệnh gọi checkValidity cho đến khi thao tác không đồng bộ của bạn hoàn tất và lệnh gọi ValidityState0 đã được thực hiện
Mở rộng trình xử lý gửi ở trên để bao gồm kiểm tra tên người dùng có thể giống như thế này
form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });Hạn chế của API xác thực ràng buộc
Mặc dù API đơn giản hóa rất nhiều logic xác thực cốt lõi, nhưng trong hầu hết các trường hợp, bạn sẽ cần thực hiện thêm một số công việc để lấp đầy khoảng trống cho một giải pháp xác thực đầy đủ tính năng
Xây dựng dòng chảy của riêng bạn
Hạn chế chính với API này là cần phải rõ ràng về một số thao tác xác thực. Nếu thuộc tính function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }4 được đặt — thường là như vậy, để tắt thông báo trong trình duyệt — quy trình xác thực phải được sắp xếp theo cách thủ công
May mắn thay, không có nhiều mã thừa để viết. Nếu bạn chỉ muốn xác thực khi gửi, đoạn mã trên sẽ thực hiện. Nếu bạn muốn xác thực sớm hơn, chẳng hạn như khi đầu vào mất tiêu điểm, bạn sẽ cần lắng nghe sự kiện mờ và trong trình xử lý sự kiện, hãy thực hiện bất kỳ xác thực tùy chỉnh nào, sau đó gọi checkValidity trên đầu vào
Hiển thị thông báo lỗi
Nếu thông báo xác thực trong trình duyệt bị tắt thông qua thuộc tính function validatePasswords() { if (passwordField.value !== confirmPasswordField.value) { confirmPasswordField.setCustomValidity('Password does not match'); } }4, một trường sẽ được đánh dấu là không hợp lệ trong ValidityState của nó, nhưng sẽ không có thông báo nào được hiển thị. Trình duyệt vẫn cung cấp thông báo phù hợp với thuộc tính ValidityState7 của phần tử <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>0, nhưng bạn sẽ cần thêm mã để hiển thị thông báo (hoặc cung cấp mã của riêng bạn)
Một <form name="loginForm" novalidate> Username: <input type="text" name="username" required> </form>0 có thể lắng nghe sự kiện form.addEventListener('submit', async event => { // first check any custom validation logic // as shown above, if the username field is blank the async validation // will be skipped, and the required validation rule will be handled // below when we call `form.checkValidity`. await checkUsername(); if (passwordInput.value !== confirmPasswordInput.value) { confirmPasswordInput.setCustomValidity('Passwords do not match'); } // now run the built-in validation, which will detect // any custom validation errors from above // if validation fails, stop the submission if (!form.checkValidity()) { event.preventDefault(); } });9 và hiển thị thông báo lỗi thích hợp để phản hồi sự kiện đó. Nếu có một thông báo hợp lệ tùy chỉnh, thông báo đó có thể được sử dụng, nếu không, thông báo sẽ phải phụ thuộc vào các giá trị trong ValidityState của đầu vào
Logic xác thực tùy chỉnh hoặc nâng cao
Có những khía cạnh tốt và xấu của điều này. API cốt lõi không thể dự đoán tất cả các tình huống xác thực có thể xảy ra, do đó, thường sẽ có khoảng trống nếu bạn có các yêu cầu xác thực duy nhất. Tuy nhiên, khi bạn đã thực hiện kiểm tra xác thực tùy chỉnh của mình, bạn có thể dựa vào API để đưa các kết quả đó vào phần còn lại của trạng thái hợp lệ của biểu mẫu
Ví dụ: kiểm tra xác thực tùy chỉnh có thể hữu ích trên trang Thay đổi mật khẩu, nơi có hai trường cho phép nhập mật khẩu. Kiểm tra xác thực tùy chỉnh có thể cho biết liệu mật khẩu mới và đầu vào xác nhận mật khẩu có khớp hay không. Xem CodePen bên dưới
Kiểm tra xác thực tùy chỉnh
mẫu const = tài liệu. querySelector('form'); . querySelector(‘. lỗi'); . truy vấnSelector('đầu vào'); . querySelector('#success'); . tài liệu. querySelector(‘#password’), xác nhậnMật khẩu. tài liệu. querySelector(‘#confirmPassword’) } const errorMessages = { mật khẩu. tài liệu. querySelector(‘#password-error’), confirmPassword. tài liệu. querySelector(‘#confirmPassword-error’) }; . addEventListener('gửi', sự kiện => { thành công. danh sách lớp học. thêm ('ẩn');
Phần kết luận
API xác thực ràng buộc chỉ là một trong nhiều API trình duyệt tiện dụng đã được thêm vào trong những năm gần đây. API xác thực ràng buộc, kết hợp với các thuộc tính xác thực HTML5, có thể giúp bạn tiết kiệm rất nhiều mã xác thực soạn sẵn. Đối với các ứng dụng đơn giản, đó có thể là tất cả những gì bạn cần
Nó cũng có hỗ trợ trình duyệt tuyệt vời, từ Internet Explorer 10. Các trình duyệt cũ hơn có thể không hỗ trợ một số tính năng mới hơn của API này, nhưng vẫn có hỗ trợ cốt lõi
Để xác thực nâng cao hơn hoặc các ứng dụng quy mô lớn hơn, nó có thể không đủ
May mắn thay, API hiển thị các khối xây dựng cấp thấp vững chắc có thể được sử dụng để xây dựng giải pháp xác thực mạnh mẽ hơn với ít mã hơn. Bạn sẽ cần lo lắng về xác thực tùy chỉnh, thông báo lỗi và thời điểm xác thực, nhưng API sẽ đảm nhận việc kiểm tra và xác thực các trường
Nếu bạn muốn xem thêm một số ví dụ về từng loại này, hãy xem Bộ sưu tập CodePen mà tôi tổng hợp
Đăng NhậpTên Lửa. Khả năng hiển thị đầy đủ vào web và ứng dụng dành cho thiết bị di động của bạn
LogRocket là một giải pháp giám sát ứng dụng giao diện người dùng cho phép bạn phát lại các sự cố như thể chúng đã xảy ra trong trình duyệt của chính bạn. Thay vì đoán tại sao xảy ra lỗi hoặc yêu cầu người dùng chụp ảnh màn hình và kết xuất nhật ký, LogRocket cho phép bạn phát lại phiên để nhanh chóng hiểu điều gì đã xảy ra. Nó hoạt động hoàn hảo với bất kỳ ứng dụng nào, bất kể khung công tác nào và có các plugin để ghi lại ngữ cảnh bổ sung từ Redux, Vuex và @ngrx/store
Ngoài việc ghi nhật ký các hành động và trạng thái Redux, LogRocket còn ghi nhật ký bảng điều khiển, lỗi JavaScript, dấu vết ngăn xếp, yêu cầu/phản hồi mạng với tiêu đề + nội dung, siêu dữ liệu trình duyệt và nhật ký tùy chỉnh. Nó cũng cung cấp công cụ cho DOM để ghi lại HTML và CSS trên trang, tạo lại các video hoàn hảo về pixel của ngay cả các ứng dụng dành cho thiết bị di động và trang đơn phức tạp nhất