Pojawia się błąd „Przesłanie formularza zostało anulowane, ponieważ formularz nie jest połączony”

156

Mam starą stronę internetową z JQuery 1.7, która działa poprawnie jeszcze dwa dni temu. Nagle część moich przycisków już nie działa i po ich kliknięciu w konsoli pojawia się takie ostrzeżenie:

Przesłanie formularza zostało anulowane, ponieważ formularz nie jest połączony

Kod kliknięcia wygląda mniej więcej tak:

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

Wygląda na to, że Chrome 56 nie obsługuje już tego rodzaju kodu. Prawda? Jeśli tak, moje pytanie brzmi:

  1. Dlaczego stało się to nagle? Bez żadnego ostrzeżenia o wycofaniu?
  2. Jakie jest obejście tego kodu?
  3. Czy istnieje sposób, aby zmusić Chrome (lub inne przeglądarki) do działania tak jak wcześniej, bez zmiany kodu?

PS To również nie działa w najnowszej wersji przeglądarki Firefox (bez żadnego komunikatu). Nie działa również w IE 11.0 i Edge! (oba bez żadnej wiadomości)

Mahmoud Moravej
źródło
Dodałem poprawkę w zaakceptowanej odpowiedzi, aby dopasować fakt, że formularz jest obiektem jQuery. Zauważ, że ma to również wpływ na .submit()procedurę obsługi jQuery (oprócz .click()metody wskazanej powyżej).
ryanm

Odpowiedzi:

185

Szybka odpowiedź: dołącz formularz do treści.

document.body.appendChild(form);

Lub, jeśli używasz jQuery jak powyżej: $(document.body).append(form);

Szczegóły: Zgodnie ze standardami HTML, jeśli formularz nie jest powiązany z kontekstem przeglądania (dokumentem), przesyłanie formularza zostanie przerwane.

HTML SPEC, patrz 4.10.21.3.2

W Chrome 56 ta specyfikacja została zastosowana.

Różnica w kodzie Chrome patrz @@ -347,9 +347,16 @@

PS odnośnie twojego pytania nr 1. Moim zdaniem, w przeciwieństwie do Ajaxa, przesłanie formularza powoduje natychmiastowe przesunięcie strony.
Dlatego wyświetlenie „przestarzałego komunikatu ostrzegawczego” jest prawie niemożliwe.
Uważam też, że niedopuszczalne jest, aby ta poważna zmiana nie została uwzględniona na liście zmian funkcji. Funkcje Chrome 56 - www.chromestatus.com/features#milestone%3D56

KyungHun Jeon
źródło
4
Właśnie ten błąd został zgłoszony przez niektórych użytkowników. Ponadto niektórzy użytkownicy nie mieli zaktualizowanej wersji, więc mogli bez problemu przesłać formularz. Zwiększenie niespójności błędu. Dziękuję za odpowiedź!
Ironicnet
Proponowane rozwiązanie nie działało u mnie w połączeniu z wykorzystaniem jQuery, jak w pierwotnym pytaniu. Zamiast tego zadziałało: $(document.body).append(form);
Chris,
1
@Chris Właśnie zredagowałem zaakceptowaną odpowiedź, ponieważ zmienna formularza jest obiektem jQuery, a nie rzeczywistym elementem formularza DOM. Ponieważ był używany form[0], spowodowałby błąd „Nie udało się wykonać 'appendChild' na 'Węzeł': parametr 1 nie jest typu 'Węzeł'.” w przeglądarce Chrome. Dlatego po prostu zmień na document.body.appendChild(form[0]).
ryanm
@ryanm, jestem tylko redaktorem, ponieważ napisałem następujący wiersz $(document.body).append(form);. Możesz dodać swoje rozwiązanie do zaakceptowanej odpowiedzi, edytując ją lub pytając @KyungHun Jeon, czy chce przyjąć Twoje rozwiązanie zamiast swojego.
Chris
@Chris thanks! Pomyślałem, że skoro pytanie było w jQuery, odpowiedź też powinna być (może być myląca), ale moja edycja wygląda tak, jakby została odrzucona. Tylko uwaga dla innych przechodniów, że może to być document.body.appendChild(form[0])(nieco szybciej) LUB $(document.body).append(form).
ryanm
50

Jeśli widzisz ten błąd w React JS, gdy próbujesz przesłać formularz, naciskając klawisz Enter, upewnij się, że wszystkie przyciski w formularzu, które nie wysyłają formularza, mają rozszerzenie type="button".

Jeśli masz tylko jeden buttonz type="submit"naciśnięciem klawisza Enter, wyśle ​​formularz zgodnie z oczekiwaniami.

Źródła :
https://dzello.com/blog/2017/02/19/demystifying-enter-key-submission-for-react-forms/ https://github.com/facebook/react/issues/2093

vaskort
źródło
6
również rzecz, na którą należy zwrócić uwagę w Reakcie, <form>nadal musi renderować się w DOM po kliknięciu. tj. to się nie powiedzie `{this.state.submitting? <div> Formularz jest przesyłany </div>: <form onSubmit = {() => this.setState ({submitting: true}) ...> <button ...> </form>} `Więc kiedy formularz zostanie przesłany, state.submittingzostanie ustawiony, a zamiast formularza zostanie wyświetlony komunikat „przesyłanie ...”, a następnie wystąpi ten błąd. Przeniesienie tagu formularza poza warunek zapewniło, że był tam zawsze, gdy był potrzebny.
Mike Ruhlin
Dobrze wiedzieć. Myślę, że nie musisz zmieniać całego formelementu na a div. Wierzę, że jeśli tylko zmienisz zawartość formzamiast podmieniać element to będzie działał zgodnie z oczekiwaniami.
vaskort
Tak więc, jak powiedział Max Williams, jest to stan wyścigu - przeglądarka sprawdza, czy formularz jest dostępny, ale formularz już zniknął.
pianoJames
PreventDefault () powoduje ten alert z Chrome
imbatman
12

