HTML 表单扩展元素:datalist、output 与 keygen 的现代边界
本文目录
旧 HTML5 列表把 datalist、output 和 keygen 并排列为“新表单元素”,容易让人误以为它们都能直接承担输入、提交和认证。三者职责不同,其中 keygen 已是过时功能;新项目应以当前 HTML Standard 和目标浏览器验证为准。
datalist 是输入建议,不是选项约束
datalist 通过唯一 id 与 input list 关联,提供浏览器可展示的推荐值。用户仍可输入列表之外的内容,所以当业务只能接受固定选项时用 select,并在服务端再次校验;不能把建议列表当成白名单。
datalist 的弹层外观和辅助技术支持存在浏览器差异,选项通常也难以完全用 CSS 控制。把它用于可选的自动补全提示,不要把关键说明、错误消息或不可替代的选择流程只放在弹层里。
<label for='framework'>常用前端框架</label>
<input id='framework' name='framework' list='framework-options' autocomplete='off'>
<datalist id='framework-options'>
<option value='React'></option>
<option value='Vue'></option>
<option value='Svelte'></option>
</datalist>
这里的 autocomplete='off' 仅是演示输入建议与浏览器历史自动填充是不同机制;生产表单不要习惯性关闭用户依赖的自动填充。若输入值参与查询、SQL 或命令,仍必须按上下文验证和编码。
output 表示计算结果,不是提交字段
output 表示计算或用户操作的结果,可用 for 列出参与计算的控件 ID。它是表单关联元素,但 output 的 name 和内容不会作为字段随表单提交;后端需要结果时应根据已提交的可信输入重新计算,不能相信前端显示值。
<form id='estimate'>
<label for='quantity'>数量</label>
<input id='quantity' name='quantity' type='number' min='1' value='2'>
<label for='unit-price'>单价</label>
<input id='unit-price' name='unitPrice' type='number' min='0' step='0.01' value='19.5'>
<p>小计:<output id='subtotal' name='subtotal' for='quantity unit-price'>39</output></p>
</form>
JS 根据输入更新 output 时,要处理空值、无效数字和精度规则;如果结果关系到价格、库存或权限,权威计算必须留在服务器。辅助技术可能会播报 output 更新,更新过于频繁时应设计节制的反馈。
keygen 不要用于新项目
旧材料曾把 keygen 描述为浏览器生成密钥对并提交公钥的可靠认证方式。这个元素已从 HTML 标准移除,浏览器支持也不互通,不应再复制旧示例,也不能用它建立登录或证书流程。
根据目标选择现代协议:网站用户认证可评估 WebAuthn/passkeys;应用层密钥生成与加密运算使用 Web Crypto API,并先定义密钥生命周期、服务端验证、恢复和威胁模型。不要在页面里自创密码学协议,也不要把“浏览器生成了密钥”误当作已完成身份认证。
样式和安全验收
表单控件的默认外观受平台影响;优先保留熟悉的原生语义,只为可用性调整布局与焦点状态。所有输入都要有可见 label,错误信息应与字段关联并能被键盘和辅助技术发现。浏览器端校验帮助及时反馈,但攻击者可绕过它,服务端必须重新校验。
- 固定候选值用 select;可自由输入且只需建议时才考虑 datalist。
- 检查目标浏览器、屏幕放大、键盘操作和屏幕阅读器中的建议列表行为。
- 用 output 展示计算结果;提交时仅发送需要的输入,并由服务端重新计算。
- 删除 keygen 示例;认证使用 WebAuthn 等标准方案,密码学操作使用经过审查的平台 API。
- 在客户端和服务端分别做输入校验,避免把 UI 提示当作权限或安全边界。
参考:MDN datalist、MDN output、WHATWG obsolete features、MDN Web Crypto API、MDN Web Authentication API、MDN constraint validation。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。