Comment capturer la réponse de form.submit

130

J'ai le code suivant:

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

            form1.submit();
        }

        function ShowResponse()
        {

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

Je veux capturer la réponse html de form1.submit? Comment puis-je faire cela? Puis-je enregistrer une fonction de rappel dans la méthode form1.submit?

nmdr
la source

Réponses:

110

Vous ne pourrez pas le faire facilement avec du javascript simple. Lorsque vous publiez un formulaire, les entrées du formulaire sont envoyées au serveur et votre page est actualisée - les données sont gérées côté serveur. Autrement dit, la submit()fonction ne renvoie rien, elle envoie simplement les données du formulaire au serveur.

Si vous voulez vraiment obtenir la réponse en Javascript (sans rafraîchir la page), alors vous aurez besoin d'utiliser AJAX, et quand vous commencez à parler en utilisant AJAX, vous devez utiliser une bibliothèque. jQuery est de loin le plus populaire et mon préféré. Il existe un excellent plugin pour jQuery appelé Form qui fera exactement ce que vous voulez.

Voici comment vous utiliseriez jQuery et ce plugin:

$('#myForm')
    .ajaxForm({
        url : 'myscript.php', // or whatever
        dataType : 'json',
        success : function (response) {
            alert("The server says: " + response);
        }
    })
;
nickf
la source
5
+1 pour le plugin jQuery Form. C'est génial, mais l'attribut «cible» est faux. Ce n'est pas comme l'attribut «action» du formulaire; c'est-à-dire que ce n'est pas la destination de soumission. À partir de la documentation : target - Identifie le ou les éléments de la page à mettre à jour avec la réponse du serveur.
JCotton
39
pour être honnête, vous n'avez pas BESOIN d'utiliser une bibliothèque pour AJAX. les bibliothèques sont écrites en javascript, donc il existe une solution sans bibliothèque. Cela dit, je suis à 100% en faveur de l'utilisation d'une bibliothèque pour résumer tout le ridicule et la complexité qu'implique un appel AJAX.
Jason le
3
Je publie ce commentaire plus comme un FYI que la solution ci-dessus fonctionne, sauf en ce qui concerne les téléchargements de fichiers via AJAX sur IE 9 et ci-dessous. J'ai eu des problèmes pour soumettre des fichiers via ajax sur des navigateurs IE non HTML5 (IE 9 et inférieurs), je dois donc utiliser un hack iframe. Mais l'utilisation du hack iframe nécessite le form.submit (), mais vous ne pouvez pas attendre une réponse pour vous dire si elle a réussi ou non. Cela m'a laissé dans un dilemme.
javaauthority
17
Utiliser une bibliothèque ne vaut vraiment pas la peine ici. En pur JS, le code n'est pas beaucoup plus compliqué: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

Une alternative Ajax consiste à définir un invisible <iframe>comme cible de votre formulaire et à en lire le contenu <iframe>dans son onloadgestionnaire. Mais pourquoi s'embêter quand il y a Ajax?

Remarque: je voulais juste mentionner cette alternative car certaines des réponses affirment qu'il est impossible d'y parvenir sans Ajax.

Ates Goral
la source
4
Dites si vous souhaitez publier sur une URL pour un téléchargement via un clic sur un bouton? Vous ne pouvez plus utiliser Ajax pour votre demande. Vous souhaitez ensuite nettoyer ou mettre à jour l'interface une fois le téléchargement terminé? Il est maintenant temps de vouloir un rappel d'un POST qui n'est pas Ajax. (Necropost, je sais.)
AlbertEngelB
2
@ Dropped.on.Caprica Yup, c'est toujours un cas d'utilisation légitime pour les <iframe>POST (avec rappel à parent). Pour les téléchargements et les uploads ...
Ates Goral
1
Aussi pour autant que je sache, pour quiconque a besoin de compatibilité avec les anciennes versions d'IE (7+), je suis à peu près sûr que la méthode iframe est la seule solution. Veuillez me corriger si je me trompe car je rencontre actuellement ce problème.
CoffeeIsProgramming
1
Pour détecter le succès d'un téléchargement, une astuce intéressante que j'ai apprise récemment consiste à définir un cookie dans la réponse de téléchargement et à rechercher l'existence de ce cookie dans le navigateur.
Ates Goral
3
Notez que cela ne fonctionnera que si l'action de soumission de formulaire est sur le même site que l'iframe. Sinon, la politique de même origine le bloquera.
TechnoSam
38

La méthode Javascript vanille non jQuery, extraite du commentaire 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);

