JavaScript console.log powoduje błąd: „Synchroniczne XMLHttpRequest w głównym wątku jest przestarzałe…”


386

Dodałem dzienniki do konsoli, aby sprawdzić status różnych zmiennych bez korzystania z debugera Firefox.

Jednak w wielu miejscach, w których mogę dodać console.logw moim main.jspliku, pojawia się następujący błąd zamiast moich uroczych odręcznych wiadomości do siebie:

Synchroniczne XMLHttpRequest w głównym wątku jest przestarzałe ze względu na jego szkodliwy wpływ na doświadczenie użytkownika końcowego. Aby uzyskać więcej pomocy http://xhr.spec.whatwg.org/

Jakie alternatywy lub opakowania console.logmogę dodać do mojego kodu, które nie spowodują tego błędu?

Czy „robię to źle”?


8
Nie rozumiem, w jaki sposób wywołanie console.log () spowodowałoby wywołanie ajax, chyba że włączona jest jakaś wtyczka zdalnego rejestrowania lub cokolwiek innego.
Marc B

Nie jestem pewien, czy wykonuje wywołanie ajax. Czy pomogłbym, jeśli dołączyłem zrzut ekranu?
Nathan Basanese

6
Zasadniczo xmlhttprequest jest zapytaniem ajax.
Marc B

14
<script>$.ajaxPrefilter(function( options, originalOptions, jqXHR ) { options.async = true; });</script> spowoduje to usunięcie ostrzeżenia. Możesz zobaczyć tutaj ten sam problem.
Akilsree1,

1
Właśnie użyłem get zamiast postu, to pomogło. jQuery.
Stas Kazanin

Odpowiedzi:


278

Zdarzyło mi się to, gdy byłem leniwy i włączyłem tag skryptu jako część zwracanej treści. Takie jak:

Częściowa treść HTML:

<div> 
 SOME CONTENT HERE
</div>
<script src="/scripts/script.js"></script> 

Wydaje się, przynajmniej w moim przypadku, że jeśli zwrócisz taką treść HTML przez xhr, spowoduje to, że jQuery wykona wywołanie, aby uzyskać ten skrypt. To wywołanie następuje z flagą asynchroniczną false, ponieważ zakłada, że ​​potrzebujesz skryptu, aby kontynuować ładowanie.

W sytuacjach takich jak ten lepiej byłoby ci lepiej spojrzeć na jakąś strukturę wiążącą i po prostu zwrócić obiekt JSON, lub w zależności od twojego backendu i szablonów możesz zmienić sposób wczytywania skryptów.

Możesz także użyć jQuery's,getScript() aby pobrać odpowiednie skrypty. Oto skrzypce, to tylko prosta kopia przykładu jQuery, ale nie widzę żadnych ostrzeżeń, gdy skrypty są ładowane w ten sposób.

Przykład

<script>
var url = "/scripts/script.js";
$.getScript(url);
</script>

http://jsfiddle.net/49tkL0qd/


8
błąd polega na tym, że OP używa gdzieś synchronicznego XMLHttpRequests, nie sądzę, aby należna jquery, ponieważ nie wydaje się, że on go używa ... jednak dzieje się to ze mną, gdy próbuję załadować, <script>jak powiedziałeś w wywołaniu zwrotnym asynchronicznego wywołania ajax. Moje ajax wywołanie jest asynchroniczna jednak w zwrotnego robię $('#object').html(data), gdy dane jest kawałek htmlz <script>a gdy linia ta jest wykonywana w której wyświetla się błąd w js console. +1 !!! dzięki :).
albciff,

2
W tym projekcie użyłem JQuery.
Nathan Basanese

1
@ 37coins, jeśli to była odpowiedź; oznacz to jako tak .. i zamień tag javascript na jQuery.
Brett Caswell

3
To był mój problem i najprawdopodobniej również problem PO - PO proszę rozważyć zaznaczenie tego jako odpowiedzi. Tutaj wyższa głosowana odpowiedź obecnie nie pomaga ludziom z tym problemem, więc zaakceptowanie tej odpowiedzi bardzo pomogłoby innym.
Nick Coad

1
tylko FYI jQuery getScript przerywa buforowanie. Myślę, że .ajax zrobi to samo i pozwoli na buforowanie
Ronnie Royston

75

Komunikat ostrzegawczy MOŻE BYĆ spowodowany żądaniem XMLHttpRequest w głównym wątku z flagą asynchroniczną ustawioną na false.

