Obteniendo error "El envío del formulario se canceló porque el formulario no está conectado"

156

Tengo un sitio web antiguo con JQuery 1.7 que funciona correctamente hasta hace dos días. De repente, algunos de mis botones ya no funcionan y, después de hacer clic en ellos, aparece esta advertencia en la consola:

Envío de formulario cancelado porque el formulario no está conectado

El código detrás del clic es algo como esto:

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

Parece que Chrome 56 ya no es compatible con este tipo de código. ¿No es así? En caso afirmativo, mi pregunta es:

  1. ¿Por qué sucedió esto de repente? Sin ninguna advertencia de desaprobación?
  2. ¿Cuál es la solución para este código?
  3. ¿Hay alguna manera de obligar a Chrome (u otros navegadores) a funcionar como antes sin cambiar ningún código?

PD : tampoco funciona en la última versión de Firefox (sin ningún mensaje). ¡Tampoco funciona en IE 11.0 y Edge! (ambos sin ningún mensaje)

Mahmoud Moravej
fuente
Agregué una solución en la respuesta aceptada para que coincida con el hecho de que el formulario es un objeto jQuery. Tenga en cuenta que esto también afecta al .submit()controlador jQuery (además del .click()método indicado anteriormente).
ryanm

Respuestas:

185

Respuesta rápida: agregue el formulario al cuerpo.

document.body.appendChild(form);

O, si está utilizando jQuery como se indica arriba: $(document.body).append(form);

Detalles: de acuerdo con los estándares HTML, si el formulario no está asociado con el contexto de navegación (documento), se cancelará el envío del formulario.

HTML SPEC ver 4.10.21.3.2

En Chrome 56, se aplicó esta especificación.

Dif. De código de Chrome ver @@ -347,9 +347,16 @@

PD sobre tu pregunta # 1. En mi opinión, a diferencia de ajax, el envío de formularios provoca el movimiento instantáneo de la página.
Por lo tanto, mostrar "mensaje de advertencia obsoleto" es casi imposible.
También creo que es inaceptable que este cambio serio no esté incluido en la lista de cambios de características. Funciones de Chrome 56: www.chromestatus.com/features#milestone%3D56

KyungHun Jeon
fuente
44
Acabo de informar sobre este error a algunos usuarios. Además, algunos otros usuarios no tenían la versión actualizada, por lo que podían enviar el formulario sin problemas. Haciendo el error más inconsistente. ¡Gracias por tu respuesta!
Ironicnet
La solución propuesta no funcionó para mí en combinación con el uso de jQuery, como en la pregunta original. Esto funcionó en su lugar: $(document.body).append(form);
Chris
1
@ Chris Acabo de editar la respuesta aceptada, ya que la variable de formulario es un objeto jQuery, no el elemento de formulario DOM real. Como estaba usando form[0], produciría un error "Error al ejecutar 'appendChild' en 'Nodo': el parámetro 1 no es del tipo 'Nodo'". en cromo. Por lo tanto, simplemente cambie a document.body.appendChild(form[0]).
ryanm
@ryanm, solo soy un editor ya que contribuí con la siguiente línea $(document.body).append(form);. De nada, agregue su solución a la respuesta aceptada editándola o preguntándole a @ KyungHun Jeon si quiere adoptar su solución en lugar de la suya.
Chris
@ Chris gracias! Pensé que dado que la pregunta estaba en jQuery, la respuesta también debería serlo (puede ser confuso), pero parece que mi edición fue rechazada. Sólo una nota a continuación para otros transeúntes que puede ser document.body.appendChild(form[0])(un poco más rápido) O $(document.body).append(form).
ryanm
50

si ve este error en React JS cuando intenta enviar el formulario presionando enter, asegúrese de que todos los botones del formulario que no envían el formulario tengan un type="button".

Si solo tiene uno buttoncon type="submit"presionar Enter, enviará el formulario como se esperaba.

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

vaskort
fuente
66
También es algo a tener en cuenta en React, <form>todavía tiene que renderizarse en el DOM después de hacer clic. es decir, esto fallará `{this.state.submitting? <div> El formulario se está enviando </div>: <form onSubmit = {() => this.setState ({submitting: true}) ...> <button ...> </form>} `Entonces, cuando el se envía el formulario, state.submittingse configura y aparece el mensaje "enviando ..." en lugar del formulario, entonces se produce este error. Mover la etiqueta del formulario fuera del condicional garantiza que siempre esté allí cuando sea necesario.
Mike Ruhlin
Bueno saber. Supongo que no tienes que cambiar todo el formelemento a a div. Creo que si solo cambia el contenido del elemento en formlugar de reemplazarlo, funcionará como se espera.
vaskort
Entonces, como dijo Max Williams, es una condición de carrera: el navegador está verificando si el formulario está allí, pero el formulario ya no está.
pianoJames
preventDefault () provoca esta alerta desde Chrome
imbatman
12

