¿Cómo capturo la respuesta de form.submit?

130

Tengo el siguiente código:

<script type="text/javascript">
        function SubmitForm()
        {

            form1.submit();
        }

        function ShowResponse()
        {

        }
</script>
.
.
.
<div>
    <a href="#" onclick="SubmitForm();">Click</a>
</div>

Quiero capturar la respuesta html de form1.submit? ¿Cómo hago esto? ¿Puedo registrar cualquier función de devolución de llamada en el método form1.submit?

nmdr
fuente

Respuestas:

110

No podrá hacer esto fácilmente con javascript simple. Cuando publica un formulario, las entradas del formulario se envían al servidor y su página se actualiza: los datos se manejan en el lado del servidor. Eso es elsubmit() función en realidad no devuelve nada, solo envía los datos del formulario al servidor.

Si realmente quería obtener la respuesta en Javascript (sin la página refrescante), entonces usted tendrá que utilizar AJAX, y cuando se empieza a hablar sobre el uso de AJAX, usted necesita utilizar una biblioteca. jQuery es, con mucho, el más popular y mi favorito personal. Hay un gran complemento para jQuery llamado Form que hará exactamente lo que parece que quieres.

Así es como usarías jQuery y ese complemento:

$('#myForm')
    .ajaxForm({
        url : 'myscript.php', // or whatever
        dataType : 'json',
        success : function (response) {
            alert("The server says: " + response);
        }
    })
;
nickf
fuente
55
+1 para el complemento jQuery Form. Es increíble, pero tienes el atributo 'objetivo' incorrecto. No es como el atributo 'acción' de la forma; es decir, no es el destino de envío. Desde los documentos : target: identifica los elementos de la página que se actualizarán con la respuesta del servidor.
JCotton
39
Para ser justos, NO NECESITA usar una biblioteca para AJAX. Las bibliotecas se escriben con JavaScript, por lo que existe una solución que no es de biblioteca. Dicho esto, estoy 100% a favor de usar una biblioteca para abstraer toda la ridiculez y complejidad involucradas en hacer una llamada AJAX.
Jason
3
Estoy publicando este comentario más como un FYI que la solución anterior funciona, excepto cuando se trata de Subidas de archivos a través de AJAX en IE 9 y a continuación. He tenido problemas para enviar archivos a través de ajax en navegadores IE no HTML5 (IE 9 y posteriores), así que debo usar un hack de iframe. Pero usar el hack de iframe requiere el formulario.submit (), pero no puede esperar una respuesta que le diga si tuvo éxito o no. Esto me ha dejado en un dilema.
javaauthority
17
Usar una biblioteca realmente no vale la pena aquí. En JS puro, el código no es mucho más complicado:var xhr = new XMLHttpRequest() xhr.open("POST", "myscript.php"); xhr.onload=function(event){ alert("The server says: " + event.target.response); }; var formData = new FormData(document.getElementById("myForm")); xhr.send(formData);
12Me21
59

Una alternativa de Ajax es establecer un invisible <iframe>como el objetivo de su formulario y leer su contenido <iframe>en su onloadcontrolador. ¿Pero por qué molestarse cuando hay Ajax?

Nota: Solo quería mencionar esta alternativa ya que algunas de las respuestas afirman que es imposible lograr esto sin Ajax.

Ates Goral
fuente
44
¿Diga si desea publicar en una URL para descargar mediante un clic de botón? Ahora no puede usar Ajax para su solicitud. ¿Desea luego limpiar o actualizar la interfaz cuando se complete la descarga? Ahora es el momento de querer una devolución de llamada de un POST que no sea Ajax. (Necropost, lo sé)
AlbertEngelB
2
@ Dropped.on.Caprica Sí, sigue siendo un caso de uso legítimo para <iframe>POST (con devolución de llamada a parent). Para descargas y cargas por igual ...
Ates Goral
1
Además, por lo que sé para cualquiera que necesite compatibilidad con versiones anteriores de IE (7+), estoy bastante seguro de que el método iframe es el único camino a seguir. Corríjame si estoy equivocado porque actualmente estoy teniendo este problema en este momento.
CoffeeIsProgramming
1
Para detectar el éxito de una descarga, un buen truco que aprendí recientemente es establecer una cookie en la respuesta de descarga y sondear la existencia de esa cookie en el navegador.
Ates Goral
3
Tenga en cuenta que esto solo funcionará si la acción de envío del formulario está en el mismo sitio que el iframe. De lo contrario, la política del mismo origen lo bloqueará.
TechnoSam
37