https://xhr.spec.whatwg.org/#synchronous-flag :

Synchroniczne XMLHttpRequest poza pracownikami jest w trakcie usuwania z platformy internetowej, ponieważ ma szkodliwy wpływ na doświadczenie użytkownika końcowego. (Jest to długi proces, który trwa wiele lat.) Programiści nie mogą przekazywać argumentu asynchronicznego, gdy globalne środowisko JavaScript jest środowiskiem dokumentów. Zaleca się, aby programy klienckie ostrzegały o takim użyciu w narzędziach programistycznych i mogą eksperymentować z zgłaszaniem wyjątku InvalidAccessError, gdy wystąpi.

Przyszłym kierunkiem jest zezwolenie na XMLHttpRequests tylko w wątkach roboczych. Wiadomość ma być ostrzeżeniem w tym zakresie.


6
nie, ostrzeżenie o wiadomości jest NIESAMOWITE z powodu żądania XMLHttpRequest w głównym wątku z flagą asynchroniczną ustawioną na false. To może być bardzo dobrze błąd w Firefoksie (ale prawdopodobnie jest to funkcja / implementacja jQuery); tak czy inaczej, w jaki sposób opisanie części specyfikacji byłoby uważane za odpowiedź na pytanie, które twierdzi, że console.logwysyła te ostrzeżenia?
Brett Caswell

1
@Brett - ostatnie dwa zdania mojej odpowiedzi wyjaśniają, dlaczego zawarłem część specyfikacji, którą zrobiłem. Zmodyfikuję swoją odpowiedź, aby była bardziej precyzyjna.
PedanticDan

2
z tym wszystkim, co powiedziano: wszystko, co powiedziałeś w tej odpowiedzi, to poprawna informacja; ponadto jest to prawdopodobnie związane z prawdopodobnym problemem; to znaczy, podniesienie tego ostrzeżenia wpływa na zachowanie i / lub stabilność debuggera. Tym sposobem obejściem problemu może być uniknięcie ostrzeżenia przed skorygowaniem przyczyny.
Brett Caswell

Powinny dodać flagę about:, aby umożliwić lokalne debugowanie. Synchronizacja XHR może być bardzo przydatna w narzędziach / środowiskach debugowania z uruchomionym hostem lokalnym.
user2800679

62

Miałem również ten sam problem, ale udało mi się go rozwiązać, wprowadzając async: true. Wiem, że jest to domyślnie prawda, ale działa, gdy piszę to wprost

$.ajax({
   async: true,   // this will solve the problem
   type: "POST",
   url: "/Page/Method",
   contentType: "application/json",
   data: JSON.stringify({ ParameterName: paramValue }),
});

2
To nie był powód w moim przypadku ... tylko usunięcie async: false bez zmiany true ustalona, że
hsobhy

@ Irfan w moim przypadku ustawienie synchronizacji: fałsz, które pomogło!
t_plusplus

34

Debuger na żywo programu Visual Studio 2015/2017 wstrzykuje kod zawierający przestarzałe wywołanie.


13
Spędziłem sporo czasu próbując zrozumieć, dlaczego widziałem to ostrzeżenie; Pomyślałem, że podzielę się najbardziej odpowiednim pytaniem SO, aby inni mogli zaoszczędzić trochę czasu.
Charlie

22

Czasami konieczne jest załadowanie skryptu ajax, ale opóźnienie przygotowania dokumentu do momentu załadowania skryptu.

jQuery obsługuje to z holdReady()funkcją.

Przykładowe użycie:

$.holdReady(true);                              //set hold
function releaseHold() { $.holdReady(false); }  //callback to release hold
$.getScript('script.js', releaseHold);          //load script then release hold

Rzeczywiste ładowanie skryptu jest asynchroniczne ( bez błędów ), ale efekt jest synchroniczny, jeśli reszta kodu JavaScript działa po przygotowaniu dokumentu .

Ta zaawansowana funkcja byłaby zwykle używana przez dynamiczne programy ładujące skrypty, które chcą załadować dodatkowe JavaScript, takie jak wtyczki jQuery, zanim pozwolą na wystąpienie zdarzenia gotowego, nawet jeśli DOM może być gotowy.

Dokumentacja:
https://api.jquery.com/jquery.holdready


AKTUALIZACJA 7 stycznia 2019 r

Z JQMIGRATE :

Funkcja jQuery.holdReady () jest przestarzała

