jQuery ma przestarzałe synchroniczne żądanie XMLHTTPRequest

119

Podobnie jak wiele innych, moja witryna korzysta z jQuery. Kiedy otwieram narzędzia programistyczne, widzę ostrzeżenie, że XMLHTTPRequest jest

przestarzałe ze względu na jego szkodliwy wpływ na wrażenia użytkownika końcowego.

Kontynuowałem i przeczytałem część dokumentacji , ale była dość techniczna. Czy ktoś może w prosty sposób wyjaśnić konsekwencje przejścia z XMLHTTPRequest na WHATWG? Mówi, że stało się to w 2012 roku.

Ponadto dokumentacja mówi, że synchroniczny XMLHttpRequest poza pracownikami jest w trakcie usuwania z platformy internetowej, a kiedy tak się dzieje, jeśli agent użytkownika miał je w usłudze, czy muszą modyfikować swój istniejący kod?

Edd
źródło
2
Musisz mówić o synchronicznych żądaniach XMLHTTP, a nie asynchronicznych, prawda? Żądania synchroniczne są okropne dla wrażeń użytkownika końcowego (blokują przeglądarkę podczas żądania) i generalnie nie powinny być używane.
jfriend00
2
podaj kod, który to uruchamia
charlietfl
3
Czy to jest pełny tekst, o którym mowa? Synchroniczne XMLHttpRequest w głównym wątku jest przestarzałe ze względu na jego szkodliwy wpływ na środowisko użytkownika końcowego.
Qantas 94 Heavy
1
jQuery daje to ostrzeżenie tylko w przypadku żądań synchronicznych, prawda? Czy celowo wysyłasz żądanie synchroniczne? Jeśli tak, rozwiązaniem jest taka struktura kodu, aby działał z żądaniami asynchronicznymi, co i tak powinieneś zrobić, ponieważ są one znacznie przyjemniejsze z punktu widzenia użytkownika.
nnnnnn
1
Widziałem tę flagę nie tylko na mojej stronie, widziałem ją też na innych, np. Youtube. Jeśli chodzi o specyfikacje, z jaką specyfikacją powinien być zgodny mój kod, W3C czy WHATWG? , odniesienie Nie chcę o to pytać w głównym wątku, ponieważ byłby on oznaczony jako kwestia opinii. @ Qantas94Heavy
Edd

Odpowiedzi:

136

Aby uniknąć tego ostrzeżenia, nie używaj:

async: false

w każdym z twoich $.ajax()połączeń. To jedyna funkcja, XMLHttpRequestktóra jest przestarzała.

Wartość domyślna to async: true, więc jeśli nigdy nie użyjesz tej opcji, twój kod powinien być bezpieczny, jeśli funkcja zostanie kiedykolwiek naprawdę usunięta.

Jednak pewnie nie będzie - może zostanie usunięty ze standardów, ale założę się, że przeglądarki będą go wspierać przez wiele lat. Więc jeśli z jakiegoś powodu naprawdę potrzebujesz synchronicznego AJAX, możesz użyć async: falsei po prostu zignorować ostrzeżenia. Ale są dobre powody, dla których synchroniczny AJAX jest uważany za kiepski styl, więc prawdopodobnie powinieneś spróbować znaleźć sposób, aby tego uniknąć. A ludzie, którzy pisali aplikacje Flash, prawdopodobnie też nigdy nie myśleli, że to zniknie, ale obecnie jest w trakcie wycofywania.

Zwróć uwagę, Fetchże zastępujący interfejs API XMLHttpRequestnie oferuje nawet opcji synchronicznej.

