Constraint Validation API - 用于提交前检查用户已输入的值

Constraint Validation API(约束验证 API)用于在将值提交到服务器之前检查用户已输入到表单控件中的值。

概念和用法

某些 HTML 表单控件,如 <input><select><textarea>,可以限制允许值的格式,使用像 requiredpattern 这样的属性来设置基本约束。

然而,你可能想施加更复杂的约束,或者对验证失败提供比默认值更清晰的报告。这可以使用约束条件验证 API 来完成。

注意: 客户端的约束验证并不能替代服务器端的验证。即使客户端验证可以防止许多常见的无效值,但无效值仍然可以由旧的浏览器或试图欺骗你的 Web 应用程序的攻击者发送。因此,你也需要在服务器端验证输入值,验证的方式要与在客户端所做的一致。客户端验证是一个向用户提供快速反馈的工具。您不应该依赖它来完全阻挡发送给服务器的错误数据。

通过约束验证API对约束进行验证,可以在单个表单元素上进行,也可以在表单层面上,在 <form> 元素上进行。

约束验证接口

ValidityState

ValidityState 接口表示一个表单控制元素的有效性状态,与它定义的约束条件有关。它们一起帮助解释元素的值是否以及为什么无法验证。

invalid 事件

如果表单控制元素不满足其约束,则会触发此事件类型。

扩展到其他接口

约束验证 API 使用一些新的属性和方法扩展了下面列出的表单相关元素的接口(这些元素有一个form属性,表示它们的表单所有者)。

属性

validity

一个只读属性,它返回一个 ValidityState 对象,该对象的属性表示该元素值的验证错误状态。

validationMessage

一个只读的属性,如果该元素不是约束验证的候选者,或者该元素的值是有效,则返回一个空字符串。如果元素的值是无效的,它会返回一个本地化的验证信息。如果该元素是唯一存在有效性问题的表单控件,这将显示在用户界面中;如果使用 setCustomValidity() 设置了一个自定义错误信息,则会显示该错误消息。

willValidate

一个只读的布尔属性,如果该元素是约束验证的候选者,则返回 true;否则为 false。带有 HTMLObjectElement 接口的元素永远不是约束验证的候选对象。其他元素可能会被禁止进行约束验证,这取决于具体条件。

方法

checkValidity()

根据其约束检查元素的值。如果该值无效,则在元素上触发 invalid 事件并返回 false;否则,返回 true

reportValidity() HTMLFormElement 方法

根据其约束检查元素的值,并报告有效性状态;如果值无效,则它将在元素上触发 invalid 事件,返回 false,然后以用户代理可用的任何方式向用户报告有效性状态。否则,它返回 true

setCustomValidity(message)

设置自定义错误消息字符串,以在提交表单时显示给用户,解释为什么值无效 — 设置消息时,有效性状态会被设置为无效。要清除此状态,请传递参数为空字符串来调用该函数。在这种情况下,将清除自定义错误消息,该元素被视为有效,并且不显示任何消息。

实例

以下面表单为例:

<form>
  <label for="name"> 输入用户名(大写和小写字母):</label>
  <input type="text" name="name" id="name" required pattern="[A-Za-z]+">
  <button>提交</button>
</form>

如果您尝试提交没有填写有效数据或与 pattern 不匹配的表单,则基本的 HTML 表单验证功能将产生一个默认的错误信息。

如果要显示自定义错误消息,则可以使用如下所示的 JavaScript:

const nameInput = document.querySelector('input');
const form = document.querySelector('form');

nameInput.addEventListener('input', () => {
  nameInput.setCustomValidity('');
  nameInput.checkValidity();
});

nameInput.addEventListener('invalid', () => {
  if(nameInput.value === '') {
    nameInput.setCustomValidity('输入你的用户名!');
  } else {
    nameInput.setCustomValidity('用户名只能包含大写和小写字母。再试一次!');
  }
});

该实例如下所示:

<form>
  <label for="name"> 输入用户名(大写和小写字母):</label>
  <input type="text" name="name" id="name" required pattern="[A-Za-z]+">
  <button>提交</button>
</form>

<script>
const nameInput = document.querySelector('input');
const form = document.querySelector('form');

nameInput.addEventListener('input', () => {
  nameInput.setCustomValidity('');
  nameInput.checkValidity();
});

nameInput.addEventListener('invalid', () => {
  if(nameInput.value === '') {
    nameInput.setCustomValidity('输入你的用户名!');
  } else {
    nameInput.setCustomValidity('用户名只能包含大写和小写字母。再试一次!');
  }
});
</script>

尝试一下 »

简单来说:

  • 每次输入元素的值被改变时,我们通过 input 事件处理程序运行 checkValidity() 方法来检查其有效状态。
  • 如果值是无效的,就会引发一个 invalid 事件,并运行 invalid 事件处理函数。在这个函数中,我们使用 if() 块计算出该值无效是因为它是空的,还是因为它不符合模式,并设置一个自定义的有效性错误信息。
  • 因此,如果在按下提交按钮时输入值是无效的,将显示一个自定义的错误信息。
  • 如果它是有效的,就会像你所期望的那样提交。要做到这一点,必须通过调用 setCustomValidity(),并传入空字符串值来取消设置其为无效。因此,我们在每次 input 事件触发时都要这样做。如果你不这样做,并且之前设置了一个自定义的有效性,那么输入将被设置为无效,即使它目前包含一个有效的提交值。

注意: Firefox在许多版本中支持一个专有的错误属性 - x-moz-errormessage,它允许你以类似的方式设置自定义错误信息。从版本 66 开始,这个属性已经被删除了(参见 Bug 1513890)。

规范

规范 状态 备注
HTML Living Standard
constraint validation API 的定义
现行的标准 -
HTML 5.1
constraint validation API 的定义
推荐 与之前的快照 HTML5 相同。
HTML5
constraint validation API 的定义
推荐 包含此接口的 HTML Living Standard 的第一个快照。

相关链接