Envío de formularios HTML

Envío de formularios HTML6 min de lectura

El atributo action de un formulario HTML, explicado

Qué hace el atributo action de un formulario, cómo se resuelven los valores relativos y vacíos, cómo formaction envía un formulario a dos sitios y por qué los hostings estáticos responden 405.

Preet SutharFundador, Ikiform

El atributo action es la URL a la que un formulario envía sus datos. Un valor relativo se resuelve respecto a la dirección de la página, uno vacío o ausente significa la propia página, y el formaction de un botón de envío lo sobrescribe para ese botón. En un sitio estático, ponle la URL completa de un backend de formularios como https://ikiform.com/f/<formId>, porque tu propio hosting no puede aceptar el POST.

La mayoría de formularios rotos en sitios estáticos fallan en este único atributo. El markup parece correcto, el botón funciona y el navegador muestra un 405 o una página en blanco, porque los datos fueron a un sitio que no puede recibirlos. Esta página muestra exactamente adónde envía los datos un action concreto, y luego usa formaction para dirigir un formulario a dos bandejas de entrada.

Qué cambia aquí

action es una URL como cualquier href, con un matiz: un formulario sin action no deja de hacer nada, envía a la página en la que está. En un sitio renderizado en el servidor, esa página podría gestionar el envío. En un hosting estático no puede, así que un action ausente o relativo solo falla después de desplegar.

Adónde envía los datos cada valor

Toma una página en https://example.com/company/contact.html con cinco formularios:

contact.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<form action="/api/contact" method="post">
<form action="send" method="post">
<form action="" method="post">
<form method="post">
actionSe resuelve comoEn un hosting estático
https://ikiform.com/f/frm_...Exactamente esa URLFunciona. Ikiform acepta el POST
/api/contacthttps://example.com/api/contactSolo funciona si tu hosting ejecuta una función en esa ruta
sendhttps://example.com/company/send, relativa a la carpeta405 o 404
"" (empty)La propia página, contact.html405 en la mayoría de hostings estáticos
AusenteLa propia página405 en la mayoría de hostings estáticos
Cómo convierte el navegador el atributo action de un formulario en la URL a la que envíaabsolutorelativo, vacío o ausenteaction="https://ikiform.com/f/..."se usa tal cualIkiform responde303action="send" oningunose resuelverespecto a lapáginao un <base href> si lapágina tiene unotu hostingestáticono acepta POST: 405Cómo convierte el navegador el atributo action de un formulario en la URL a la que envíaabsolutorelativo, vacío o ausenteaction="https://ikiform.com/f/..."se usa tal cualIkiform responde 303action="send" o ningunose resuelve respecto a lapáginao un <base href> si la páginatiene unotu hosting estáticono acepta POST: 405
  1. Un action absoluto se usa exactamente como está escrito, así que el envío llega a Ikiform, que responde con una redirección.
  2. Un action relativo, vacío o ausente se resuelve respecto a la dirección de la propia página, o respecto a un elemento base si la página tiene uno.
  3. El envío va entonces a tu propio hosting. Un hosting estático solo sirve archivos, así que rechaza el POST, normalmente con 405.
Si la barra de direcciones muestra tu propio dominio justo después de enviar, el action era relativo.
Un elemento <base href> en el head de la página cambia cómo se resuelve cada URL relativa, incluido action. Algunos creadores de sitios y configuraciones de apps de una sola página añaden uno. Usa una URL completa y no importará.

Comprueba qué usará el navegador

En la consola del navegador, el atributo y la propiedad son distintos. getAttribute devuelve lo que escribiste; la propiedad action devuelve la URL resuelta a la que el navegador enviará de verdad:

Consola
const form = document.querySelector("form");
form.getAttribute("action");
form.action;

Si form.action muestra tu propio dominio, ahí es adonde van los datos. Creadores como Webflow y Framer suelen poner el action desde su propio panel de ajustes, así que revisa la página publicada, no tu código fuente. Las guías de creadores de sitios indican dónde lo guarda cada creador.

Un formulario, dos bandejas de entrada

El formaction de un botón de envío sustituye el action del formulario solo para ese botón. Aquí, un mismo conjunto de campos va a dos formularios de Ikiform. Ask support envía al formulario de soporte, Talk to sales al de ventas, y cada formulario de Ikiform manda email a sus propios destinatarios:

contact.html
<form action="https://ikiform.com/f/frm_supportxxxxxxxxx" method="post">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <label for="message">How can we help?</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Ask support</button>
  <button formaction="https://ikiform.com/f/frm_salesxxxxxxxxxxx">Talk to sales</button>
</form>
  • Cada formulario de Ikiform tiene sus propios destinatarios de notificaciones, ajustes de spam y webhooks, así que soporte y ventas nunca ven el correo del otro.
  • Los dos formularios necesitan la misma definición de campos, o ninguna. Con campos definidos, un campo que un formulario no conoce se rechaza con 422.
  • Los demás atributos form* funcionan igual: formmethod, formenctype, formnovalidate y formtarget. Un botón Save draft con formnovalidate se salta las comprobaciones del navegador.
  • formaction solo funciona en botones de envío: <button>, <input type="submit"> e <input type="image">.

La alternativa es un único formulario de Ikiform con un campo topic, y enrutar por tema en un webhook o con los filtros de tu bandeja de entrada. Así mantienes una sola lista y una sola exportación. Dos formularios son más sencillos cuando los dos equipos no deberían compartir destinatarios en absoluto.

action con query string

Con method="get", el navegador sustituye la query string del action por los campos del formulario. El lang=de del primer formulario de abajo se descarta sin avisar; el segundo lo conserva como input oculto:

search.html
<form action="/search?lang=de" method="get">
  <input name="q" />
</form>

<form action="/search" method="get">
  <input name="q" />
  <input type="hidden" name="lang" value="de" />
</form>

Con method="post" la query string se conserva, porque los campos van en el cuerpo. Eso no cambia nada para Ikiform: los parámetros de query de la URL del endpoint no se guardan, así que usa inputs ocultos para los valores que quieras conservar.

Inputs fuera del formulario

A veces el diseño necesita un input que no está dentro del elemento <form>, como un registro en el pie junto a otro contenido. El atributo form en un input o un botón lo une a un formulario por id, y envía al action de ese formulario:

footer.html
<form id="newsletter" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post"></form>

<footer>
  <input form="newsletter" name="email" type="email" required />
  <button form="newsletter">Subscribe</button>
</footer>

Actions mailto: y javascript:

action="mailto:you@example.com" pide a la app de correo del visitante que abra un mensaje con los campos. No se envía nada salvo que tenga una app de correo configurada y pulse enviar, y nunca sabrás que lo intentó. action="javascript:..." ejecuta código en lugar de enviar y lo bloquean la mayoría de políticas de seguridad de contenido. Merece la pena sustituir ambos por un endpoint real.

Comprueba que funciona

  1. En Allowed domains del formulario, añade el dominio de tu sitio, y localhost mientras desarrollas. Déjalo vacío para aceptar envíos desde cualquier lugar.
  2. Abre la página publicada, no tu código fuente, y ejecuta document.querySelector("form").action en la consola. Imprime tu URL completa de Ikiform.
  3. Envía el formulario. El panel Network muestra un POST a ikiform.com respondido con 303, no un POST a tu propio dominio.
  4. En el formulario de dos bandejas, envía una vez con cada botón. Cada envío aparece bajo su propio formulario en el panel.
  5. Revisa la bandeja de entrada de cada destinatario de las notificaciones. Cada uno recibe un email con los campos, y Reply va a quien envió el formulario cuando este tiene un campo email.

Errores comunes

ProblemaCausa y solución
405 Method Not Allowed desde tu propio dominioEl action es relativo, está vacío o falta, así que el envío fue a tu hosting estático. Usa la URL completa de Ikiform
404 not_found desde ikiform.comEl id del formulario en el action es incorrecto, o el formulario se eliminó. Copia el endpoint desde la página del formulario en el panel
El creador sigue restableciendo el actionAlgunos creadores controlan el action de su bloque de formulario. Usa su ajuste de action personalizado, o un embed con tu propio markup
El navegador avisa de que el formulario no es seguroEl action usa http: en una página https:. El endpoint de Ikiform es solo https:; corrige el esquema
También se envían campos de un segundo formularioLos formularios no se pueden anidar. El navegador cierra el formulario exterior en la etiqueta <form> interior. Usa el atributo form en su lugar

Para el flujo completo de un envío, del clic a la redirección, consulta el resumen. Todo lo que acepta el endpoint está en Formularios HTML.

Preguntas

¿Te atascaste en un paso o quieres una guía para tu caso? Escribe a hello@ikiform.com.