Barmar
źródło
9
To jest więc ostrzeżenie jQuery. Mogę to zignorować? Nie używam synchronicznych wywołań do serwera. Perfekcjonistyczna strona mnie w ogóle nie lubi ostrzeżeń.
Jordan,
2
@Jordan Myślę, że ostrzeżenie pochodzi z przeglądarki, a nie z jQuery. Stanie się tak za każdym razem, gdy spróbujesz użyć synchronicznego AJAX. Jeśli używasz jQuery, stanie się to tylko wtedy, gdy określisz tę opcję $.ajax.
Barmar
2
Używam, jquery.i18n.properties.jsale po mojej stronie nie ma wyraźnego wezwania do $.ajax.Być może wewnętrznie, ale nie jestem pewien.
Manuel Jordan
1
Ta wtyczka ładuje pakiety zasobów z .propertiesplików. Prawdopodobnie używa do tego synchronicznego AJAX, powodując to ostrzeżenie.
Barmar
1
@ManuelJordan ustawienie async: true w i18n może spowodować opóźnienie w wyświetlaniu ciągów znaków wyświetlanych na twojej stronie przy wolnym połączeniu. Zamiast tego pokaż kod ciągu
Siyon DP,
62

Przyjęta odpowiedź jest poprawna, ale znalazłem inną przyczynę, jeśli programujesz w ASP.NET z Visual Studio 2013 lub nowszym i jesteś pewien, że nie wykonałeś żadnych synchronicznych żądań ajax lub nie zdefiniowałeś żadnych skryptów w niewłaściwym miejscu.

Rozwiązaniem jest wyłączenie funkcji „Łącze przeglądarki”, odznaczając opcję „Włącz łącze przeglądarki” na liście rozwijanej paska narzędzi VS, oznaczonej małą ikoną odświeżania skierowaną w prawo. Jak tylko to zrobisz i przeładujesz stronę, ostrzeżenia powinny się zatrzymać!

Wyłącz łącze przeglądarki

Powinno to mieć miejsce tylko podczas lokalnego debugowania, ale nadal dobrze jest znać przyczynę ostrzeżeń.

Sam
źródło
Można wyłączyć web.config, dodając <add key="vs:EnableBrowserLink" value="false" />wewnątrz, <appSettings>jak opisano tutaj: poconosystems.com/software-development/… .
Beel
3
Myślę, że to zła sugestia, aby tylko uzyskać dostęp do komunikatów ostrzegawczych w konsoli. Wyłączyć link do przeglądarki i pozbyć się ulepszeń produktywności, które dodaje browserlink, tylko po to, aby nie widzieć komunikatu ostrzegawczego w konsoli przeglądarki? Lepiej zgłosić błąd za pomocą firmy Microsoft i zostanie on naprawiony.
coding4fun
4
@ coding4fun Dzięki za opinię; możesz zgłosić błąd w firmie Microsoft. Nie mówiłem, że powinieneś wyłączyć link do przeglądarki. Moja odpowiedź jest dokładna co do przyczyny tego ostrzeżenia w niektórych przypadkach i warto wykluczyć coś w swoim własnym kodzie. Osobiście poczułem się lepiej, gdy zdałem sobie sprawę, że to nie jest coś, co zrobiłem źle i pomyślałem, że inni mogą również uznać to za pomocne.
Sam
To naprawiło więcej niż tylko ostrzeżenie Ajax. Mam wszystkie rodzaje bałaganu z linkami przeglądarki w konsoli javascript przy użyciu rdzenia asp.
JoeBass
Czy ktoś wiedziałby, co to jest link do przeglądarki i dlaczego w końcu daje takie ostrzeżenie?
gideon,
15

Zdarzyło mi się to, gdy miałem łącze do zewnętrznego js poza głową tuż przed końcem sekcji ciała. Wiesz, jeden z tych:

<script src="http://somesite.net/js/somefile.js">

Nie miało to nic wspólnego z JQuery.

Prawdopodobnie zobaczyłbyś to samo robiąc coś takiego:

var script = $("<script></script>");
script.attr("src", basepath + "someotherfile.js");
$(document.body).append(script);

Ale nie przetestowałem tego pomysłu.