Przyczyna:jQuery.holdReady() metoda została zaniechana ze względu na jego szkodliwy wpływ na globalną wydajność strony. Ta metoda może uniemożliwić zainicjowanie całego kodu na stronie przez dłuższy czas.

Rozwiązanie: Przepisz stronę tak, aby nie wymagała opóźnienia wszystkich programów obsługi jQuery. Można to osiągnąć na przykład poprzez późne ładowanie tylko kodu wymagającego opóźnienia, jeśli uruchomienie jest bezpieczne. Ze względu na złożoność tej metody jQuery Migrate nie próbuje wypełnić funkcji. Jeśli podstawowa wersja jQuery używana z jQuery Migrate już nie zawiera, jQuery.holdReady()kod przestanie działać wkrótce po pojawieniu się tego ostrzeżenia.



13

@Webgr częściowa odpowiedź faktycznie pomogła mi debugować to ostrzeżenie @ logu konsoli, szkoda, że ​​inna część tej odpowiedzi przyniosła tyle głosów negatywnych :(

W każdym razie oto, jak dowiedziałem się, co było przyczyną tego ostrzeżenia w moim przypadku:

  1. Użyj przeglądarki Chrome> Hit F12, aby przynieść DevTools
  2. Otwórz menu szuflady (w Chrome 3 pionowe kropki w prawym górnym rogu)
  3. W obszarze Konsola > zaznacz opcję Zaloguj XMLHttpRequests opcję
  4. Załaduj ponownie stronę, na której pojawił się błąd i obserwuj, co dzieje się z każdym żądaniem ajax w dzienniku konsoli.

W moim przypadku inna wtyczka ładowała 2 biblioteki .js po każdym wywołaniu ajax, które absolutnie nie były wymagane ani konieczne. Wyłączenie nieuczciwej wtyczki usunęło ostrzeżenie z dziennika. Od tego momentu możesz albo spróbować rozwiązać problem samodzielnie (np. Ograniczyć ładowanie skryptów do określonych stron lub zdarzeń - jest to zbyt specyficzne dla odpowiedzi tutaj) lub skontaktować się z twórcą wtyczki innej firmy, aby go rozwiązać.

Mam nadzieję, że to komuś pomoże.


// , Dziękuję za odpowiedź! To pytanie dotyczyło tylko przeglądarki Firefox. Chciałbym zobaczyć, że miało to miejsce w Chrome. Wydaje się to jednak raczej usuwać ostrzeżenie, niż faktycznie naprawiać problem. Czy to jest poprawne?
Nathan Basanese

Wygląda na to, że Chrome ma bardziej zaawansowane funkcje w DevTools niż wersja Firefox. Fakt, że nie jest zgłaszany w przeglądarce Firefox, nie oznacza, że ​​nie jest obecny. To całkowicie naprawiło mój problem, a nie tylko go ukryło. Usunąłem skrypty z problematycznej wtyczki i strony, które zostały „przeładowane” przy każdym wywołaniu ajax.
dev101

// Czy uważasz, że warto podnieść problem z programistami Firefox?
Nathan Basanese

Nie, nie konieczne. Właśnie ponownie przetestowałem moją skrzynkę z najnowszym Firefoksem i ostrzeżenie „Synchroniczne XMLHttpRequest w głównym wątku ...” również zostało zdecydowanie zgłoszone w dzienniku konsoli. Tak więc, przynajmniej w moim przypadku, nie był to problem specyficzny dla przeglądarki. Teraz, jak można użyć Firefoksa do debugowania XMLHttpRequest za pomocą karty Sieć, obserwując, jak zasoby .js są wywoływane po każdym żądaniu ajax. Robi to samo, chociaż w Chrome jest bardziej usprawniony / filtrowany. developer.mozilla.org/en-US/docs/Tools/Network_Monitor
dev101

8

Patrzyłem na wszystkie imponujące odpowiedzi. Myślę, że powinien dostarczyć kod, który daje mu problem. Biorąc pod uwagę poniższy przykład, jeśli masz skrypt do linku do jquery w page.php, dostaniesz to powiadomienie.

$().ready(function () {
    $.ajax({url: "page.php",
        type: 'GET',
        success: function (result) {
        $("#page").html(result);
   }});
 });

6

Otrzymuję takie ostrzeżenie w następującym przypadku:

1) plik1, który zawiera <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>. Strona ma pola wprowadzania. Wpisuję wartość w polu wprowadzania i klikam przycisk. Jquery wysyła dane wejściowe do zewnętrznego pliku php.

