Haciendo trampa al enviar formularios por GET.

Ayer me encontré con un dilema. Tenía que hacer que un formulario enviara datos a 2 diferentes lugares para que fueran procesados. Si yo hubiera desarrollado el plugin en el que estaba trabajando hubiera hecho esto de una forma sencilla, pero como no lo desarrollé yo, no me quedó de otra que hacer trampa.

Originalmente el formulario envía datos mediante ajax a un documento dentro del directorio del plugin (wordpress). Para esto, el desarrollador del plugin  ha puesto una acción al evento click del botón submit del formulario. Esta función formatea los datos del formulario en una de las formas más extrañas que he visto y los pasa a un script php qué procesa esos datos, y envía correos al administrador del sitio y al usuario que llenó el formulario.

Ya que la función asignada al evento click del botón submit formatea los datos en una forma algo rara, lo mejor era seguir usando esa función para procesar la información y enviar los correos, pero el cliente requería que el formulario también enviara los datos a un sitio externo, un servicio para rastrear “leads”. Como hacemos esto?

El problema:
El problema es como mandar los datos a dos diferentes partes al mismo tiempo sin poder modificar ninguna de ellas, solo el formulario?

La respuesta:
Necesitamos una imagen.

Por loco que parezca, la solución está en usar una imagen. Lo que yo hice fue desactivar el listener asignado al evento click del botón submit del formulario, y en su lugar asignar un listener al evento submit del mismo. La función que antes estaba asignada al evento click del botón submit termina con una redirección, por lo que cualquier cosa que quicieramos hacer tiene que ser antes de que dicha función se ejecute, pero aun necesitamos ejecutar dicha función para no perder la funcionalidad del envío de emails.

Sabiendo que el servicio de leads espera que el formulario haya sido enviado por GET, podemos simplemente hacer trampa y crear una URL que simule aquella creada por el formulario al ser enviado. Por ejemplo, http://sitio.com?field1=value&field2=value…

Después simplemente creamos una imagen y le asignamos esa URL como valor a su atributo src. El navegador va a hacer una petición, que el servicio va a ejecutar. Al ejecutarse dicha petición, el servicio va a correr el script que procesa el formulario. Lo que pase después ya no es de nuestro interés, ya que en este caso el servicio no regresa ningún mensaje, simplemente hace una redirección.

Luego llamamos a la función original y dejamos que el plugin haga lo que hace originalmente. En código se ve algo así:

(abreviado para brevedad)

//Usualmente wordpress themes usan jquery. Hay que aprovecharlo
$('#form').submit(function(){
   var query = $(this).serialize();
   var img = document.createElement('img');
   img.src = 'http://leadsservice.com/process.php?' + query;//Esto simula enviar el formulario usando GET como método al servicio de leads
   originalFunc();
});

El código original que yo escribí se ve un tanto diferente; por ejemplo,  yo tuve que registrar algunas variables globales para poder acceder a unos datos que php saca de la base de datos, pero la idea es la misma.