Obtendo o erro "Envio do formulário cancelado porque o formulário não está conectado"

156

Eu tenho um site antigo com o JQuery 1.7 que funciona corretamente até dois dias atrás. De repente, alguns dos meus botões não funcionam mais e, depois de clicar neles, recebo este aviso no console:

Envio do formulário cancelado porque o formulário não está conectado

O código por trás do clique é mais ou menos assim:

 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 o Chrome 56 não suporta mais esse tipo de código. Não é? Se sim, minha pergunta é:

  1. Por que isso aconteceu de repente? Sem qualquer aviso de reprovação?
  2. Qual é a solução alternativa para esse código?
  3. Existe uma maneira de forçar o chrome (ou outros navegadores) a funcionar como antes sem alterar nenhum código?

PS: Também não funciona na versão mais recente do firefox (sem nenhuma mensagem). Também não funciona no IE 11.0 & Edge! (ambos sem nenhuma mensagem)

Mahmoud Moravej
fonte
Eu adicionei uma correção na resposta aceita para corresponder ao fato de que o formulário é um objeto jQuery. Observe que isso também afeta o .submit()manipulador jQuery (além do .click()método indicado acima).
Ryanm 02/03

Respostas:

185

Resposta rápida: anexe o formulário ao corpo.

document.body.appendChild(form);

Ou, se você estiver usando o jQuery como acima: $(document.body).append(form);

Detalhes: de acordo com os padrões HTML, se o formulário não estiver associado ao contexto de navegação (documento), o envio do formulário será abortado.

SPEC HTML, consulte 4.10.21.3.2

No Chrome 56, essa especificação foi aplicada.

Dif. De código do Chrome, consulte @@ -347,9 +347,16 @@

PS sobre sua pergunta # 1. Na minha opinião, ao contrário do ajax, o envio de formulários causa movimentação instantânea da página.
Portanto, mostrar 'mensagem de aviso obsoleta' é quase impossível.
Também acho inaceitável que essa alteração séria não esteja incluída na lista de alterações de recursos. Recursos do Chrome 56 - www.chromestatus.com/features#milestone%3D56

KyungHun Jeon
fonte
4
Só tive esse bug relatado por alguns usuários. Além disso, alguns outros usuários não tiveram a versão atualizada, para que pudessem enviar o formulário sem problemas. Tornando o erro mais inconsistente. Obrigado pela sua resposta!
Ironicnet 8/17
A solução proposta não funcionou para mim em combinação com o uso do jQuery, como na pergunta original. Isso funcionou: $(document.body).append(form);
Chris
1
@ Chris Acabei de editar a resposta aceita, já que a variável do formulário é um objeto jQuery, não o elemento do formulário DOM real. Enquanto estava em uso form[0], ele produzia um erro "Falha ao executar 'appendChild' em 'Node': o parâmetro 1 não é do tipo 'Node'." no Chrome. Assim, basta mudar para document.body.appendChild(form[0]).
Ryanm 02/03
@ryanm, sou apenas um editor, pois contribuí com a seguinte linha $(document.body).append(form);. Você pode adicionar sua solução à resposta aceita editando-a ou perguntando a @KyungHun Jeon se ele quer adotar sua solução em vez da dele.
Chris
@ Chris obrigado! Imaginei que, como a pergunta estava no jQuery, a resposta também deveria ser (pode ser confusa), mas minha edição parece ter sido rejeitada. Apenas uma observação para os outros transeuntes que pode ser document.body.appendChild(form[0])(um pouco mais rápido) OU $(document.body).append(form).
ryanm
50

se você estiver vendo esse erro no React JS ao tentar enviar o formulário pressionando enter, verifique se todos os seus botões no formulário que não enviam o formulário têm a type="button".

Se você tiver apenas um buttoncom o type="submit"pressionar Enter irá apresentar o formulário conforme o esperado.

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

vaskort
fonte
6
Também é algo a se observar no React, o <form>ainda precisa ser renderizado no DOM depois que ele é clicado. ou seja, isso falhará `{this.state.submitting? <div> O formulário está sendo enviado </div>: <form onSubmit = {() => this.setState ({submitting: true}) ...> <botão ...> </form>} `Então, quando o o formulário é enviado, state.submittingé definido e a mensagem "enviando ..." é processada em vez do formulário; esse erro ocorre. Mover a tag de formulário para fora do condicional garantiu que ela estivesse sempre lá quando necessário.
Mike Ruhlin
Bom saber. Eu acho que você não precisa alterar todo o formelemento para a div. Acredito que se você apenas alterar o conteúdo do em formvez de substituir o elemento, ele funcionará conforme o esperado.
vaskort
Então, como Max Williams disse, é uma condição de corrida - o navegador está verificando se o formulário está lá, mas o formulário já se foi.
pianoJames
preventDefault () faz com que esse alerta do Chrome
imbatman
12