La forma Javascript no jQuery vanilla, extraída del comentario de 12me21:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/your/url/name.php"); 
xhr.onload = function(event){ 
    alert("Success, server responded with: " + event.target.response); // raw response
}; 
// or onerror, onabort
var formData = new FormData(document.getElementById("myForm")); 
xhr.send(formData);

Para POST's, el tipo de contenido predeterminado es "application / x-www-form-urlencoded", que coincide con lo que enviamos en el fragmento anterior. Si desea enviar "otras cosas" o modificarlo de alguna manera, vea aquí algunos detalles esenciales.

rogerdpack
fuente
8
En realidad esta es la respuesta correcta! Porque todas las demás respuestas hacen exactamente lo mismo, pero ofuscadas por una capa más de bibliotecas.
johnfound
Esto se ve exactamente como lo que necesito, ya que ya tengo un archivo PHP que maneja muchos XMLHttpRequest () s directos en mi página. Pero en el caso de un formulario simple con las típicas etiquetas <form action = "/mysite/mycode.php"> y <submit>, no estoy seguro de cómo modificarlo. ¿Reemplazaría mis llamadas httprequest de javascript (con un callback,) como en: <form action = "myhttpreq (" url, etc ...)? o tal vez <form action = "#" onsubmit = "return myhttpfunction ()? Algo así? Si es así de fácil, esta definitivamente debería ser LA respuesta. Pero estoy un poco confundido sobre cómo configurarlo.
Randy
1
@Randy En mi caso, tenía un botón dentro del formulario como este <input type='button' onclick="submitForm(); return false;">o podría agregar un detector de eventos para el evento 'enviar' como la respuesta de Marcus: stackoverflow.com/a/51730069/32453
rogerdpack
31

Lo estoy haciendo de esta manera y está funcionando.

$('#form').submit(function(){
    $.ajax({
      url: $('#form').attr('action'),
      type: 'POST',
      data : $('#form').serialize(),
      success: function(){
        console.log('form submitted.');
      }
    });
    return false;
});
rajesh_kw
fuente
44
Es posible que desee event.preventDefault();( event= primer argumento de la función de envío) en lugar de return false. Devolver false no impedirá simplemente que el navegador envíe el formulario, sino que también evitará que ocurran otros efectos secundarios que podrían ser importantes. No son un montón de preguntas relacionadas a esto.
Nate
1
bueno, sí, devuelve false o preventDefault o stopPropogation según las necesidades.
rajesh_kw
1
Es posible que deba usarlo FormData($("myform")[0])si está intentando una entrada tipo = carga de archivo.
Aaron Hoffman el
1
Para ser un poco más genérico, puede usar event.target.actiony en $(event.target).serialize()lugar de $('#form').attr('action')y $('#form').serialize().
Mentira Ryan
16

Futuros buscadores de internet:

Para los nuevos navegadores (a partir de 2018: Chrome, Firefox, Safari, Opera, Edge y la mayoría de los navegadores móviles, pero no IE), fetches una API estándar que simplifica las llamadas de red asíncronas (para las que solíamos necesitar XMLHttpRequesto jQuery $.ajax).

Aquí hay una forma tradicional:

<form id="myFormId" action="/api/process/form" method="post">
    <!-- form fields here -->
    <button type="submit">SubmitAction</button>
</form>

Si se le entrega un formulario como el anterior (o lo creó porque es html semántico), puede envolver el fetchcódigo en un detector de eventos como se muestra a continuación:

document.forms['myFormId'].addEventListener('submit', (event) => {
    event.preventDefault();
    // TODO do something here to show user that form is being submitted
    fetch(event.target.action, {
        method: 'POST',
        body: new URLSearchParams(new FormData(event.target)) // event.target is the form
    }).then((resp) => {
        return resp.json(); // or resp.text() or whatever the server sends
    }).then((body) => {
        // TODO handle body
    }).catch((error) => {
        // TODO handle error
    });
});

(O, si como el póster original desea llamarlo manualmente sin un evento de envío, simplemente coloque el fetchcódigo allí y pase una referencia al formelemento en lugar de usarlo event.target).

Documentos:

Recuperar: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Otro: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript Esa página en 2018 no menciona fetch (todavía). Pero menciona que el truco target = "myIFrame" está en desuso. Y también tiene un ejemplo de form.addEventListener para el evento 'submit'.

Marcus
fuente
10

No estoy seguro de que entiendas lo que submit () hace ...

Cuando tu lo hagas form1.submit(); la información del formulario se envía al servidor web.

El servidor web hará lo que se supone que debe hacer y devolverá una nueva página web al cliente (generalmente la misma página con algo cambiado).

Por lo tanto, no hay forma de "atrapar" el retorno de una acción form.submit ().