dodaj atrybut type = "button" do przycisku na kto kliknie, widzisz błąd, zadziałało dla mnie.

Tayyab Mehar
źródło
Działa dobrze dla mnie:
kciuk w górę
11

Musisz upewnić się, że formularz znajduje się w dokumencie. Możesz dołączyć formularz do treści.

Liu Tao
źródło
7
Miałem to i okazało się, że do zdalnego przycisku przesyłania formularza dodano przycisk onclick, który usunął element zawierający formularz. Więc zasadniczo istniał warunek wyścigu między przesłaniem formularza a jego usunięciem.
Max Williams
4
Dzięki @Max Williams, twój komentarz przywrócił mi właściwe tory bardziej niż zaakceptowana odpowiedź.
JirkaV
11

alternatywnie dołącz event.preventDefault (); in your handleSubmit (event) {

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

joncode
źródło
2
Zachęcamy do umieszczania linków do zewnętrznych zasobów, ale proszę dodać kontekst wokół łącza, aby inni użytkownicy mieli pojęcie, co to jest i dlaczego się tam znajduje. Zawsze cytuj najbardziej odpowiednią część ważnego linku, na wypadek gdyby strona docelowa była nieosiągalna lub została trwale wyłączona. Zobacz, jak napisać dobrą odpowiedź
Peter Reid
Korzystanie z àntdformularzy. To pomogło.
Eduard
8

Widzę, że używasz jQuery do inicjalizacji formularza.

Kiedy próbuję odpowiedzieć @KyungHun Jeon, nie działa to również dla mnie, gdy używam jQuery.

Próbowałem więc dołączyć formularz do treści przy użyciu metody jQuery:

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

I zadziałało!

Rizki Pratama
źródło
6

Warto zwrócić uwagę, jeśli zobaczysz to w Reakcie, jest to, że <form>nadal musi renderować się w DOM podczas przesyłania. tj. to się nie powiedzie

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

Więc kiedy formularz jest przesyłany, state.submittingzostaje ustawiony, a komunikat „przesyłanie ...” renderuje się zamiast formularza, pojawia się ten błąd.

Przeniesienie tagu formularza poza warunek zapewniło, że był tam zawsze, gdy był potrzebny, tj

<form onSubmit={...} ...>
  { this.state.submitting ? 
     <div>Form is being submitted</div> :
     <button ...>
  }
</form>
Mike Ruhlin
źródło
Warunki wyścigu!
pianoJames
2

Z tym samym problemem spotkałem się w jednej z naszych realizacji.

używaliśmy jquery.forms.js. która jest wtyczką formularzy i jest dostępna tutaj. http://malsup.com/jquery/form/

użyliśmy tej samej odpowiedzi podanej powyżej i wkleiliśmy

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

i zadziałało. dzięki.

Abhinav Chawla
źródło
1

W zależności od odpowiedzi od KyungHun Jeon, ale appendChild oczekuje węzła dom, więc dodaj indeks do obiektu jquery, aby zwrócić węzeł: document.body.appendChild(form[0])

moti irom
źródło
2
Masz na myśli document.body.appendChild(form[0])?
efeder
1

Dodawanie dla potomnych, ponieważ nie jest to związane z Chrome, ale był to pierwszy wątek, który pojawił się w Google podczas wyszukiwania tego błędu przesyłania formularza.

W naszym przypadku dołączyliśmy funkcję zastępującą obecny kod div html animacją „wczytywania” podczas przesyłania - ponieważ miało to miejsce przed przesłaniem formularza, nie było już formularza ani danych do przesłania.

Bardzo oczywisty błąd z perspektywy czasu, ale gdyby ktoś tu trafił, może zaoszczędzić mu trochę czasu w przyszłości.

Matt H.
źródło
1

Otrzymałem ten błąd w respond.js. Jeśli masz przycisk w formularzu, który chcesz zachowywać się jak przycisk i nie wysyłasz formularza, musisz podać mu type = "button". W przeciwnym razie spróbuje wysłać formularz. Wydaje mi się, że Vaskort odpowiedział na to, przedstawiając dokumentację, którą możesz sprawdzić.

Isaiah Larsen
źródło
To ostrzeżenie: przesłanie formularza zostało anulowane, ponieważ formularz nie jest połączony. Przepraszam, że zapomniałem o tym dodać.
Isaiah Larsen
1
Mogę to potwierdzić. Otrzymałem to samo ostrzeżenie w Reakcie Form submission canceled because the form is not connectedza każdym razem , gdy naciskałem przycisk „Anuluj” w moim formularzu. Po dodaniu type="button"do mojego przycisku „Anuluj” nie otrzymuję już ostrzeżenia. Dzięki!
Ben
1

Mogłem pozbyć się tego komunikatu, dodając atrybut type = "button" do elementu button w vue.

Pasham Akhil Kumar Reddy
źródło
0

Możesz również rozwiązać ten problem, stosując pojedynczą poprawkę w jquery-xxxjs, po prostu dodaj po wierszu „try {rp;} catch (m) {}” 1833 ten kod:

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

To sprawdza, kiedy formularz nie jest częścią treści i dodaje go.

Gaytan
źródło
-1

Widziałem tę wiadomość przy użyciu angular, więc po prostu usunąłem metody method = "post" i action = "", a ostrzeżenie zniknęło.

ciężki
źródło