2) zewnętrzny plik php zawiera także jquery, aw zewnętrznym pliku php także <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>. Bo jeśli to dostanie ostrzeżenie.

Usunięty <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>z zewnętrznego pliku php i działa bez ostrzeżenia.

Jak rozumiem przy ładowaniu pierwszego pliku (file1), ładuję jquery-1.10.2.jsi ponieważ strona nie ładuje się ponownie (wysyła dane do zewnętrznego pliku php za pomocą jquery $.post), to jquery-1.10.2.jsdalej istnieje. Więc nie trzeba go ponownie ładować.


5

Dostałem ten wyjątek, kiedy ustawiłem adres URL w zapytaniu, np. „Example.com/files/text.txt”. Zmieniłem adres URL na „ http://example.com/files/text.txt ” i ten wyjątek zniknął.


Wydaje się, że mój problem dotyczy również adresu URL. Skopiowałem skrypt do tymczasowego adresu URL, aby nad nim pracować, i wtedy pojawił się błąd. Nie z oryginalnego adresu URL.
jeffery_the_wind

5

Mam ten wyjątek dotyczący dołączania jednego skryptu can.js do innego, np.

{{>anotherScript}}

To wydaje się być główną przyczyną (ładowanie dodatkowych <skryptów> i dołączanie ich do <head> w DOM)
Odzyskiwanie Nerdaholic

5

W aplikacji MVC otrzymałem to ostrzeżenie, ponieważ otwierałem okno Kendo metodą zwracającą View () zamiast PartialView (). View () próbował ponownie pobrać wszystkie skrypty strony.


5

Zdarzyło mi się to w ZF2. Próbowałem załadować zawartość modalną, ale wcześniej zapomniałem wyłączyć układ.

Więc:

$viewModel = new ViewModel();
$viewModel->setTerminal(true);
return $viewModel;

5

Podobnie jak @Nycen, dostałem również ten błąd z powodu linku do Cloudfare. Mój był dla wtyczki Select2 .

aby to naprawić właśnie usunąłem

 src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"

i błąd zniknął.


5
  1. W Chrome press F12
  2. Narzędzia do rozwijania-> naciśnij F1.
  3. Zobacz ustawienia-> ogólne-> Wygląd: "Don't show chrome Data Saver warning"- ustaw to pole wyboru.
  4. Zobacz ustawienia-> ogólne-> Konsola: "Log XMLHTTPRequest"- ustaw także to pole wyboru.

Cieszyć się



4

W moim przypadku było to spowodowane skryptem flexie, który był częścią aplikacji „CDNJS Selections” oferowanej przez Cloudflare .

Według Cloudflare „Ta aplikacja jest przestarzała w marcu 2015 r.”. Wyłączyłem go i wiadomość natychmiast zniknęła.

Możesz uzyskać dostęp do aplikacji, odwiedzając https://www.cloudflare.com/a/cloudflare-apps/twojadomena.com

Uwaga: jest to kopia mojej odpowiedzi w tym wątku Ostrzeżenie synchronicznego XMLHttpRequest i <skrypt> (odwiedziłem oba, szukając rozwiązania)


3

Naprawiłem to za pomocą poniższych kroków:

  1. Sprawdź skrypty CDN i dodaj je lokalnie.
  2. Przenieś zawarte skrypty do sekcji nagłówka.

3

W moim konkretnym przypadku renderowałem częściowo Railsy, ​​bez render layout: falsektórych ponownie renderowałem cały układ, łącznie ze wszystkimi skryptami w <head>tagu. Dodanie render layout: falsedo akcji kontrolera naprawiło problem.


3

Dla mnie problem polegał na tym, że w żądaniu OK oczekiwałem, że odpowiedź ajax będzie dobrze sformatowanym ciągiem HTML, takim jak tabela, ale w tym przypadku serwer napotkał problem z żądaniem, przekierowując na stronę błędu, i dlatego <scriptzwróciłem kod HTML strony błędu ( gdzieś był tag. Konsola zarejestrowała odpowiedź ajax i wtedy zdałem sobie sprawę, że nie jest to, czego się spodziewałem, a następnie przystąpiłem do debugowania.


2

Pytanie pojawiło się w 2014 roku i jest to rok 2019, więc myślę, że dobrze jest poszukać lepszej opcji.

Możesz po prostu użyć fetch interfejsu API w Javascript, co zapewnia większą elastyczność.

na przykład zobacz ten kod

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });

jest to czysty js, nie wymaga wtyczki?
Alok

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.