adicione o tipo de atributo = "botão" ao botão em quem está clicando, você vê o erro, funcionou para mim.

Tayyab Mehar
fonte
Trabalhando bem para mim: thumbsup:
cederlof 02/10/19
11

Você deve garantir que o formulário esteja no documento. Você pode anexar o formulário ao corpo.

Liu Tao
fonte
7
Eu tinha isso e descobriu-se que havia um onclick adicionado ao botão de envio remoto do formulário, que removeu o elemento que continha o formulário. Portanto, havia basicamente uma condição de corrida entre o formulário que está sendo enviado e o formulário que está sendo removido.
Max Williams
4
Obrigado @Max Williams, seu comentário me colocou de volta nos trilhos mais do que a resposta aceita.
precisa saber é
11

alternativamente, inclua event.preventDefault (); no seu handleSubmit (event) {

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

joncode
fonte
2
Os links para recursos externos são incentivados, mas adicione contexto ao redor do link para que seus colegas usuários tenham uma idéia do que é e por que está lá. Sempre cite a parte mais relevante de um link importante, caso o site de destino esteja inacessível ou fique permanentemente offline. Veja como escrever uma boa resposta
Peter Reid
Usando àntdformulários. Isso ajudou.
Eduard
8

Vejo que você está usando jQuery para a inicialização do formulário.

Quando tento a resposta do @KyungHun Jeon, não funciona para mim que use o jQuery também.

Então, tentei anexar o formulário ao corpo usando a maneira jQuery:

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

E funcionou!

Rizki Pratama
fonte
6

Uma coisa a se observar se você vê isso no React é que o <form>ainda precisa renderizar no DOM enquanto está enviando. ou seja, isso falhará

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

Portanto, quando o formulário é enviado, state.submittingé definido e a mensagem "enviando ..." é renderizada em vez do formulário, esse erro ocorre.

Mover a tag do formulário para fora do condicional garantiu que ela estivesse sempre lá quando necessário, ou seja,

<form onSubmit={...} ...>
  { this.state.submitting ? 
     <div>Form is being submitted</div> :
     <button ...>
  }
</form>
Mike Ruhlin
fonte
Condições da corrida!
pianoJames
2

Eu enfrentei o mesmo problema em uma de nossas implementações.

nós estávamos usando jquery.forms.js. que é um plug-in de formulários e disponível aqui. http://malsup.com/jquery/form/

usamos a mesma resposta fornecida acima e colamos

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

e funcionou.Obrigado.

Abhinav Chawla
fonte
1

Dependendo da resposta de KyungHun Jeon, mas o appendChild espera um nó dom, portanto, adicione um índice ao objeto jquery para retornar o nó: document.body.appendChild(form[0])

moti irom
fonte
2
Você quer dizer document.body.appendChild(form[0])?
efeder
1

Adição à posteridade, uma vez que isso não está relacionado ao Chrome, mas esse foi o primeiro segmento que apareceu no Google ao pesquisar esse erro de envio de formulário.

No nosso caso, anexamos uma função para substituir o div html atual por uma animação "loading" no envio - uma vez que ocorreu antes do envio do formulário, não havia mais nenhum formulário ou dados a serem enviados.

Erro muito óbvio em retrospecto, mas caso alguém acabe aqui, isso poderá economizar algum tempo no futuro.

Matt H
fonte
1

Eu recebi esse erro no react.js. Se você possui um botão no formulário que deseja agir como um botão e não envia o formulário, digite-o = "button". Caso contrário, ele tenta enviar o formulário. Acredito que o vaskort respondeu isso com alguma documentação que você pode conferir.

Isaiah Larsen
fonte
É um aviso: o envio do formulário foi cancelado porque o formulário não está conectado. Desculpe por esquecer de adicionar isso.
Isaiah Larsen
1
Eu posso confirmar isso. Recebi o mesmo aviso no React, Form submission canceled because the form is not connectedsempre que pressionava o botão "Cancelar" do meu formulário. Depois de adicionar type="button"ao meu botão "Cancelar", não recebo mais o aviso. Obrigado!
Ben
1

Consegui me livrar da mensagem usando a adição do atributo type = "button" ao elemento button no vue.

Akhamil Pasham Reddy, Kumar
fonte
0

Você também pode resolvê-lo, aplicando um único patch no jquery-xxxjs e adicione depois da linha "try {rp;} catch (m) {}" 1833 este código:

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

Isso valida quando um formulário não faz parte do corpo e o adiciona.

Gaytan
fonte
0

Percebi que estava recebendo esse erro, porque meu código HTML não tinha <body>tag.

Sem um <body>, quando a document.body.appendChild(form);instrução não tinha um objeto de corpo a ser acrescentado.

Gleno
fonte
-1

Vi essa mensagem usando angular, então tirei method = "post" e action = "", e o aviso sumiu.

heavyrick
fonte