Simule el envío del formulario de publicación con una llamada de función con javascript

4 minutos de lectura

Avatar de usuario de Alfred Huang
alfredo huang

Con jQuery, podemos simular el envío de un formulario:

<form id="form1" method="post">
    <input name="key1" value="value1" />
    <input name="key2" value="value2" />
</form>

Con una llamada de función AJAX:

$.post('', { key1: 'value1', key2: 'value2' }, function() {
   // do call back
});

si usamos jquery.form.js

$('#form1').ajaxSubmit({
    success: function() {
        // do call back
    }
});

Bueno, ahora viene mi pregunta:

No tengo el formulario en el marcado y quiero enviar un formulario con algún contenido dinámico usando el método ‘POST’.

Quiero hacer una llamada de función para simular el procedimiento, tal vez algo como:

utils.post('/url', {key1: 'value1', key2: 'value2'});

Después de esa llamada, el efecto es el mismo que el formulario que tengo arriba y lo envío, con una forma sincronizada natural.

¿Hay una buena manera de hacer esto?


Si el problema no está claro, puedo hacer un ejemplo feo para explicar lo que quiero:

util.post = function(url, fields) {
    var $form = $('<form action="'+url+'" method="post"></form>');
    var key, val;
    for(key in fields) {
        if(fields.hasOwnProperty(key)) {
            val = fields[key];
            $form.append('<input type="hidden" name="'+key+'" value="'+val+'" />');
        }
    }
    $form.submit();
}

El método anterior funciona, pero creo que no es lo suficientemente bueno. Cuando los campos tienen un carácter especial o algo más, puede causar un error.

  • no entiendo el problema Solo llama $.post() con esa URL y datos.

    – Barmar

    24 de mayo de 2015 a las 9:16


  • @Barmar Solo quiero enviar el formulario de forma natural, sin usar xhr.

    – Alfredo Huang

    25 de mayo de 2015 a las 1:01

  • ¿A qué te refieres con “de forma natural”?

    – TylerH

    26 de mayo de 2015 a las 2:18

  • @TylerH El efecto es el mismo que si envío un formulario normal, haciendo clic en el botón Enviar.

    – Alfredo Huang

    26 de mayo de 2015 a las 3:06

  • Ese es el método POST. XMLHttpRequest es lo mismo.

    – TylerH

    26 de mayo de 2015 a las 4:34

Avatar de usuario de Barmar
Barmar

Puede usar jQuery para construir el formulario funcionalmente, en lugar de concatenar cadenas, por lo que los caracteres especiales no serán un problema.

Deberá adjuntar este formulario al HTML body antes de enviarlo; versiones recientes de Chrome ahora requiere esto.

var util = {};
util.post = function(url, fields) {
    var $form = $('<form>', {
        action: url,
        method: 'post'
    });
    $.each(fields, function(key, val) {
         $('<input>').attr({
             type: "hidden",
             name: key,
             value: val
         }).appendTo($form);
    });
    $form.appendTo('body').submit();
}

  • Gracias maestro. Por cierto, ¿crees que es una buena práctica hacerlo? Quiero agregar esta función a las funciones de mi kit de herramientas y usarla ampliamente.

    – Alfredo Huang

    25 de mayo de 2015 a las 2:05

  • No veo ninguna razón para no usar algo como esto. Recomiendo encarecidamente este método de creación de elementos DOM, en lugar de construir cadenas HTML.

    – Barmar

    25 de mayo de 2015 a las 2:09

  • Hay un problema con el código. En append función, debe haber $('<input>', {...})

    – Gary

    17 de noviembre de 2015 a las 9:20


  • Esto ahora falla en Google Chrome con un Form submission canceled because the form is not connected

    – Brian M. Hunt

    22 de diciembre de 2016 a las 1:52

  • Añada el formulario al cuerpo. $form.appendTo('body').submit()

    – Barmar

    22 de diciembre de 2016 a las 2:00

Dado que la respuesta aceptada puede que ya no funcione, por ejemplo Navegadores basados ​​en Chromium en algunas circunstancias, aquí hay una solución alternativa:

util.post = function(url, fields) {
  var $form = $('<form>', {
    action: url,
    method: 'post'
  }).append(
    $.map(fields, function(key, val) {
      return $('<input>').attr({
         type: "hidden",
         name: key,
         value: val
      }).appendTo($form);
    })
  )
  var w = window.open("about:blank")
  w.document.write($form[0].outerHTML)
  w.document.forms[0].submit()
}

Su único problema es que, dado que no tiene campos de formulario para obtener datos, no puede usar .serialize para construir la matriz. Solo tiene que construir la matriz manualmente.

Key1…Keyn pueden ser nombres que asigne en lugar de atributos de nombre de campos de formulario (eso es lo que realmente hace la serialización) y los valores pueden ser lo que desee:

  • html de un div;
  • valores calculados por usted;
  • variables javascript;
  • valores provenientes de db;

El punto es que no estás simulando publicar un formulario en ningún caso. Con ajax eres solo haciéndolo asíncrono y esto te ayuda porque no necesitas cambiar/recargar la página para elaborar los resultados del formulario.

¿Ha sido útil esta solución?