Sergio
fuente
Creé otra página html y devolví esto como respuesta.
Khushboo
6

No hay devolución de llamada. Es como seguir un enlace.

Si desea capturar la respuesta del servidor, use AJAX o publíquela en un Iframe y tome lo que aparece allí después del onload()evento del iframe .

Diodeus - James MacFarlane
fuente
2

En event.preventDefault()el controlador de clics, puede hacer clic en el botón Enviar para asegurarse de que el submitevento predeterminado del formulario HTML no se active (que es lo que lleva a la actualización de la página).

Otra alternativa sería usar un marcado de forma más pirata: es el uso de <form>y type="submit"eso se está interponiendo en el comportamiento deseado aquí; ya que estos conducen finalmente a eventos de clic que actualizan la página.

Si desea utilizar todavía <form>, y no desea escribir clic encargo manipuladores, puede utilizar jQuery ajaxmétodo, que abstrae todo el problema de distancia para usted, se exponen métodos prometedores para success, error, etc.


Para recapitular, puede resolver su problema:

• evitar el comportamiento predeterminado en la función de manejo mediante el uso event.preventDefault()

• usar elementos que no tienen un comportamiento predeterminado (p. Ej. <form> )

• usando jQuery ajax


(Acabo de notar que esta pregunta es de 2008, no estoy seguro de por qué apareció en mi feed; de todos modos, espero que esta sea una respuesta clara)

Benny
fuente
2

Este es mi código para este problema:

<form id="formoid" action="./demoText.php" title="" method="post">
    <div>
        <label class="title">First Name</label>
        <input type="text" id="name" name="name" >
    </div>
    <div>
        <input type="submit" id="submitButton"  name="submitButton" value="Submit">
    </div>
</form>

<script type='text/javascript'>
/* attach a submit handler to the form */
$("#formoid").submit(function(event) {

  /* stop form from submitting normally */
  event.preventDefault();

  /* get the action attribute from the <form action=""> element */
  var $form = $( this ), url = $form.attr( 'action' );

  /* Send the data using post with element id name and name2*/
  var posting = $.post( url, { name: $('#name').val()} );

  /* Alerts the results */
  posting.done(function( data ) {
    alert('success');
  });
});
</script>
xchangcheng
fuente
1

En caso de que desee capturar la salida de una solicitud AJAX usando Chrome, puede seguir estos simples pasos:

  1. Abra la caja de herramientas Programadores.
  2. Ve a la consola y en cualquier lugar dentro de ella
  3. En el menú que aparece, haga clic en "Habilitar registro de solicitud XMXHTTP"
  4. Después de hacer eso cada vez que realice una solicitud AJAX, aparecerá un mensaje que comienza con "XHR terminó de cargar: http: // ......" aparecerá en su consola.
  5. Al hacer clic en el enlace que aparece, aparecerá la "pestaña Recursos" donde podrá ver los encabezados y el contenido de la respuesta.
Panagiotis Spiliotis
fuente
1
    $.ajax({
        url: "/users/login/",    //give your url here
        type: 'POST',
        dataType: "json",
        data: logindata,
        success: function ( data ){
        //  alert(data);    do your stuff
        },
        error: function ( data ){
        //  alert(data);    do your stuff
        }
    });
Kamal Kishor
fuente
1