Dave Friend
źródło
Ostrzeżenie zniknęło, kiedy usunąłem taką linię, której i tak nie używałem: @ Html.Script ("~ / scripts / apps / appname.js")
MsTapp,
10

Wspomniał o tym jako komentarz @ henri-chan , ale myślę, że zasługuje na więcej uwagi:

Kiedy aktualizujesz zawartość elementu nowym kodem HTML za pomocą jQuery / javascript, a ten nowy html zawiera <script>tagi, są one wykonywane synchronicznie, powodując tym samym ten błąd. To samo dotyczy arkuszy stylów.

Wiesz, że dzieje się tak, gdy widzisz ładowanych (wiele) skryptów lub arkuszy stylów, tak jak XHRw oknie konsoli. (firefox).

Hugo Delsing
źródło
3

Żadna z poprzednich odpowiedzi (wszystkie są poprawne) nie pasowała do mojej sytuacji: nie używam asyncparametru in jQuery.ajax()i nie dołączam tagu skryptu jako części zwracanej treści, na przykład:

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

Moja sytuacja jest taka, że ​​wywołuję kolejno dwa żądania AJAX w celu zaktualizowania dwóch elementów div w tym samym czasie:

function f1() {
     $.ajax(...); // XMLHTTP request to url_1 and append result to div_1
}

function f2() {
     $.ajax(...); // XMLHTTP request to url_2 and append result to div_2
}

function anchor_f1(){
$('a.anchor1').click(function(){
     f1();
})
}

function anchor_f2(){
$('a.anchor2').click(function(){
     f2();
});
}

// the listener of anchor 3 the source of problem
function anchor_problem(){
$('a.anchor3').click(function(){
     f1();
     f2();
});
}

anchor_f1();
anchor_f2();
anchor_problem();

Kiedy klikam a.anchor3, pojawia się flaga ostrzegawcza.Rozwiązałem problem, zastępując wywołanie f2 przez click()funkcję:

function anchor_problem(){
$('a.anchor_problem').click(function(){
     f1();
     $('a.anchor_f2').click();
});
}
Adib Aroui
źródło
5
Skrypty nie są wykonywane, jeśli wstawisz je bezpośrednio do DOM przez innerHTML. Więc kiedy wywołujesz .html (), jQuery pobiera i wykonuje synchronicznie wszystkie skrypty zawarte w odpowiedzi html.
Henry Chan,
@HenryChan, próbowałem cię zrozumieć, ale bezskutecznie. Czy mógłbyś mi wyjaśnić prostszymi słowami. Nie wstawiam skryptów do DOM, wstawiam tylko HTML i nadal to rozwiązanie jest dla mnie jedynym działającym rozwiązaniem. Z góry dziękuję
Adib Aroui
2
@whitelettersinblankpapers Myślę, że ma na myśli: wewnątrz twojego wywołania zwrotnego Ajax, jeśli zawartość, którą dodajesz do swoich "div", zawiera znaczniki skryptu, zostaną one wywołane synchronicznie.
Haitham Sweilem,
1

Mój problem: używam asynchronicznych żądań zrzucających kod do bufora. Mam pętlę sprawdzającą bufor co sekundę. Kiedy zrzut dotarł do bufora, wykonuję kod. Używam też limitu czasu. Dla użytkownika końcowego strona działa tak, jakby były używane synchroniczne żądania.

ucieczka
źródło
czy masz trochę kodu, aby wiedzieć, jak to osiągnąć?
ZerOne
5
@runback, czy nie można użyć wywołania zwrotnego done () promise? $.ajax({ url : "example.com", async : true /* default is true */ }).done(function(response){ // Process the dump }) Mam nadzieję, że niczego nie przeczytałem.
pravin
0

Jeśli załadujemy skrypt w częściowym widoku, ten problem się pojawi

  1. Usunąłem skrypt w częściowym widoku i przeszedłem do widoku głównego.

To rozwiązanie działa dobrze dla mnie

A. Chandrashekar shekar
źródło