HTML hidden 隐藏输入:提交值、JavaScript 修改与安全边界

input type="hidden" 在表单中包含一个名称和值,但不显示输入框。name 是提交的字段名称,value 是其值。用户可以检查或更改它,因此不要用它来保护密码、权限、价格或其他敏感决策。

何时应使用隐藏输入?

使用它可以通过编辑表单发送目标帖子 ID,或将搜索条件带入下一次请求。它传递用户无需输入的值,同时服务器仍然负责决定这些值是否有效。

接收帖子 ID 并不授予编辑该帖子的权限。服务器必须通过经过身份验证的会话识别用户,并检查对帖子的访问权限。不要仅仅因为客户端在隐藏字段中发送了账户信息或客户端 IP 信息就信任它们。

类型 屏幕上的行为 表单数据
type="hidden" 没有输入界面,也不会接收焦点。 如果已命名且未被禁用,则包含。
disabled 禁用控件。 排除。
使用 CSS display: none 隐藏普通输入。 CSS 从布局中隐藏普通输入。 仅用 CSS 隐藏并不会将其从提交中排除。

id 可以在脚本中定位元素,但不会替换其提交的名称。没有名称的隐藏输入在普通表单提交中不会作为名称/值条目包含。即使添加 required 属性,隐藏输入也不会参与浏览器约束验证。

检查不可见的值是否已提交

将此完整代码保存为 hidden.html 并在浏览器中打开。无需服务器。提交时将显示使用 FormData 构建的名称/值条目,而不是发起网络请求。

<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>检查隐藏值</title>
  <style>
    body { margin: 24px; font-family: sans-serif; }
    label { display: block; margin: 12px 0; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>选择颜色</h1>
  <form id="demo">
    <label><input type="checkbox" name="color" value="blue" checked> 蓝色</label>
    <label><input type="checkbox" name="color" value="red"> 红色</label>
    <input type="hidden" id="size" name="size" value="big">
    <input type="hidden" name="excluded" value="not-sent" disabled>
    <button type="submit">查看提交值</button>
    <button type="button" id="change">将隐藏值改为small</button>
    <button type="button" id="restore">将隐藏值恢复为big</button>
  </form>
  <p id="status" aria-live="polite">初始隐藏值为big。</p>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.querySelector('#demo');
    const size = document.querySelector('#size');
    const result = document.querySelector('#result');
    const status = document.querySelector('#status');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify([...new FormData(form).entries()], null, 2);
    });
    function setSize(value) {
      size.value = value;
      status.textContent = `当前隐藏值:${value}。请再次查看提交值。`;
    }
    document.querySelector('#change').addEventListener('click', () => setSize('small'));
    document.querySelector('#restore').addEventListener('click', () => setSize('big'));
  </script>
</body>
</html>
  1. 首次提交:color=blue 和 size=big 出现。没有可见的尺寸框,但其值包含在内。excluded 被省略,因为它被禁用。
  2. 选择红色并再次提交以在重复的颜色名称下获得蓝色和红色。清除两个复选框后,只剩下尺寸。
  3. 按下将隐藏值更改为 small 的按钮并再次提交:size=small 出现。隐藏值也可以通过 JavaScript 进行更改。
  4. 用恢复按钮将值改回 big,再提交确认。修改按钮用于观察示例,并非每个实际服务都需要的功能。

将表单发送到真实服务器

对于真实服务,将 action 设置为现有的处理路径,并选择支持的方法,如 method="post"。示例的提交处理程序会阻止请求;请将其移除或替换为发送数据的服务器请求代码。服务器表单处理功能会像普通文本字段一样接收隐藏字段。

在接收多个同名复选框时,请检查服务器框架的数组和多值规则。有些解析器只读取最后重复的值。JavaScript 输出会保留重复名称,以便你观察差异。

不要把隐藏与安全混淆

隐藏的值在 HTML 源代码、开发者工具和网络请求中都是可见的。HTTPS 并不会向发送数据的用户隐藏该值。在接收产品 ID 时,应在服务器上查找产品和价格,并根据可信服务器信息验证允许的尺寸值。

隐藏字段可以携带 CSRF(跨站请求伪造)令牌。保护措施来自于正确的服务器端令牌发放和验证。在隐藏输入中放任意固定字符串本身不能防止伪造请求。

MDN 隐藏输入参考 解释了其行为及其不参与验证的原因。