Sobre la base de la respuesta de @rajesh_kw ( https://stackoverflow.com/a/22567796/4946681 ), manejo los errores y el éxito de la publicación de formularios:

    $('#formName').on('submit', function(event) {
        event.preventDefault(); // or return false, your choice
        $.ajax({
            url: $(this).attr('action'),
            type: 'post',
            data: $(this).serialize(),
            success: function(data, textStatus, jqXHR) {
                // if success, HTML response is expected, so replace current
                if(textStatus === 'success') {
                    // https://stackoverflow.com/a/1236378/4946681
                    var newDoc = document.open('text/html', 'replace');
                    newDoc.write(data);
                    newDoc.close();
                }
            }
        }).fail(function(jqXHR, textStatus, errorThrown) {
            if(jqXHR.status == 0 || jqXHR == 302) {
                alert('Your session has ended due to inactivity after 10 minutes.\nPlease refresh this page, or close this window and log back in to system.');
            } else {
                alert('Unknown error returned while saving' + (typeof errorThrown == 'string' && errorThrown.trim().length > 0 ? ':\n' + errorThrown : ''));
            }
        });
    });

Hago uso de this para que mi lógica sea reutilizable, espero que el HTML se devuelva con éxito, así que lo represento y reemplazo la página actual, y en mi caso espero una redirección a la página de inicio de sesión si la sesión se agota, así que Intercepto esa redirección para preservar el estado de la página.

Ahora los usuarios pueden iniciar sesión a través de otra pestaña e intentar enviar nuevamente.

Nate
fuente
0

Necesitas estar usando AJAX. Al enviar el formulario, generalmente el navegador carga una nueva página.

sblundy
fuente
0

Puede hacerlo utilizando javascript y la tecnología AJAX. Eche un vistazo a jquery y a este formulario . Solo necesita incluir dos archivos js para registrar una devolución de llamada para el formulario.submit.

kgiannakakis
fuente
0

Puede lograr esto usando jQuery y el ajax()método:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
function submitform() {
      $.ajax({
        headers: { 
          'Accept': 'application/json',
          'Content-Type': 'application/json' 
        },
        type: "POST",
        url : "/hello.hello",
        dataType : "json",
        data : JSON.stringify({"hello_name": "hello"}),
        error: function () {
          alert('loading Ajax failure');
        },
    	onFailure: function () {
          alert('Ajax Failure');
    	},
    	statusCode: {
          404: function() {
          alert("missing info");
          }   
    	},
        success : function (response) {
          alert("The server says: " + JSON.stringify(response));
        }
      })
      .done(function( data ) {
        $("#result").text(data['hello']);
      });
};</script>

usuario5435345
fuente
0
 $(document).ready(function() {
    $('form').submit(function(event) {
        event.preventDefault();
        $.ajax({
            url : "<wiki:action path='/your struts action'/>",//path of url where u want to submit form
            type : "POST",
            data : $(this).serialize(),
            success : function(data) {
                var treeMenuFrame = parent.frames['wikiMenu'];
                if (treeMenuFrame) {
                    treeMenuFrame.location.href = treeMenuFrame.location.href;
                }
                var contentFrame = parent.frames['wikiContent'];
                contentFrame.document.open();
                contentFrame.document.write(data);
                contentFrame.document.close();
            }
        });
    });
});

Blockquote

en primer lugar, use $ (document) .ready (function ()) dentro de este uso ('formid'). submit (function (event)) y luego evite la acción predeterminada después de llamar al formulario ajax $ .ajax ({,,, ,}); tomará el parámetro que puede elegir según sus requisitos y luego llame al éxito de la función: función (datos) {// haga lo que quiera mi ejemplo para poner la respuesta html en div}

YogeshBagdawat
fuente
0

En primer lugar, necesitaremos serializeObject ();

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

luego haces una publicación básica y obtienes respuesta

$.post("/Education/StudentSave", $("#frmNewStudent").serializeObject(), function (data) {
if(data){
//do true 
}
else
{
//do false
}

});
Euforia
fuente
0

Tengo el siguiente código ejecutado perfectamente usando ajax con datos de formulario de varias partes

function getUserDetail()
{
    var firstName = document.getElementById("firstName").value;
    var lastName = document.getElementById("lastName").value;
    var username = document.getElementById("username").value;
    var email = document.getElementById("email").value;
    var phoneNumber = document.getElementById("phoneNumber").value;
    var gender =$("#userForm input[type='radio']:checked").val();
    //var gender2 = document.getElementById("gender2").value;
    //alert("fn"+firstName+lastName+username+email);
    var roleIndex = document.getElementById("role");
    var role = roleIndex.options[roleIndex.selectedIndex].value;
    var jobTitleIndex = document.getElementById("jobTitle");
    var jobTitle = jobTitleIndex.options[jobTitleIndex.selectedIndex].value;
    var shiftIdIndex = document.getElementById("shiftId");
    var shiftId = shiftIdIndex.options[shiftIdIndex.selectedIndex].value;


    var addressLine1 = document.getElementById("addressLine1").value;
    var addressLine2 = document.getElementById("addressLine2").value;
    var streetRoad = document.getElementById("streetRoad").value;

    var countryIndex = document.getElementById("country");
    var country = countryIndex.options[countryIndex.selectedIndex].value;

    var stateIndex = document.getElementById("state");
    var state = stateIndex.options[stateIndex.selectedIndex].value;

    var cityIndex = document.getElementById("city");
    var city = cityIndex.options[cityIndex.selectedIndex].value;



    var pincode = document.getElementById("pincode").value;

    var branchIndex = document.getElementById("branch");
    var branch = branchIndex.options[branchIndex.selectedIndex].value;

    var language = document.getElementById("language").value;
    var profilePicture = document.getElementById("profilePicture").value;
    //alert(profilePicture);
    var addDocument = document.getElementById("addDocument").value;


    var shiftIdIndex = document.getElementById("shiftId");
    var shiftId = shiftIdIndex.options[shiftIdIndex.selectedIndex].value;


    var data = new FormData();
    data.append('firstName', firstName);
    data.append('lastName', lastName);
    data.append('username', username);
    data.append('email', email);
    data.append('phoneNumber', phoneNumber);
    data.append('role', role);
    data.append('jobTitle', jobTitle);
    data.append('gender', gender);
    data.append('shiftId', shiftId);
    data.append('lastName', lastName);
    data.append('addressLine1', addressLine1);
    data.append('addressLine2', addressLine2);
    data.append('streetRoad', streetRoad);
    data.append('country', country);
    data.append('state', state);
    data.append('city', city);
    data.append('pincode', pincode);
    data.append('branch', branch);
    data.append('language', language);
    data.append('profilePicture', $('#profilePicture')[0].files[0]);
     for (var i = 0; i < $('#document')[0].files.length; i++) {
            data.append('document[]', $('#document')[0].files[i]);
        }



    $.ajax({
        //url : '${pageContext.request.contextPath}/user/save-user',
        type: "POST",
        Accept: "application/json",
        async: true,
        contentType:false,
        processData: false,
        data: data,
        cache: false,

        success : function(data) {      
            reset();
            $(".alert alert-success alert-div").text("New User Created Successfully!");
         },
       error :function(data, textStatus, xhr){
           $(".alert alert-danger alert-div").text("new User Not Create!");
        }


    });


//

}
gajera bhavin
fuente
0

Puede usar jQuery.post () y devolver respuestas JSON bien estructuradas del servidor. También le permite validar / desinfectar sus datos directamente en el servidor, lo cual es una buena práctica porque es más seguro (e incluso más fácil) que hacerlo en el cliente.

Por ejemplo, si necesita publicar un formulario html en el servidor (para guardar el perfil del perfil) con los datos del usuario para un registro simple:

I. Piezas del cliente:

Ia parte HTML:

<form id="user_profile_form">
  <label for="first_name"><input type="text" name="first_name" id="first_name" required />First name</label>
  <label for="family_name"><input type="text" name="family_name" id="family_name" required />Family name</label>
  <label for="email"><input type="email" name="email" id="email" required />Email</label> 
  <input type="submit" value="Save changes" id="submit" />
</form>

Ib Parte del guión:

$(function () {
    $("#user_profile_form").submit(function(event) {
      event.preventDefault();
      var postData = {
        first_name: $('#first_name').val(),
        family_name: $('#family_name').val(),
        email: $('#email').val()
      };
      $.post("/saveprofilechanges.php", postData,
        function(data) {
          var json = jQuery.parseJSON(data);
          if (json.ExceptionMessage != undefined) {
            alert(json.ExceptionMessage); // the exception from the server
            $('#' + json.Field).focus(); // focus the specific field to fill in
          }
          if (json.SuccessMessage != undefined) {
            alert(json.SuccessMessage); // the success message from server
          }
       });
    });
});

II Parte del servidor (saveprofilechanges.php):

$data = $_POST;
if (!empty($data) && is_array($data)) {
    // Some data validation:
    if (empty($data['first_name']) || !preg_match("/^[a-zA-Z]*$/", $data['first_name'])) {
       echo json_encode(array(
         'ExceptionMessage' => "First name missing or incorrect (only letters and spaces allowed).",
         'Field' => 'first_name' // Form field to focus in client form
       ));
       return FALSE;
    }
    if (empty($data['family_name']) || !preg_match("/^[a-zA-Z ]*$/", $data['family_name'])) {
       echo json_encode(array(
         'ExceptionMessage' => "Family name missing or incorrect (only letters and spaces allowed).",
         'Field' => 'family_name' // Form field to focus in client form
       ));
       return FALSE;
    }
    if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
       echo json_encode(array(
         'ExceptionMessage' => "Email missing or incorrectly formatted. Please enter it again.",
         'Field' => 'email' // Form field to focus in client form
       ));
       return FALSE;
    }
    // more actions..
    // more actions..
    try {
       // Some save to database or other action..:
       $this->User->update($data, array('username=?' => $username));
       echo json_encode(array(
         'SuccessMessage' => "Data saved!"
       ));
       return TRUE;
    } catch (Exception $e) {
       echo json_encode(array(
         'ExceptionMessage' => $e->getMessage()
       ));
       return FALSE;
    }
}
Vlado
fuente
-5

puedes hacer eso sin ajax.

escribe tu me gusta a continuación.

.. .. ..

y luego en "action.php"

luego después de frmLogin.submit ();

leer variable $ submit_return ..

$ submit_return contiene el valor de retorno.

buena suerte.

annih
fuente