FormData y controles asociados en formularios HTML | Nicolás Garzón
FormData
JavaScript
Copiar const formData = new FormData ( form) ; HTML
Copiar < form id = " profile-form" >
< input name = " name" value = " Nicolás" >
< input name = " avatar" type = " file" >
</ form> JavaScript
Copiar const form = document. querySelector ( "#profile-form" ) ;
const formData = new FormData ( form) ; Solo incluye controles exitosos y asociados.
HTML
Copiar < input id = " email" type = " email" value = " hello@example.com" > No aparece en FormData sin name.
JavaScript
Copiar const name = formData. get ( "name" ) ; Retorna el primer valor o null.
El resultado puede ser string | File | null. No lo conviertas directamente a número u objeto sin validar.
JavaScript
Copiar const technologies = formData. getAll ( "technology" ) ; Obtiene todas las entradas repetidas, por ejemplo varios checkboxes.
JavaScript
Copiar formData. has ( "newsletter" ) ; Ayuda a distinguir ausencia. Un checkbox no seleccionado normalmente no aparece.
JavaScript
Copiar formData. append ( "tag" , "html" ) ;
formData. append ( "tag" , "accessibility" ) ; append conserva valores existentes.
JavaScript
Copiar formData. set ( "name" , "Nicolás Garzón" ) ; set reemplaza entradas previas del mismo nombre.
JavaScript
Copiar formData. delete ( "internalField" ) ; Elimina todas las entradas con ese name.
JavaScript
Copiar for ( const [ name, value] of formData) {
console. log ( name, value) ;
} No registres passwords, tokens o archivos sensibles en consola o analytics.
JavaScript
Copiar form. addEventListener ( "submit" , ( event ) => {
event. preventDefault ( ) ;
const data = new FormData ( form, event. submitter) ;
} ) ; Cuando la API soporta el segundo argumento, incluye name/value del botón submitter. Sin él, una construcción manual puede perder la intención publish o draft.
JavaScript
Copiar form. addEventListener ( "formdata" , ( event ) => {
event. formData. append ( "clientVersion" , "1" ) ;
} ) ; Permite ajustar el conjunto cuando se construye para envío.
No añadas datos de autoridad que el servidor debería determinar por sesión o permisos.
JavaScript
Copiar await fetch ( form. action, {
method : form. method,
body : new FormData ( form) ,
} ) ; No configures manualmente Content-Type: multipart/form-data; el navegador añade el boundary.
JavaScript
Copiar const object = Object. fromEntries ( formData) ; Pierde valores repetidos porque las claves se sobrescriben. Tampoco transforma tipos ni representa archivos como JSON útil.
JavaScript
Copiar const tags = formData. getAll ( "tag" ) ; JavaScript
Copiar const quantityValue = formData. get ( "quantity" ) ; Aunque provenga de input type="number", es normalmente string.
JavaScript
Copiar const quantity = Number ( quantityValue) ; Debes comprobar vacío, finitud, rango e integralidad según la regla.
JavaScript
Copiar const subscribed = formData. has ( "newsletter" ) ; JavaScript
Copiar const attachment = formData. get ( "attachment" ) ;
if ( attachment instanceof File && attachment. size > 0 ) {
} El cliente puede ofrecer feedback, pero el servidor valida tipo, contenido y tamaño.
HTML
Copiar < form id = " order-form" > </ form>
< input form = " order-form" name = " notes" > FormData incluye controles con el mismo form owner aunque estén fuera del árbol descendiente.
Disabled: normalmente excluido.
Readonly: normalmente incluido.
No habilites temporalmente controles disabled solo para capturar valores que el servidor debería conocer por otra fuente.
Form-associated custom elements pueden participar mediante ElementInternals cuando se implementan correctamente. No basta con tener un atributo name en cualquier custom element.
Para datos exclusivamente textuales compatibles con URL encoding:
JavaScript
Copiar const params = new URLSearchParams ( formData) ; No es apropiado cuando existen archivos y puede convertir valores de formas inesperadas. Comprueba el conjunto antes.
JavaScript
Copiar form. addEventListener ( "submit" , async ( event ) => {
event. preventDefault ( ) ;
if ( ! form. reportValidity ( ) ) return ;
const formData = new FormData ( form, event. submitter) ;
const response = await fetch ( form. action, {
method : "POST" ,
body : formData,
} ) ;
if ( ! response. ok) {
showSubmissionError ( ) ;
}
} ) ; El servidor sigue siendo la autoridad.
Esperar un objeto tipado.
Omitir names.
Usar get cuando existen valores repetidos.
Convertir con Object.fromEntries y perder entradas.
Asumir que number produce number.
Configurar manualmente multipart boundary.
Registrar datos sensibles.
Olvidar el submitter.
Confiar en file type del cliente.
Añadir roles/permisos desde el navegador como autoridad.
FormData contiene strings y Files.
Solo incluye controles exitosos.
Get devuelve el primero; getAll, todos.
Append conserva; set reemplaza.
Los tipos deben parsearse y validarse.
Object.fromEntries pierde duplicados.
El submitter puede formar parte de los datos.
Fetch gestiona el Content-Type multipart.
La autoridad y validación permanecen en servidor.
¿Por qué Object.fromEntries(new FormData(form)) puede perder checkboxes seleccionados?
Respuesta Porque varios checkboxes pueden compartir el mismo name; un objeto solo conserva una propiedad por clave y sobrescribe valores anteriores.
Seguridad y privacidad en formularios analiza datos no confiables, CSRF, uploads y información sensible.