> Manuales > Manual de Ajax práctico

Cómo enviar un formulario por Ajax de manera sencilla usando la interfaz de XMLHttpRequest y el método HTTP POST.

Enviar un formulario por Ajax usando XMLHttpRequest

En el artículo anterior aprendimos a usar XMLHttpRequest para hacer solicitudes al servidor asíncronas, sin recargar la página, lo que se conoce comúnmente como Ajax. Se trataba de un ejemplo sencillo para comenzar a familiarizarse con esta interfaz de trabajo de Ajax. Si no tuviste ocasión de leerlo te recomiendo hacerlo antes de ponerte con esta nueva práctica: Ajax con XMLHttpRequest.

En el presente artículo vamos a realizar un ejemplo con XMLHttpRequest en el que enviaremos datos por POST a una página, transmitiendo por supuesto campos que estarán en un formulario. El ejemplo sigue siendo sencillo, pero ya requiere algo de configuración en el objeto XMLHttpRequest.

Nuestro formulario HTML

Vamos a comenzar viendo rápidamente el formulario HTML que vamos a usar. No tiene nada de especial. En realidad solo lo colocamos para que se vea que es un formulario normal y corriente, pues toda la funcionalidad de envío mediante Ajax la tenemos que realizar con Javascript.

<form action="recibir.php" id="formulario">
  <p>
    Empresa:
    <br>
    <input type="text" name="empresa" id="empresa">
  </p>
  <p>
    CIF:
    <br>
    <input type="text" name="cif" id="cif">
  </p>
  <p>
    Dirección:
    <br>
    <input type="text" name="direccion" id="direccion">
  </p>
  <p>
    <input type="submit" value="Enviar">
  </p>
</form>

Solo quiero que te fijes que tienes el action del formulario dirigido a una página PHP, pues para recibir los datos por POST en la página de destino y componer la respuesta necesitaremos algo de programación del lado del servidor.

Configurar el evento de envío del formulario con Javascript

Como segundo paso vamos a realizar el evento de envío de formulario, que tendremos que detectar para evitar que se mande de manera corriente.

La manera corriente de enviar un formulario sería recargar la página completamente, sin embargo el objetivo es enviarlo por Ajax, por lo que tendremos que detectar el momento en el que el usuario pulsa el botón de submit y parar el envío del formulario, para a continuación enviarlo por Ajax.

Para ello vamos a acceder al objeto del formulario y crear un evento "submit", parando el envío del formulario predeterminado.

let form = document.getElementById('formulario');
form.addEventListener('submit', function(e) {
  e.preventDefault();
  // El formulario se ha bloqueado, para que no se envíe de manera normal
});

Supongo que el código anterior lo tienes claro, si no es así te recomiendo leer el artículo sobre eventos en Javascript. El método preventDefault() sobre el objeto evento es el que nos permite parar el envío del formulario.

Código para envío por Ajax enviando datos por POST

Ahora vamos con el código que más nos interesa, que es justamente la parte de la conexión por Ajax y el envío de los datos por post. Voy a poner todo el código a continuación y lo iremos comentando después.

let form = document.getElementById('formulario');
form.addEventListener('submit', function(e) {
  e.preventDefault();
  let xhr = new XMLHttpRequest();
  xhr.open("POST", form.action);
  xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  xhr.send(datosFormulario());
  xhr.onload = function (e) {
    document.getElementById('respuesta').innerHTML = xhr.responseText;
  }
});

Comenzamos viendo cómo configurar el objeto Ajax para que se envíe usando el método POST del HTTP.

xhr.open("POST", form.action);

Recuerda que con el método open() solamente se prepara la solicitud. Le estamos pasando "POST" como método del HTTP y con form.action accedemos al valor del atributo action de nuestro formulario HTML.

Luego vemos algo muy importante, que es la cabecera del HTTP que se debe enviar para que se sepa que se están mandando datos por POST:

xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