Pour POST's, le type de contenu par défaut est "application / x-www-form-urlencoded" qui correspond à ce que nous envoyons dans l'extrait ci-dessus. Si vous voulez envoyer "d'autres trucs" ou l'ajuster d'une manière ou d'une autre, voyez ici pour quelques détails.

rogerdpack
la source
8
En fait, c'est la bonne réponse! Parce que toutes les autres réponses font exactement la même chose, mais masquées par une couche supplémentaire de bibliothèques.
john trouvé le
Cela ressemble exactement à ce dont j'ai besoin, car j'ai déjà un fichier PHP qui gère de nombreuses requêtes XMLHttpRequest () directes sur ma page. Mais dans le cas d'un formulaire simple avec des balises typiques <form action = "/mysite/mycode.php"> et <submit>, je ne sais pas comment modifier ... Est-ce que je remplacerais mes appels httprequest javascript (par un callback,) comme dans: <form action = "myhttpreq (" url, etc ...)? ou peut-être que <form action = "#" onsubmit = "return myhttpfunction ()? Quelque chose comme ça? Si c'est aussi simple que ça, cela devrait certainement être LA réponse. Mais je ne sais pas trop comment le configurer.
Randy
1
@Randy Dans mon cas, j'avais un bouton dans le formulaire comme celui-ci <input type='button' onclick="submitForm(); return false;">ou vous pourriez ajouter un écouteur d'événement pour «soumettre» un événement comme la réponse de Marcus: stackoverflow.com/a/51730069/32453
rogerdpack
31

Je le fais de cette façon et cela fonctionne.

$('#form').submit(function(){
    $.ajax({
      url: $('#form').attr('action'),
      type: 'POST',
      data : $('#form').serialize(),
      success: function(){
        console.log('form submitted.');
      }
    });
    return false;
});
rajesh_kw
la source
4
Vous pouvez vouloir event.preventDefault();( event= premier argument de la fonction de soumission) au lieu de return false. Renvoyer false n'empêchera pas simplement le navigateur de soumettre le formulaire, mais empêchera également d'autres effets secondaires qui pourraient être importants. Il y a beaucoup de question liées à ce sujet .
Nate
1
eh bien, oui, retournez false ou preventDefault ou stopPropogation en fonction des besoins.
rajesh_kw
1
Vous devrez peut-être utiliser FormData($("myform")[0])si vous essayez un type d'entrée = téléchargement de fichier.
Aaron Hoffman
1
Pour être un peu plus générique, vous pouvez utiliser event.target.actionet $(event.target).serialize()au lieu de $('#form').attr('action')et $('#form').serialize().
Lie Ryan
17

Futurs chercheurs Internet:

Pour les nouveaux navigateurs (à partir de 2018: Chrome, Firefox, Safari, Opera, Edge et la plupart des navigateurs mobiles, mais pas IE), fetchest une API standard qui simplifie les appels réseau asynchrones (pour lesquels nous avions besoin de XMLHttpRequestjQuery$.ajax ).

Voici une forme traditionnelle:

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

Si un formulaire comme celui-ci vous est remis (ou que vous l'avez créé car il est sémantique html), vous pouvez envelopper le fetchcode dans un écouteur d'événements comme ci-dessous:

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
    });
});

(Ou, si, comme l'affiche originale, vous voulez l'appeler manuellement sans événement de soumission, mettez simplement le fetchcode là-bas et passez une référence à l' formélément au lieu d'utiliserevent.target .)

Documents:

Récupérer: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Autre: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript Cette page en 2018 ne mentionne pas (encore) fetch. Mais il mentionne que l'astuce target = "myIFrame" est obsolète. Et il a également un exemple de form.addEventListener pour l'événement 'submit'.

Marcus
la source
11

Je ne suis pas sûr que vous compreniez ce que fait submit () ...

Lorsque vous effectuez form1.submit();le formulaire, les informations sont envoyées au serveur Web.

Le serveur Web fera tout ce qu'il est censé faire et renverra une toute nouvelle page Web au client (généralement la même page avec quelque chose de modifié).

Donc, il n'y a aucun moyen que vous puissiez "attraper" le retour d'une action form.submit ().

Sergio
la source
J'ai créé une autre page html et l'ai renvoyée en réponse.
Khushboo
6

Il n'y a pas de rappel. C'est comme suivre un lien.

Si vous souhaitez capturer la réponse du serveur, utilisez AJAX ou publiez-la dans une Iframe et récupérez ce qui y apparaît après l' onload()événement de l'iframe .

Diodeus - James MacFarlane
la source
2

