表单在 Web 应用程序中无处不在。一些应用程序使用表单来收集数据,实现用户注册和收集电子邮件地址。也有一些应用程序使用表单来完成在线交易,以促进购物体验。

你可能会使用一些网络表单来申请新汽车贷款或者订购披萨饼作为晚餐。因此,将这些表单收集的数据进行清理,正确地格式化,避免包含任何恶意代码,这个过程很重要,它被称为“表单验证”。

当我们接受用户输入时,都需要进行表单验证。我们必须确保输入的数据格式正确,在有效数据范围内(例如日期字段),并且不包含可能导致 SQL 注入的恶意代码。数据格式错误或丢失也可能导致 API 引发错误。

表单验证有哪些不同类型?

表单验证可以在客户端和服务器端进行。

客户端验证使用 HTML5 属性和客户端 JavaScript 进行。

你可能已经注意到,在某些表单中,如果输入无效的电子邮件地址,表单就会出现错误“请输入有效的电子邮件”。 这种直接的验证类型通常是通过客户端 JavaScript 来完成的。

1

在其他情况下,你可能已经注意到,当你填写表格并输入诸如信用卡之类的详细信息时,屏幕可能显示加载,然后显示错误“此信用卡无效”。

这是因为表单调用了其服务器端代码,并在执行了信用卡检查之后返回了验证错误。 进行服务器端调用的这种验证情况被称为“服务器端验证”。

应该验证什么数据?

当你接受来自用户的数据时,都需要进行表单验证。这可能包括:

  • 验证字段格式,例如电子邮件地址、电话号码、邮政编码、名称、密码
  • 验证必填字段
  • 检查诸如字符串与数字之类的数据类型,以查找诸如社会保险号之类的字段
  • 确保输入的值是有效值,例如国家/地区、日期等

如何设置客户端验证

在客户端,可以通过两种方式完成验证:

  • 使用 HTML5 功能
  • 使用 JavaScript

如何使用 HTML5 功能设置验证

HTML5 提供了一堆属性来帮助验证数据。以下是一些常见的验证案例:

  • 使用 required 来定义必填字段
  • 限制数据长度
  • minlengthmaxlength:用于文本数据
  • minmax表示数值类型的最大值
  • 使用 type 限制数据类型
  • <input type="email" name="multiple>
  • 使用 pattern 指定数据模式
  • 指定输入的表单数据需要匹配的正则表达式

当输入值与上述 HTML5 验证匹配时,将为它分配一个 psuedo-class::valid,否则就是 :invalid

看一下这个例子:

<form>
<label for="firstname"> First Name: </label>
<input type="text" name="firstname" id="firstname" required maxlength="45">
<label for="lastname"> Last Name: </label>
<input type="text" name="lastname" id="lastname" required maxlength="45">
<button>Submit</button>
</form>
2

链接到 JSFiddle

在这里,我们有两个必填字段——名和姓。在 JSFidle 中尝试这个示例。如果你跳过这两个字段中的任何一个并按提交,你将收到一条消息,“请填写此字段”。这是使用内置 HTML5 进行的验证。

如何使用 JavaScript 设置验证

进行表单验证时,需要考虑以下几点:

  • 什么被定义为“有效”数据? 这可以帮助你回答有关格式、长度、必填字段和数据类型的问题。
  • 输入无效数据会怎样?这将帮助你定义验证的用户体验——是在行内显示错误消息还是在表单顶部显示错误消息,错误消息的详细程度,表单是否提交,是否应进行分析以跟踪无效格式数据的,等等。

你可以通过两种方式执行 JavaScript 验证:

  • 使用 JavaScript 进行内联验证
  • HTML5 约束验证 API

使用 JavaScript 进行内联验证

<form id="form">
  <label for="firstname"> First Name* </label>
  <input type="text" name="firstname" id="firstname" />
  <button id="submit">Submit</button>

  <span role="alert" id="nameError" aria-hidden="true">
    Please enter First Name
  </span>
</form>
const submit = document.getElementById("submit");

submit.addEventListener("click", validate);

function validate(e) {
  e.preventDefault();

  const firstNameField = document.getElementById("firstname");
  let valid = true;

  if (!firstNameField.value) {
    const nameError = document.getElementById("nameError");
    nameError.classList.add("visible");
    firstNameField.classList.add("invalid");
    nameError.setAttribute("aria-hidden", false);
    nameError.setAttribute("aria-invalid", true);
  }
  return valid;
}
#nameError {
  display: none;
  font-size: 0.8em;
}

#nameError.visible {
  display: block;
}

input.invalid {
  border-color: red;
}

链接到 JSFiddle

在这个示例中,我们使用 JavaScript 检查必填字段。如果不存在必填字段,我们将使用 CSS 来显示错误消息。

相应地修改了 Aria 标签,以表示错误。通过使用 CSS 显示/隐藏错误,我们减少了需要进行的 DOM 操作数量。 错误消息是在上下文中提供的,从而使用户体验更加直观。

HTML5 约束验证 API

HTML 的 requiredpattern 属性可以帮助执行基本验证。但是,如果你想要更复杂的验证,或想要提供详细的错误消息,则可以使用约束验证 API。

这个 API 提供的一些方法:

  1. checkValidity
  2. setCustomValidity
  3. reportValidity

下面这些属性很有用:

  1. validity
  2. validationMessage
  3. willValidate

在这个示例中,我们将使用 HTML5 内置方法(例如 requiredlength)结合约束验证 API进行验证,以提供详细的错误消息。

<form>
<label for="firstname"> First Name: </label>
<input type="text" name="firstname" required id="firstname">
<button>Submit</button>
</form>
const nameField = document.querySelector("input");

nameField.addEventListener("input", () => {
  nameField.setCustomValidity("");
  nameField.checkValidity();
  console.log(nameField.checkValidity());
});

nameField.addEventListener("invalid", () => {
  nameField.setCustomValidity("Please fill in your First Name.");
});

链接到 JSFiddle

不要忘记服务器端验证

除了客户端验证,你还必须在服务器端代码上验证从客户端收到的数据,以确保数据与你期望的数据匹配。

你还可以使用服务器端验证来执行不应在客户端上进行的业务逻辑验证。

表单验证最佳实践

  1. 始终进行服务器端验证,因为恶意行为者可以绕过客户端验证
  2. 在产生错误的字段的上下文中提供详细的错误消息
  3. 提供一个示例,以显示出现错误消息时数据的外观,例如:“电子邮件与格式不匹配——test@example.com
  4. 避免使用涉及重定向的单个错误页面——这是糟糕的用户体验,迫使用户返回上一页以修复表单并丢失上下文
  5. 始终标记必填字段

原文:Data Validation – How to Check User Input on HTML Forms with Example JavaScript Code,作者:Shruti Kapoor