agregue el tipo de atributo = "botón" al botón de quién hace clic para ver el error, funcionó para mí.

Tayyab Mehar
fuente
Funciona bien para mí: thumbsup:
cederlof
11

Debe asegurarse de que el formulario esté en el documento. Puede agregar el formulario al cuerpo.

Liu Tao
fuente
77
Tuve esto y resultó que había un onclick agregado al botón de envío de formulario remoto, que eliminó el elemento que contiene el formulario. Básicamente, hubo una condición de carrera entre el formulario que se envió y el que se eliminó.
Max Williams
44
Gracias @Max Williams, tu comentario me volvió a encaminar más que la respuesta aceptada.
JirkaV
11

alternativamente incluir event.preventDefault (); en su handleSubmit (evento) {

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

joncode
fuente
2
Se recomiendan enlaces a recursos externos, pero agregue contexto alrededor del enlace para que sus usuarios tengan una idea de qué es y por qué está allí. Siempre cite la parte más relevante de un enlace importante, en caso de que no se pueda acceder al sitio de destino o se desconecte permanentemente. Vea cómo escribir una buena respuesta
Peter Reid
Utilizando àntdformularios. Esto ayudó
Eduard
8

Veo que está utilizando jQuery para la inicialización del formulario.

Cuando intento la respuesta de @ KyungHun Jeon, no funciona para mí que use jQuery también.

Entonces, intenté agregar el formulario al cuerpo usando la forma jQuery:

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

¡Y funcionó!

Rizki Pratama
fuente
6

Una cosa a tener en cuenta si ve esto en React, es que <form>aún debe mostrarse en el DOM mientras se envía. es decir, esto fallará

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

Entonces, cuando se envía el formulario, state.submitting se configura y mensaje "enviando ..." en lugar del formulario, entonces se produce este error.

Mover la etiqueta del formulario fuera del condicional garantizaba que siempre estuviera allí cuando fuera necesario, es decir

<form onSubmit={...} ...>
  { this.state.submitting ? 
     <div>Form is being submitted</div> :
     <button ...>
  }
</form>
Mike Ruhlin
fuente
¡Condiciones de carrera!
pianoJames
2

Enfrenté el mismo problema en una de nuestras implementaciones.

estábamos usando jquery.forms.js. que es un complemento de formularios y está disponible aquí. http://malsup.com/jquery/form/

utilizamos la misma respuesta proporcionada anteriormente y pegamos

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

y funcionó. Gracias.

Abhinav Chawla
fuente
1

Dependiendo de la respuesta de KyungHun Jeon, pero appendChild espera un nodo dom, así que agregue un índice al objeto jquery para devolver el nodo: document.body.appendChild(form[0])

moti irom
fuente
2
Quieres decir document.body.appendChild(form[0])?
efeder
1

Agregar para la posteridad ya que esto no está relacionado con Chrome, pero este fue el primer hilo que apareció en Google al buscar este error de envío del formulario.

En nuestro caso, adjuntamos una función para reemplazar el div html actual con una animación de "carga" al enviarlo, ya que ocurrió antes de que se enviara el formulario, ya no había ningún formulario o datos para enviar.

Un error muy obvio en retrospectiva, pero en caso de que alguien termine aquí, podría ahorrarle algo de tiempo en el futuro.

Matt H
fuente
1

He recibido este error en react.js. Si tiene un botón en el formulario que desea que actúe como un botón y no envíe el formulario, debe asignarle type = "button". De lo contrario, intenta enviar el formulario. Creo que Vaskort respondió esto con documentación que puede consultar.

Isaiah Larsen
fuente
Es una advertencia: el envío del formulario se canceló porque el formulario no está conectado. Perdón por olvidar agregar eso.
Isaiah Larsen
1
Puedo confirmar esto. Recibí la misma advertencia en React, Form submission canceled because the form is not connectedcada vez que presioné el botón "Cancelar" de mi formulario. Después de agregar type="button"a mi botón "Cancelar", ya no recibo la advertencia. ¡Gracias!
Ben
1

Pude deshacerme del mensaje al agregar el atributo type = "button" al elemento button en vue.

Pasham Akhil Kumar Reddy
fuente
0

También puede resolverlo, aplicando un solo parche en jquery-xxxjs simplemente agregue después de "try {rp;} catch (m) {}" línea 1833 este código:

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

Esto valida cuando un formulario no es parte del cuerpo y lo agrega.

Gaytan
fuente
0

Noté que recibía este error, porque mi código HTML no tenía <body>etiqueta.

Sin un <body>, cuando la document.body.appendChild(form);declaración no tenía un objeto de cuerpo para agregar.

Gleno
fuente
-1

Vi este mensaje usando angular, así que simplemente eliminé method = "post" y action = "", y la advertencia desapareció.

heavyrick
fuente