Por último, los datos enviados por el formulario los tenemos que componer nosotros mismos y enviarlos en el método send().

xhr.send(datosFormulario());

Como puedes apreciar para componer los datos estamos usando una función llamada datosFormulario(), que se encargará de acceder a los campos de formulario que tengas y colocarlos todos en una cadena.

Esta función podría ser algo como esto:

function datosFormulario() {
  let datos = '';
  datos += 'empresa=' + document.getElementById('empresa').value;
  datos += '&cif=' + document.getElementById('cif').value;
  datos += '&direccion=' + document.getElementById('direccion').value;
  return datos;
}

Usando FormData para componer los datos del formulario

Como habrás comprobado, la parte menos "agradable" de este ejemplo que hemos realizado es la de componer los datos de un formulario en una cadena que enviemos en la solicitud. Tenemos solamente 3 campos, pero imagina tener 20 campos lo repetitivo que sería. Incluso sería difícil de mantener, pues si tuviéramos que cambiar los campos de formulario HTML tendríamos que cambiar el Javascript.

Podríamos usar un bucle para recorrer de manera genérica los campos de formulario, lo que sería una mejoría bastante relevante, pero vamos a aportar una solución todavía mejor que consiste en usar la clase FormData para extraer los datos del formulario sin realizar ninguna operación más que instanciar un objeto.

Básicamente vamos a crear un objeto de la clase FormData indicando el formulario sobre el que queremos obtener los datos. Esto lo conseguimos de manera tan sencilla como puedes ver.

let objetoFormData = new FormData(document.getElementById('formulario'));

Usando FormData además sería innecesaria la cabecera que habíamos entregado antes application/x-www-form-urlencoded. Con todo, el código del envío por POST de un formulario con AJAX podría resumirse así.

let form = document.getElementById('formulario');
form.addEventListener('submit', function(e) {
  e.preventDefault();
  let xhr = new XMLHttpRequest();
  xhr.open("POST", form.action);
  xhr.send(new FormData(form));
  xhr.onload = function (e) {
    document.getElementById('respuesta').innerHTML = xhr.responseText;
  }
});

Código completo de la página que envía datos por Ajax

Para acabar y por si hay alguna duda, voy a poner aquí todo el código de esta página de envío de datos por Ajax usando POST.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Post por Ajax con XMLHttpRequest</title>
</head>
<body>
  <h2>Enviar datos de una empresa</h2>
  <form action="recibir.php" id="formulario">
    <p>
      Empresa:
      <br>
      <input type="text" name="empresa" id="empresa">
    </p>
    <p>
      CIF:
      <br>
      <input type="text" name="cif" id="cif">
    </p>
    <p>
      Dirección:
      <br>
      <input type="text" name="direccion" id="direccion">
    </p>
    <p>
      <input type="submit" value="Enviar">
    </p>
  </form>

  <div id="respuesta"></div>

  <script>
    let form = document.getElementById('formulario');
    form.addEventListener('submit', function(e) {
      e.preventDefault();
      let xhr = new XMLHttpRequest();
      xhr.open("POST", form.action);
      xhr.send(new FormData(form));
      xhr.onload = function (e) {
        document.getElementById('respuesta').innerHTML = xhr.responseText;
      }
    });
  </script>
</body>
</html>

Y por si alguien tiene alguna curiosidad sobre cómo sería el script PHP que recibe los datos, dejo un posible código por aquí.

<?php
  echo 'Empresa:' . $_POST['empresa'];
  echo '<br>';
  echo 'cif:' . $_POST['cif'];
  echo '<br>';
  echo 'direccion:' . $_POST['direccion'];
  echo '<br>';
?>

En este artículo puedes aprender a recibir datos por post con PHP.

Hemos avanzado bastante en el Taller de Ajax gracias a esta práctica un poco más completa de trabajo con formularios. De todos modos, quedan muchas cosas por aprender en los próximos artículos.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual