Dynamicznie dodaję <script>
tagi do strony <head>
i chciałbym być w stanie stwierdzić, czy ładowanie się w jakiś sposób nie powiodło - 404, błąd skryptu w załadowanym skrypcie, cokolwiek.
W przeglądarce Firefox działa to:
var script_tag = document.createElement('script');
script_tag.setAttribute('type', 'text/javascript');
script_tag.setAttribute('src', 'http://fail.org/nonexistant.js');
script_tag.onerror = function() { alert("Loading failed!"); }
document.getElementsByTagName('head')[0].appendChild(script_tag);
Jednak to nie działa w IE lub Safari.
Czy ktoś zna sposób, aby to działało w przeglądarkach innych niż Firefox?
(Nie sądzę, aby rozwiązanie wymagające umieszczenia specjalnego kodu w plikach .js było dobre. Jest nieeleganckie i nieelastyczne).
javascript
onerror
script-tag
David
źródło
źródło
if
+ sondowanie jest denerwującym okrucieństwem, którego nie chcę umieszczać we wszystkich JS.Odpowiedzi:
Nie ma zdarzenia błędu dla tagu skryptu. Możesz stwierdzić, kiedy się powiedzie, i założyć, że nie został załadowany po upływie limitu czasu:
źródło
Jeśli zależy Ci tylko na przeglądarkach HTML5, możesz użyć zdarzenia błędu (ponieważ służy to tylko do obsługi błędów, powinno być w porządku, aby obsługiwać to tylko w przeglądarkach następnej generacji dla KISS IMHO).
Ze specyfikacji:
~
Oznacza to, że nie musisz wykonywać żadnych podatnych na błędy sondowań i możesz łączyć je z atrybutami async i defer, aby upewnić się, że skrypt nie blokuje renderowania strony:
Więcej na http://www.w3.org/TR/html5/scripting-1.html#script
źródło
<script src="nonexistent.js" onerror="alert('error!')"></script>
skrzypceUncaught SyntaxError: Unexpected token '<'
(w najnowszym Chrome)<script src="nonexistent.js" onerror="alert('error!')"></script>
powinien znaleźć się w pliku HTML, a nie JS.Skrypt Erwinusa działa świetnie, ale nie jest zbyt jasno zakodowany. Pozwoliłem sobie wyczyścić to i rozszyfrować, co robi. Dokonałem tych zmian:
prototype
.require()
używa zmiennej argumentowejalert()
Domyślnie żadne wiadomości nie są zwracaneJeszcze raz dziękujemy Erwinusowi, sama funkcjonalność jest na miejscu.
źródło
moje działające czyste rozwiązanie (2017)
Jak zauważył Martin, użyte w ten sposób:
LUB
źródło
loaderScript("myscript.js").then(() => { console.log("loaded"); }).catch(() => { console.log("error"); });
Wiem, że to stary wątek, ale mam dla ciebie fajne rozwiązanie (chyba). Jest skopiowany z mojej klasy, która obsługuje wszystkie rzeczy AJAX.
Gdy nie można załadować skryptu, ustawia procedurę obsługi błędów, ale gdy nie jest obsługiwana, powraca do licznika czasu, który sprawdza błędy przez 15 sekund.
źródło
Aby sprawdzić, czy javascript
nonexistant.js
nie zwróciło błędu, musisz dodać zmienną wewnątrzhttp://fail.org/nonexistant.js
like,var isExecuted = true;
a następnie sprawdzić, czy istnieje, gdy tag skryptu jest ładowany.Jeśli jednak chcesz tylko sprawdzić, czy
nonexistant.js
zwrócony jest bez 404 (co oznacza, że istnieje), możesz spróbować zeisLoaded
zmienną ...Obejmuje to oba przypadki.
źródło
Mam nadzieję, że nie zostanie to odrzucone, ponieważ w szczególnych okolicznościach jest to najbardziej niezawodny sposób rozwiązania problemu. Za każdym razem, gdy serwer umożliwia pobranie zasobu Javascript za pomocą CORS ( http://en.wikipedia.org/wiki/Cross-origin_resource_sharing ), masz do dyspozycji bogatą gamę opcji.
Używanie XMLHttpRequest do pobierania zasobów będzie działać we wszystkich nowoczesnych przeglądarkach, w tym IE. Ponieważ chcesz załadować Javascript, przede wszystkim masz JavaScript dostępny. Postęp możesz śledzić za pomocą readyState ( http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener ). Wreszcie, po otrzymaniu zawartości pliku, możesz go wykonać za pomocą eval (). Tak, powiedziałem eval - ponieważ pod względem bezpieczeństwa nie różni się to od normalnego ładowania skryptu. W rzeczywistości podobną technikę sugeruje John Resig, aby mieć ładniejsze tagi ( http://ejohn.org/blog/degrading-script-tags/ ).
Ta metoda pozwala również oddzielić ładowanie od eval i wykonywać funkcje przed i po wystąpieniu eval. Staje się bardzo przydatne podczas równoległego ładowania skryptów, ale oceniając je jeden po drugim - coś, co przeglądarki mogą łatwo zrobić, gdy umieścisz tagi w HTML, ale nie pozwala na to, dodając skrypty w czasie wykonywania za pomocą JavaScript.
CORS jest również lepszy od JSONP do ładowania skryptów ( http://en.wikipedia.org/wiki/XMLHttpRequest#Cross-domain_requests ). Jeśli jednak opracowujesz własne widżety innych firm, które mają być osadzone w innych witrynach, w rzeczywistości powinieneś załadować pliki Javascript z własnej domeny do własnego elementu iframe (ponownie za pomocą AJAX)
W skrócie:
Spróbuj sprawdzić, czy możesz załadować zasób za pomocą AJAX GET
Użyj eval po pomyślnym załadowaniu
Aby to poprawić:
Sprawdź wysyłane nagłówki kontroli pamięci podręcznej
Jeśli potrzebujesz, zajrzyj do buforowania zawartości w localStorage w inny sposób
Sprawdź „degradujący javascript” Resiga, aby uzyskać bardziej przejrzysty kod
Sprawdź require.js
źródło
Ta sztuczka mi się sprawdziła, choć przyznaję, że to chyba nie jest najlepszy sposób na rozwiązanie tego problemu. Zamiast próbować tego, powinieneś zobaczyć, dlaczego skrypty JavaScript się nie ładują. Spróbuj zachować lokalną kopię skryptu na swoim serwerze itp. Lub skontaktuj się z dostawcą zewnętrznym, z którego próbujesz pobrać skrypt.
Tak czy inaczej, więc oto obejście: 1) Zainicjuj zmienną na false 2) Ustaw ją na true, gdy ładuje się javascript (używając atrybutu onload) 3) sprawdź, czy zmienna ma wartość true lub false po załadowaniu treści HTML
źródło
Oto kolejne rozwiązanie oparte na JQuery bez żadnych timerów:
Dzięki: https://stackoverflow.com/a/14691735/1243926
Przykładowe użycie (oryginalna próbka z dokumentacji JQuery getScript ):
źródło
cache:true
dla wywołania $ .getScript (jest to domyślnie wyłączone). W ten sposób dla większości żądań automatycznie używa wersji z pamięci podręcznej do wywołania getScript (oszczędzając opóźnienie)Można to zrobić bezpiecznie, korzystając z obietnic
i używaj w ten sposób
źródło
Powodem, dla którego nie działa w Safari, jest to, że używasz składni atrybutów. To jednak zadziała dobrze:
... z wyjątkiem IE.
Jeśli chcesz sprawdzić skrypt wykonany pomyślnie, po prostu ustaw zmienną za pomocą tego skryptu i sprawdź, czy jest ustawiona w zewnętrznym kodzie.
źródło
<script>
. Jeśli spróbujesz dodać go wcześniej, pojawi się błąd, że tag nie istnieje, a jeśli dodasz go później, skrypt już się uruchomił i wyzwolił swoje zdarzenia. Jedynym sposobem jest wyszukanie skutków ubocznych spowodowanych przez skrypt.zdarzenie powodujące błąd
* Aktualizacja sierpień 2017: onerror jest uruchamiany przez Chrome i Firefox. onload jest uruchamiany przez Internet Explorer. Edge nie uruchamia się ani przy błędzie, ani podczas ładowania. Nie użyłbym tej metody, ale w niektórych przypadkach może działać. Zobacz też
<link> onerror nie działa w IE
*
Definicja i zastosowanie Zdarzenie onerror jest wyzwalane, jeśli podczas ładowania pliku zewnętrznego (np. Dokumentu lub obrazu) wystąpi błąd.
Wskazówka: W przypadku użycia na mediach audio / wideo, powiązane zdarzenia, które występują, gdy występują jakieś zakłócenia w procesie ładowania multimediów, to:
W HTML:
element onerror = "myScript">
W JavaScript za pomocą metody addEventListener ():
object.addEventListener ("błąd", myScript);
Uwaga: metoda addEventListener () nie jest obsługiwana w programie Internet Explorer 8 i wcześniejszych wersjach.
Przykład Wykonaj JavaScript, jeśli wystąpi błąd podczas ładowania obrazu:
img src = "image.gif" onerror = "myFunction ()">
źródło
Zaproponowano ustawienie limitu czasu, a następnie założenie awarii ładowania po upływie limitu czasu.
Problem z takim podejściem polega na tym, że założenie jest oparte na przypadku. Po wygaśnięciu limitu czasu żądanie nadal oczekuje. Żądanie oczekującego skryptu może zostać załadowane, nawet jeśli programista założył, że ładowanie nie nastąpi.
Jeśli żądanie można anulować, program może czekać przez pewien czas, a następnie anulować żądanie.
źródło
Oto jak wykorzystałem obietnicę do wykrycia błędów ładowania, które są emitowane na obiekcie window:
źródło
Cóż, jedyny sposób, w jaki mogę myśleć o robieniu wszystkiego, co chcesz, jest dość brzydki. Najpierw wykonaj wywołanie AJAX, aby pobrać zawartość pliku Javascript. Po zakończeniu możesz sprawdzić kod stanu, aby zdecydować, czy to się powiodło, czy nie. Następnie weź responseText z obiektu xhr i zawiń go w try / catch, dynamicznie utwórz tag script, a dla IE możesz ustawić właściwość text tagu script na tekst JS, we wszystkich innych przeglądarkach powinieneś być w stanie dołącz węzeł tekstowy z zawartością do tagu script. Jeśli istnieje kod, który oczekuje, że tag skryptu faktycznie zawiera lokalizację src pliku, to nie zadziała, ale powinno wystarczyć w większości sytuacji.
źródło