Vous pouvez event.preventDefault()dans le gestionnaire de clics de votre bouton d'envoi pour vous assurer que l' submitévénement par défaut du formulaire HTML ne se déclenche pas (ce qui conduit à l'actualisation de la page).

Une autre alternative serait d'utiliser un balisage de formulaire plus pirate: c'est l'utilisation de <form>ettype="submit" qui le comportement souhaité ici; car ceux-ci conduisent finalement à des événements de clic actualisant la page.

Si vous souhaitez toujours utiliser <form>, et vous ne voulez pas écrire cliquez sur Gestion personnalisée, vous pouvez utiliser jQuery ajaxméthode, qui fait abstraction du problème entier loin pour vous en exposant les méthodes de promesse pour success, erroretc.


Pour récapituler, vous pouvez résoudre votre problème en:

• empêcher le comportement par défaut dans la fonction de gestion en utilisant event.preventDefault()

• en utilisant des éléments qui n'ont pas de comportement par défaut (par exemple <form> )

• en utilisant jQuery ajax


(Je viens de remarquer que cette question date de 2008, je ne sais pas pourquoi elle est apparue dans mon flux; en tout cas, j'espère que c'est une réponse claire)

Benny
la source
2

Voici mon code pour ce problème:

<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
la source
1

Si vous souhaitez capturer la sortie d'une requête AJAX à l'aide de Chrome, vous pouvez suivre ces étapes simples:

  1. Ouvrez la boîte à outils des programmeurs
  2. Accédez à la console et n'importe où à l'intérieur
  3. Dans le menu qui apparaît, cliquez sur "Activer la journalisation XMXHTTPRequest"
  4. Après avoir fait cela à chaque fois que vous faites une requête AJAX, un message commençant par "XHR a terminé le chargement: http: // ......" apparaîtra dans votre console.
  5. En cliquant sur le lien qui apparaît, vous amènera l'onglet "Ressources" où vous pourrez voir les en-têtes et le contenu de la réponse!
Panagiotis spiliotis
la source
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
la source
1

En m'appuyant sur la réponse de @rajesh_kw ( https://stackoverflow.com/a/22567796/4946681 ), je gère les erreurs et le succès des messages de formulaire:

    $('#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 : ''));
            }
        });
    });

Je fais usage de this pour que ma logique soit réutilisable, je m'attends à ce que le HTML soit renvoyé en cas de succès, donc je le rend et remplace la page actuelle, et dans mon cas, j'attends une redirection vers la page de connexion si la session est expirée, donc J'intercepte cette redirection afin de préserver l'état de la page.

Les utilisateurs peuvent désormais se connecter via un autre onglet et réessayer de soumettre.

Nate
la source
0

Vous devez utiliser AJAX. L'envoi du formulaire entraîne généralement le chargement d'une nouvelle page par le navigateur.

sblundy
la source
0

Vous pouvez le faire en utilisant la technologie javascript et AJAX. Jetez un œil à jquery et à ce plug-in de formulaire . Il vous suffit d'inclure deux fichiers js pour enregistrer un rappel pour le form.submit.

kgiannakakis
la source
0

Vous pouvez accomplir cela en utilisant jQuery et la ajax()méthode:

<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>

user5435345
la source
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

la première de toutes utiliser $ (document) .ready (function ()) dans cette utilisation ('formid'). submit (function (event)) et ensuite empêcher l'action par défaut après avoir appelé la soumission de formulaire ajax $ .ajax ({,,, ,}); il faudra le paramètre que vous pouvez choisir en fonction de vos besoins puis appeler une fonction success: function (data) {// faire ce que vous voulez mon exemple pour mettre la réponse html sur div}

YogeshBagdawat
la source
0

Tout d'abord, nous aurons besoin de 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;
};

Ensuite, vous faites un message de base et obtenez une réponse

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

});
Euphorie
la source
0

J'ai le code suivant exécuté parfaitement en utilisant ajax avec des données de formulaire en plusieurs parties

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
la source
0

Vous pouvez utiliser jQuery.post () et renvoyer des réponses JSON bien structurées à partir du serveur. Il vous permet également de valider / désinfecter vos données directement sur le serveur, ce qui est une bonne pratique car c'est plus sécurisé (et même plus facile) que de le faire sur le client.

Par exemple, si vous devez publier un formulaire html sur le serveur (pour saveprofilechanges.php) avec des données utilisateur pour une inscription simple:

I. Pièces client:

Partie HTML Ia:

<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>

Partie Ib Script:

$(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. Partie serveur (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
la source
-5

vous pouvez le faire sans ajax.

écrivez votre comme ci-dessous.

.. .. ..

puis dans "action.php"

puis après frmLogin.submit ();

lire la variable $ submit_return ..

$ submit_return contient la valeur de retour.

bonne chance.

anéantir
la source