Abriendo formularios web externos y agregado de datos


<< Peticiones y respuestas web
Canal seguro entre dominios/Secure channel between domains >gt;

Hago la aclaración que el agregado de campos es posible, solo si la página destino pertenece al mismo dominio o si, al pertenecer a un dominio ajeno, tiene alguna programación para generar tantos campos como elementos contenidos el el POST

En el transcurso del mismo proyecto se me planteó un reto interesante: desplegar un formulario web y agregarle datos en campos ocultos. Nada extraordinario; solo que... se trata de una aplicación MVC a la cual no puedo hacerle muchos cambios, además de que algunos datos los tengo disponibles desde un modelo al cual, en ciertos momentos no tengo acceso.

Intenté decantarme por una aproximación jQuery, con lo cual logro perfectamente desplegar el formulario en una nueva ventana pero no logro recuperar los datos que me interesa enviarle. ¿Modificar el modelo para que ahí traiga esos datos? No, ya que eso afectaría la aplicación más allá, y el objetivo es mantenerla íntegra para poder actualizarla con nuevas versiones del fabricante, y en todo caso solo modificar la sección.

He aquí una pantilla de mi código que haría eso desde un botón usando jQuery. Como dije, no es la aproximación que necesitaba por faltarme datos que solo puedo acceder desde otro punto debido a los modelos de datos. Sin embargo, a alguien puede serle util.

$(document).ready(function(){
  $.("#btnId").on("click", function() {
    var nuevoFormulario = document.createElement("form");
    nuevoFormulario.target = "NuevoForm";
    nuevoFormulario.method = "POST";
    nuevoFormulario.action = "URL_destino";

    //Desde aquí...
    var campo = document.createElement("input");
    campo.type = "hidden";
    campo.name = "txtCampo";
    campo.value = "ElValor";
    nuevoFormulario.appendChild(campo);
    //... Hasta aquí por cada campo que quieras agregar

    document.body.appendChild(nuevoFormulario);

    ventana = window.open("", "NuevoForm", 
                          "status=0, title=0, height=600, width=800, scrollbars=1");

    if (ventana) {
      nuevoFormulario.submit();
    } else {
      alert('Algo inesperado ocurrió.');
    }
  });
});

Existe una parte dentro del código original que me permite accesar a los datos que me interesan, pero es en la parte entre el modelo y el controlador, por lo que es puro código C#.

Analizando esa parte, y procurando afectar lo menos al resto del proyecto, encontré que en el Controlador obtengo los datos que necesito, los cuales terminé enviando al modelo previamente modificado (situación que quería evitar, pero tuve que afrontar agregándole propiedades públicas simples y que solo me sirven para este efecto para que acepte esos datos. Entonces,
en la vista recupero los datos colocándolos en campos ocultos y mediante el botón del javascript los adjunto al formulario para ser enviados mediante POST.

Para la parte de recuperar datos no es posible hacer esa recuperación si la página de mi popup pertenece a un dominio distinto, esto por políticas de seguridad a nivel de internet. Con el fin de obtener los datos, estoy pensando que el proveedor devuelva los datos a una micro-aplicación, la cual mostraría un rótulo dependiendo del resultado y los datos de respuesta, aquí agregaría un javascript que pasaría los datos a su invocador el cual los colocaría en un formulario y procesaría la información.

Esto depende del proveedor, quien ha de enviar los datos a una URL que le facilitemos por algún mecanismo (directamente hablando con él para que la coloque por hardcode o permita un campo que recibiría la URL en cuestión.

A continuación pongo una plantilla de código que coloqué en el archivo destino al que el servidor externo envía la respuesta. Este archivo destino pertenece a mi dominio, por lo que no debería tener problemas para recuperar los datos. La segunda plantilla de código es para la página dentro de la aplicación original (la que abrió el PopUp) y que permite realizar un proceso (el que definas) al momento de que el PopUp se cierra.

// Diseñado para ejecutarse tan pronto termina de cargarse la página.
$(document).ready(function(){
  var resp = $("#Respuesta").html();
    
  // ... procesamiento de "resp" según requieras... 

  window.opener.document.getElementById("campo_en_aplicacion_original").innerHTML = resp;
  window.close();
});

Esto va después de if (ventana) { nuevoFormulario.submit(); y antes de que se cierre el bloque

var timer = setInterval(function () {
  if (theWindow.closed) {
    clearInterval(timer);
    // El nombre "campo_en_aplicacion_original" lo puse así por consistencia con la plantilla anterior.
    if ($("#campo_en_aplicacion_original").html() == valor_a_comparar) {
      // Procesamiento que requieras. 
    }
  }
}, 1000);

Realmente fue un poquito latoso encontrar la secuencia de códigos, y como se que no soy el único, ni el último que ha de necesitar esto, pues espero que sea de utilidad para más de uno. No olviden comentar, les agradeceré sus opiniones

Comentarios

Entradas populares