Obtention de l'erreur "Envoi du formulaire annulé car le formulaire n'est pas connecté"


157

J'ai un ancien site Web avec JQuery 1.7 qui fonctionne correctement jusqu'à il y a deux jours. Soudain, certains de mes boutons ne fonctionnent plus et, après avoir cliqué dessus, j'obtiens cet avertissement dans la console:

Envoi du formulaire annulé car le formulaire n'est pas connecté

Le code derrière le clic est quelque chose comme ceci:

 this.handleExcelExporter = function(href, cols) {
   var form = $('<form method="post"><input type="submit" /><input type="hidden" name="layout" /></form>').attr('action', href);
   $('input[name="layout"]', form).val(JSON.stringify(cols));
   $('input[type="submit"]', form).click();
 }

Il semble que Chrome 56 ne prend plus en charge ce type de code. N'est-ce pas? Si oui, ma question est:

  1. Pourquoi est-ce arrivé soudainement? Sans aucun avertissement de dépréciation?
  2. Quelle est la solution de contournement pour ce code?
  3. Existe-t-il un moyen de forcer Chrome (ou d'autres navigateurs) à fonctionner comme avant sans changer de code?

PS Cela ne fonctionne pas non plus dans la dernière version de Firefox (sans aucun message). De plus, cela ne fonctionne pas dans IE 11.0 et Edge! (les deux sans aucun message)


J'ai ajouté un correctif dans la réponse acceptée pour correspondre au fait que le formulaire est un objet jQuery. Notez que cela affecte également le .submit()gestionnaire jQuery (en plus de la .click()méthode indiquée ci-dessus).
ryanm

Réponses:


186

Réponse rapide: ajoutez le formulaire au corps.

document.body.appendChild(form);

Ou, si vous utilisez jQuery comme ci-dessus: $(document.body).append(form);

Détails: Selon les normes HTML, si le formulaire n'est pas associé au contexte de navigation (document), la soumission du formulaire sera abandonnée.

HTML SPEC voir 4.10.21.3.2

Dans Chrome 56, cette spécification a été appliquée.

Différence de code Chrome voir @@ -347,9 +347,16 @@

PS à propos de votre question n ° 1. À mon avis, contrairement à ajax, la soumission de formulaire provoque un déplacement instantané de la page.
Ainsi, afficher un «message d'avertissement obsolète» est presque impossible.
Je pense également qu'il est inacceptable que ce changement sérieux ne soit pas inclus dans la liste des changements de fonctionnalités. Fonctionnalités de Chrome 56 - www.chromestatus.com/features#milestone%3D56


4
Je viens de signaler ce bug par certains utilisateurs. De plus, certains autres utilisateurs n'avaient pas la version mise à niveau, ils pouvaient donc soumettre le formulaire sans problème. Rendre le bogue plus incohérent. Merci pour votre réponse!
Ironicnet

La solution proposée n'a pas fonctionné pour moi en combinaison avec l'utilisation de jQuery, comme dans la question d'origine. Cela a fonctionné à la place: $(document.body).append(form);
Chris

1
@Chris Je viens de modifier la réponse acceptée, car la variable de formulaire est un objet jQuery, pas l'élément de formulaire DOM réel. Comme il était utilisé form[0], cela produirait une erreur "Impossible d'exécuter 'appendChild' sur 'Node': le paramètre 1 n'est pas de type 'Node'." dans Chrome. Ainsi, changez simplement en document.body.appendChild(form[0]).
ryanm

@ryanm, je ne suis qu'un éditeur car j'ai contribué à la ligne suivante $(document.body).append(form);. Vous pouvez ajouter votre solution à la réponse acceptée en la modifiant ou en demandant à @KyungHun Jeon s'il souhaite adopter votre solution au lieu de la sienne.
Chris

@Chris merci! J'ai pensé que puisque la question était dans jQuery, la réponse devrait être aussi (peut être déroutante), mais ma modification semble avoir été rejetée. Juste une note alors pour les autres passants que ça peut être document.body.appendChild(form[0])(légèrement plus rapide) OU $(document.body).append(form).
ryanm

50

si vous voyez cette erreur dans React JS lorsque vous essayez de soumettre le formulaire en appuyant sur Entrée, assurez-vous que tous les boutons du formulaire qui ne soumettent pas le formulaire ont un type="button".

Si vous n'en avez qu'un buttonen type="submit"appuyant sur Entrée, soumettez le formulaire comme prévu.

Références :
https://dzello.com/blog/2017/02/19/demystifying-enter-key-submission-for-react-forms/ https://github.com/facebook/react/issues/2093


6
également une chose à surveiller dans React, le <form>rendu doit encore être rendu dans le DOM après avoir cliqué. c'est-à-dire que cela échouera `{this.state.submitting? <div> Le formulaire est en cours d'envoi </div>: <form onSubmit = {() => this.setState ({submitting: true}) ...> <button ...> </form>} `Alors quand le le formulaire est soumis, state.submittingest défini et le message "Soumission ..." s'affiche à la place du formulaire, puis cette erreur se produit. Le déplacement de la balise de formulaire en dehors du conditionnel garantissait qu'elle était toujours là lorsque cela était nécessaire.
Mike Ruhlin

Bon à savoir. Je suppose que vous n'avez pas besoin de changer l' formélément entier en a div. Je crois que si vous changez simplement le contenu de la formau lieu de remplacer l'élément, cela fonctionnera comme prévu.
vaskort

Donc, comme l'a dit Max Williams, c'est une condition de concurrence - le navigateur vérifie si le formulaire est là, mais le formulaire est déjà parti.
pianoJames

preventDefault () provoque cette alerte de Chrome
imbatman


12

ajoutez l'attribut type = "bouton" au bouton sur qui clique vous voyez l'erreur, cela a fonctionné pour moi.


Fonctionne bien pour moi:
pouce levé

11

Vous devez vous assurer que le formulaire figure dans le document. Vous pouvez ajouter le formulaire au corps.


7
J'avais ceci et il s'est avéré qu'il y avait un onclick ajouté au bouton d'envoi de formulaire distant, qui a supprimé l'élément contenant du formulaire. Il y avait donc essentiellement une condition de concurrence entre le formulaire soumis et le formulaire supprimé.
Max Williams

4
Merci @Max Williams, votre commentaire m'a remis sur la bonne voie plus que la réponse acceptée.
JirkaV

11

Vous pouvez également inclure event.preventDefault (); dans votre handleSubmit (event) {

voir https://facebook.github.io/react/docs/forms.html


2
Les liens vers des ressources externes sont encouragés, mais veuillez ajouter du contexte autour du lien afin que vos collègues utilisateurs aient une idée de ce que c'est et pourquoi il est là. Citez toujours la partie la plus pertinente d'un lien important, au cas où le site cible serait inaccessible ou serait définitivement hors ligne. Voir comment écrire une bonne réponse
Peter Reid

Utiliser des àntdformulaires. Cela a aidé.
Eduard

8

Je vois que vous utilisez jQuery pour l'initialisation du formulaire.

Quand j'essaie la réponse de @KyungHun Jeon, cela ne fonctionne pas pour moi qui utilise jQuery aussi.

J'ai donc essayé d'ajouter le formulaire au corps en utilisant la méthode jQuery:

$(document.body).append(form);

Et ça a marché!


6

Une chose à surveiller si vous voyez cela dans React, c'est que le <form>doit encore être rendu dans le DOM pendant sa soumission. c'est-à-dire que cela échouera

{ this.state.submitting ? 
     <div>Form is being submitted</div> :
     <form onSubmit={()=>this.setState({submitting: true}) ...>
         <button ...>
     </form>
}

Ainsi, lorsque le formulaire est soumis, state.submittingest défini et que le message "Soumission ..." s'affiche à la place du formulaire, cette erreur se produit.

Déplacer la balise de formulaire en dehors du conditionnel garantissait qu'elle était toujours là lorsque cela était nécessaire, c'est-à-dire

<form onSubmit={...} ...>
  { this.state.submitting ? 
     <div>Form is being submitted</div> :
     <button ...>
  }
</form>

Conditions de course!
pianoJames

2

J'ai été confronté au même problème dans l'une de nos implémentations.

nous utilisions jquery.forms.js. qui est un plugin de formulaires et disponible ici. http://malsup.com/jquery/form/

nous avons utilisé la même réponse fournie ci-dessus et collé

$(document.body).append(form);

et cela a fonctionné, merci.


1

En fonction de la réponse de KyungHun Jeon, mais l'appendChild attend un nœud dom, alors ajoutez un index à l'objet jquery pour renvoyer le nœud: document.body.appendChild(form[0])


2
Tu veux dire document.body.appendChild(form[0])?
efeder le

1

Ajout pour la postérité car ce n'est pas lié au chrome, mais c'était le premier fil qui est apparu sur Google lors de la recherche de cette erreur de soumission de formulaire.

Dans notre cas, nous avons joint une fonction pour remplacer le html div actuel par une animation de "chargement" lors de la soumission - comme cela s'est produit avant que le formulaire ne soit soumis, il n'y avait plus de formulaire ni de données à soumettre.

Une erreur très évidente rétrospectivement, mais au cas où quelqu'un se retrouverait ici, cela pourrait lui faire gagner du temps dans le futur.


1

J'ai reçu cette erreur dans react.js. Si vous avez un bouton dans le formulaire que vous souhaitez agir comme un bouton et ne pas soumettre le formulaire, vous devez lui donner type = "bouton". Sinon, il essaie de soumettre le formulaire. Je crois que vaskort a répondu à cela avec une documentation que vous pouvez consulter.


C'est un avertissement: la soumission du formulaire a été annulée car le formulaire n'est pas connecté. Désolé d'avoir oublié d'ajouter cela.
Isaiah Larsen

1
Je peux le confirmer. J'ai reçu le même avertissement dans React, Form submission canceled because the form is not connectedchaque fois que j'appuyais sur le bouton "Annuler" de mon formulaire. Après avoir ajouté type="button"à mon bouton "Annuler", je ne reçois plus l'avertissement. Merci!
Ben


0

Vous pouvez également le résoudre, en appliquant un seul patch dans le jquery-xxxjs, ajoutez simplement après "try {rp;} catch (m) {}" ligne 1833 ce code:

if (r instanceof HTMLFormElement &&! r.parentNode) { r.style.display = "none"; document.body.append (r); r [p] (); }

Cela valide lorsqu'un formulaire ne fait pas partie du corps et l'ajoute.


0

J'ai remarqué que j'obtenais cette erreur, car mon code HTML n'avait pas de <body>balise.

Sans instruction <body>, when document.body.appendChild(form);n'avait pas d'objet corps à ajouter.


-1

J'ai vu ce message en utilisant angular, donc j'ai juste sorti method = "post" et action = "", et l'avertissement a disparu.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.