HTML hidden: valores enviados, cambios con JavaScript y límites de seguridad

input type="hidden" incluye un nombre y un valor en un formulario sin mostrar un cuadro de entrada. name es el nombre del campo enviado y value es su valor. Los usuarios pueden inspeccionarlo o cambiarlo, así que no lo uses para proteger contraseñas, permisos, precios u otras decisiones sensibles.

¿Cuándo deberías usar entradas ocultas?

Úsalo para enviar el ID de la publicación objetivo con un formulario de edición, o para llevar condiciones de búsqueda a la siguiente solicitud. Pasa valores que el usuario no necesita escribir, mientras que el servidor sigue siendo responsable de decidir si son válidos.

Recibir un ID de publicación no concede permiso para editar esa publicación. El servidor debe identificar al usuario a través de la sesión autenticada y verificar el acceso a la publicación. No confíes únicamente en los detalles de la cuenta o la información de IP del cliente solo porque el cliente los envió en campos ocultos.

Tipo Comportamiento en pantalla Datos del formulario
type="hidden" No hay interfaz de entrada y no recibe foco. Incluido si se nombra y no está deshabilitado.
disabled Deshabilita el control. Excluido.
Entrada ordinaria oculta con CSS display: none CSS oculta la entrada ordinaria del diseño. Ocultar solo con CSS no la excluye del envío.

id puede localizar un elemento en un script, pero no reemplaza su nombre enviado. Una entrada oculta sin nombre no se incluye como una entrada de nombre/valor en el envío ordinario del formulario. Incluso con required, las entradas ocultas no participan en la validación de restricciones del navegador.

Compruebe que se envían los valores invisibles

Guarda este código completo como hidden.html y ábrelo en un navegador. No se necesita servidor. El envío muestra las entradas de nombre/valor construidas con FormData en lugar de realizar una solicitud de red.

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Comprobar valores ocultos</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>Elegir colores</h1>
  <form id="demo">
    <label><input type="checkbox" name="color" value="blue" checked> Azul</label>
    <label><input type="checkbox" name="color" value="red"> Rojo</label>
    <input type="hidden" id="size" name="size" value="big">
    <input type="hidden" name="excluded" value="not-sent" disabled>
    <button type="submit">Mostrar valores enviados</button>
    <button type="button" id="change">Cambiar el valor oculto a small</button>
    <button type="button" id="restore">Restaurar el valor oculto a big</button>
  </form>
  <p id="status" aria-live="polite">El valor oculto inicial es 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 = `Valor oculto actual: ${value}. Vuelve a mostrar los valores enviados.`;
    }
    document.querySelector('#change').addEventListener('click', () => setSize('small'));
    document.querySelector('#restore').addEventListener('click', () => setSize('big'));
  </script>
</body>
</html>
  1. Envío inicial: color=blue y size=big aparecen. No hay un cuadro de tamaño visible, pero su valor está incluido. excluded se omite porque está deshabilitado.
  2. Selecciona Rojo y envía de nuevo para obtener azul y rojo bajo el nombre de color repetido. Borra ambos checkboxes y solo queda el tamaño.
  3. Presiona el botón que cambia el valor oculto a small y envía de nuevo: size=small aparece. Los valores ocultos también se pueden cambiar mediante JavaScript.
  4. Restaura big con el botón correspondiente y envía otra vez. El botón de cambio permite observar el ejemplo; no es necesario en todos los servicios reales.

Envía el formulario a un servidor real

Para un servicio real, establece la acción a una ruta de procesamiento existente y elige un método compatible como method="post". El manejador de envío del ejemplo bloquea las solicitudes; elimínalo o reemplázalo con código de solicitud al servidor para enviar datos. Las funciones de procesamiento de formularios del servidor reciben campos ocultos como campos de texto ordinarios.

Al recibir varias casillas de verificación con un mismo nombre, revisa las reglas de arrays y de valores múltiples del framework del servidor. Algunos analizadores solo leen el último valor repetido. La salida de JavaScript conserva los nombres repetidos para que puedas observar la diferencia.

No confunda ocultar con seguridad

Los valores ocultos son visibles en el código fuente HTML, las herramientas de desarrollador y las solicitudes de red. HTTPS no oculta el valor para el usuario que lo envía. Al recibir un ID de producto, busque el producto y el precio en el servidor y valide los valores de tamaño permitidos con la información confiable del servidor.

Un campo oculto puede contener un token CSRF (Cross-Site Request Forgery). La protección proviene de la emisión y validación adecuada del token en el servidor. Poner una cadena fija arbitraria en un input oculto por sí solo no previene solicitudes falsificadas.

La referencia de input oculto MDN explica su comportamiento y exclusión de la validación.