Tajemniczy „błąd skryptu”. zgłaszane w JavaScript w Chrome i Firefox

199

Mam skrypt, który wykrywa błędy Javascript w mojej witrynie i wysyła je do zaplecza w celu zgłoszenia. Podaje pierwszy napotkany błąd, przypuszczalny numer linii i godzinę.

EDYCJA, aby dołączyć doctype:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:fb="http://www.facebook.com/2008/fbml">

...

<script type="text/javascript">
//<![CDATA[
// for debugging javascript!
(function(window){
    window.onerror = function(msg, url, ln) {
        //transform errors
        if (typeof(msg) === 'object' && msg.srcElement && msg.target) {
            if(msg.srcElement == '[object HTMLScriptElement]' && msg.target == '[object HTMLScriptElement]'){
                msg = 'Error loading script';
            }else{
                msg = 'Event Error - target:' + msg.target + ' srcElement:' + msg.srcElement;
            }
        }

        msg = msg.toString();

        //ignore errors
        if(msg.indexOf("Location.toString") > -1){
            return;
        }
        if(msg.indexOf("Error loading script") > -1){
            return;
        }

        //report errors
        window.onerror = function(){};
        (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url || document.location.toString().replace(/#.*$/, "")) + "&ln=" + parseInt(ln || 0) + "&r=" + (+new Date());
    };
})(window);
//]]>
</script>

Z powodu tego skryptu jestem w pełni świadomy wszelkich błędów javascript, które występują w mojej witrynie. Jednym z największych przestępców jest „Błąd skryptu”. w linii 0. w Chrome 10+ i Firefox 3+. Ten błąd nie istnieje (lub może być nazywany czymś innym?) W Internet Explorerze.

Korekta (23.05.2013): Ten błąd „Błąd skryptu, wiersz 0” jest teraz wyświetlany w IE7 i prawdopodobnie w innych wersjach IE. Prawdopodobnie wynik niedawnej poprawki zabezpieczeń IE, ponieważ takie zachowanie wcześniej nie istniało.

Czy ktoś ma pojęcie, co oznacza ten błąd lub co go powoduje? Zdarza się to w około 0,25% moich wszystkich ładowań stron i stanowi połowę zgłoszonych błędów.

Mike Sherov
źródło
Jaki jest twój typ dokumentu? Jeśli nie deklarujesz typu XHTML, nie potrzebujesz CDATA, co może być przyczyną błędów skryptu.
James
Doceniam pomoc ... Dodano doctype: XHTML. Jednak zdarza się to tylko w 0,25% ładowania stron ... Myślę, że to coś bardziej egzotycznego.
Mike Sherov
3
@jayp: Tylko wspominam. Dokument typu XHTML jest nadal parserem HTML. Musisz wysłać zawartość, application/xhtml+xmlaby uruchomić ją w parserze XHTML (jak mówi specyfikacja XHTML). Istnieje wiele treści, które podają się za XHTML, ale wysyłają normalny typ HTML. Z powodu tego, w jaki sposób twórcy treści używają niepoprawnie XHTML, przeglądarki zdecydowały się używać parsera XML tylko application/xhtml+xml(jest to naprawdę ścisły parser). Hixie.ch/advocacy/xhtml i webdevout.net/articles/beware-of-xhtml mówi dlaczego nie używać HTML parser z XHTML.
Konrad Borowski
11
Westchnienie ... na miłość boską, każdy, kto to czyta, proszę, niech wasze komunikaty o błędach dokładnie wyjaśnią , co poszło nie tak! Oszczędzając 30 sekund wysiłku na napisanie go, marnujesz świat na całe lata!
Roman Starkov,
1
Ignorujesz błąd podczas ładowania błędów skryptu. Czemu? Czy można je zignorować?
rampr

Odpowiedzi:

261

„Błąd skryptu”. zdarza się w Firefox, Safari i Chrome, gdy wyjątek narusza zasady tego samego pochodzenia przeglądarki - tj. gdy błąd występuje w skrypcie hostowanym w domenie innej niż domena bieżącej strony.

Takie zachowanie jest celowe, aby zapobiec wyciekaniu przez skrypty informacji do domen zewnętrznych. Na przykład, dlaczego jest to konieczne, wyobraź sobie przypadkowe odwiedziny evilsite.com, na których wyświetla się strona <script src="yourbank.com/index.html">. (tak, wskazujemy ten skrypt na HTML, a nie JS). Spowoduje to błąd skryptu, ale błąd jest interesujący, ponieważ może nam powiedzieć, czy jesteś zalogowany, czy nie. Jeśli jesteś zalogowany, może to oznaczać błąd 'Welcome Fred...' is undefined, a jeśli nie, to może być 'Please Login ...' is undefined. Coś w tym stylu.

Jeśli evilsite.com robi to dla około 20 najlepszych instytucji bankowych, mieliby całkiem niezłe pojęcie o tym, które witryny bankowe odwiedzasz, i mogłyby zapewnić znacznie bardziej ukierunkowaną stronę phishingową. (To oczywiście tylko jeden przykład. Ale ilustruje, dlaczego przeglądarki nie powinny zezwalać żadnym danym na przekraczanie granic domen.)

Przetestowałem to w najnowszych wersjach Safari, Chrome i Firefox - wszystkie to robią. IE9 nie - traktuje wyjątki pochodzenia x tak samo jak wyjątki tego samego pochodzenia. (A Opera nie obsługuje onerror.)

Z ust koni: źródło WebKit, które sprawdza pochodzenie , przekazując wyjątki do onerror (). I źródło Firefox, które sprawdza .

AKTUALIZACJA (21.10.11) : Błąd Firefoksa, który śledzi ten problem, zawiera link do postu na blogu, który zainspirował to zachowanie.

AKTUALIZACJA (12/2/14) : Możesz teraz włączyć pełne raportowanie błędów między domenami w niektórych przeglądarkach, określając crossoriginatrybut znaczników skryptu i wysyłając przez serwer odpowiednie nagłówki odpowiedzi CORS HTTP.

Broofa
źródło
3
Dzięki za to. Chciałbym trochę wyjaśnienia. Widzę szczegółowe komunikaty o błędach ze skryptów, które cały czas umieszczam na swojej stronie. Na przykład, jeśli dołączę jQuery z cdn google i używam go do manipulowania nieistniejącym elementem na mojej stronie, otrzymuję onerror wskazujący na CDN google. Mówisz „Błąd skryptu”. dzieje się, ponieważ zdalny skrypt zgłasza wyjątek?
Mike Sherov
150
Można by pomyśleć, że ktoś miałby sens powiedzieć: „Skrypt zdalny zgłosił błąd, który został ukryty z powodu polityki tego samego pochodzenia”, zamiast pozostawiać zastanawianie się, co poszło nie tak, prawda?
Roman Starkov
3
@broofa Czy to oznacza, że ​​stanę się lepszy, jeśli hostuję jquery w mojej domenie zamiast CDN Google?
Paul Biggar,
6
Mała aktualizacja. Dzieje się tak również lokalnie, gdy strona jest ładowana przez file: //, a skrypt jest uruchamiany przez eval (). Drobny przypadek użycia, ale nadal :)
Willem Mulder
6
Po pewnym dochodzeniu zauważyłem, że Script Error.zdarza się również wtedy, gdy użytkownik zainstalował rozszerzenie Safari (prawdopodobnie takie samo dla wtyczek Firefox), które wstrzykuje kod JavaScript z błędami
Alex Hoppen
49

Aktualizacja dla tych, którzy napotkają to pytanie w przyszłości: Broofa ma rację z odpowiedzią i nie ma na to obejścia.

Oczywiście inne natknęły się na to ograniczenie i niektóre błędy wymagające poprawki zostały zgłoszone do przeglądarki Firefox: Bug 69301 i WebKit: Bug 70574

Dobrą wiadomością jest to, że błąd został rozwiązany w Firefoksie wraz z wydaniem Firefoksa 13. Oto jak go wykorzystujesz:

<script src="http://somremotesite.example/script.js" crossorigin>

crossoriginjest równoważne crossorigin=anonymousi nakazuje przeglądarce wykonanie skryptu przez CORS bez wysyłania poświadczeń.

Musisz upewnić się, że skrypt jest wysyłany z Access-Control-Allow-Originwartością nagłówka HTTP pasującą do domeny żądającej, np.

Access-Control-Allow-Origin: http://myhomesite.example
Access-Control-Allow-Origin: *

w przeciwnym razie przeglądarka anuluje ładowanie skryptu .

W przypadku Apache:

Header set Access-Control-Allow-Origin "*"

(I zobacz przykłady CORS dla innych serwerów sieciowych ).

Jeśli wysyłasz skrypty w PHP:

header('Access-Control-Allow-Origin', 'http://myhomesite.example');

Przetestowałem to i działa zgodnie z oczekiwaniami. wszystkie błędy z script.js zostaną przechwycone przezwindow.onerror moduł obsługi ze szczegółami komunikatu, pliku i wiersza.

Błąd WebKit nie został jeszcze naprawiony, ale zaproponowano łatkę (i używa tego samego rozwiązania). Mamy nadzieję, że poprawka zostanie wkrótce wydana.

Więcej informacji o CORS tutaj: http://enable-cors.org/

adig
źródło
2
Dobre podsumowanie: blog.errorception.com/2012/12/…
Sam
1
Re webkit. Jeśli masz na myśli ten, wygląda na to, że został rozwiązany teraz: bugs.webkit.org/show_bug.cgi?id=70574
UpTheCreek
3
Powiedzmy, że chcemy monitorować błędy JS w mysite.com/index.php, w tym plik JS od strony zewnętrznej (np. Serwer dostawcy API apiprovider.com/api.js); w tym przypadku nie mamy dostępu do tego serwera, więc nie możemy dodać nagłówka „Access-Control-Allow-Origin”. Czy jest jakiś sposób na uzyskanie komunikatów o błędach pochodzących z api.js?
Eugenio
23

To zajęło sporo czasu.

Zrobiliśmy wiele rzeczy, aby spróbować to rozwiązać, w tym takie rzeczy, jak zrzut Całą dokumentację z powrotem na nasze serwery za pośrednictwem Ajax, aby spróbować ją rozwiązać.

Nadal nie jestem pewien, co powoduje „Błąd skryptu”. (z okresem BTW, tak to pokazuje się w naszym rejestratorze Ajax) w Firefox, ale w Chrome mogliśmy zawęzić go do ...

Werble...

Funkcja automatycznego tłumaczenia w Google Chrome.

Wiele osób mówiących po angielsku prawdopodobnie nawet nie wie o tej funkcji, ale aby ją przetestować, myślę, że odwiedzam witrynę w języku innym niż angielski za pomocą Chrome. Lub jeszcze lepiej, jeśli przejrzysz opcje Chrome, możesz zmienić język przeglądarki. Zmień to na coś innego niż angielski, uruchom ponownie przeglądarkę i odwiedź witrynę w języku angielskim.

Na górze powinien pojawić się pasek z pytaniem, czy chcesz, aby Chrome przetłumaczył stronę za Ciebie.

W naszym przypadku i tak przyczyną problemu był tłumacz, który wstrzykuje znacznik skryptu do treści dokumentu i (zgadując tutaj) używa jakiegoś systemu opartego na JS do wysyłania treści na serwery Google i zmuszania ich do przetłumaczenia.

Mimo że błąd w konsoli był niepowiązany, komunikat wysyłany do window.onerror brzmiał „Błąd skryptu”.

W każdym razie istnieje lekarstwo.

http://googlewebmastercentral.blogspot.com/2007/12/answering-more-popular-picks-meta-tags.html

<meta name="google" content="notranslate"/>

To zrobi 2 rzeczy (o ile wiemy, może więcej?):

a) Wyłącz pasek tłumaczeń, aby pojawiał się w Chrome.

b) Wyłącz tłumaczenie strony za pośrednictwem translate.google.com.

W naszej sytuacji rozwiązało to TONĘ tych „błędów skryptu”. problemy, które mieliśmy.

Przepraszam za błędy ortograficzne w tym poście, wciąż piszę w Chrome w trybie innym niż angielski, a moduł sprawdzania pisowni nie jest ustawiony na angielski;) Czas na powrót.

Cieszyć się!

anonimowy-jeden
źródło
4
Bezpośrednim powodem jest prawdopodobnie to, że skrypt tłumaczący został uruchomiony z innej domeny niż strona internetowa i onerror(przynajmniej w Firefox) po prostu mówi „błąd skryptu” w takim przypadku.
Tgr
10

Ze względu na niski% możesz założyć, że nie są zwykłymi użytkownikami. Prawdopodobnie użytkownicy mają skrypty użytkownika, skryptozakładki, a nawet po prostu majstrują przy konsoli w Twojej witrynie. Posiadanie całego kodu HTML strony, na której to się dzieje, może pomóc w testowaniu tej teorii. Jak również całkowity błąd. Powinien dać ci adres URL, czy zawsze jest taki sam? Czy linia jest naprawdę 0 czy tylko niezdefiniowana?

Nie sądzę, aby ustawienie wartości domyślnych w tobie było dobrym pomysłem, a 0 prawdopodobnie pochodzi z parseInt(ln || 0)sytuacji, gdy błędu tak naprawdę nie ma na stronie (patrz przykłady powyżej).

Dodanie if, aby sprawdzić, czy wiersz jest znany w JavaScript, aby zignorować te błędy (ponieważ prawdopodobnie nie pochodzą one z twojego kodu) lub w kodzie po stronie serwera, aby zająć się nimi osobno, byłoby, imo, lepiej .

=== EDYCJA === Muszę: http://www.xavierm02.net/AZE/ Zainstalować plik user.js (Zrobiłem to w Chrome, ale powinien również działać w Firefoksie). Następnie otwórz stronę HTML w tej samej przeglądarce. Pokaże ci błąd (zmieniłem tylko tę instancję raportowania do serwera, zapisuje to na stronie). Z 0 jako numer linii.

xavierm02
źródło
Adres URL jest równomiernie rozprowadzany między stronami mojej witryny. Domyślam się też bookmarklety, a nawet rozszerzenia lub motywy, biorąc pod uwagę, że to FF i chrome. Chciałbym jednak móc dokładnie wypisać ten komunikat o błędzie, zanim bezpiecznie go zignoruję.
Mike Sherov
Zamień swój wiersz na, (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url) + "&ln=" + parseInt(ln) + "&r=" + (+new Date());a prawdopodobnie nie zobaczysz adresu URL (ponieważ jest to rozszerzenie lub coś lokalnego, więc przeglądarka Cię nie wyświetla) i numeru linii.
xavierm02
A tak przy okazji, powinieneś raczej uzyskać znacznik czasu na swoim serwerze niż na JS (a może nawet po prostu pobrać wersję zamiast znacznika czasu).
xavierm02
1
W rzeczywistości JS powinien po prostu wysłać surowe dane, a PHP powinien zignorować błędy ładowania i tak dalej.
xavierm02
Robię trochę przetwarzania po stronie JS, ponieważ chcę tylko zgłosić PIERWSZY istotny błąd, więc po pojawieniu się prawdziwego błędu ponownie przypisuję funkcję onerror do zera. Zapobiega to również błędom występującym w pętlach, powodując ddos'owanie mojego serwera .
Mike Sherov
3

Miałem podobny problem: moje skrypty są obsługiwane przez subdomenę i podlegają temu samemu ograniczeniu pochodzenia. Rozwiązałem to jednak poprzez:

1) dodając każdy tag skryptu w ten sposób:

<script type="text/javascript" src="http://subdomain.mydomain.tld" crossorigin="*.mydomain.tld" />

2) modyfikowanie httpd.conf apache przez dodanie następujących elementów w każdym vhostie (musisz włączyć mod_headers):

<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*.mydomain.tld"
</IfModule>

Mam nadzieję że to pomoże ...

EDYTOWAĆ

Na jednym z moich serwerów nie byłem w stanie uczynić tego funkcjonalnym inaczej niż przez wymianę

*.mydomain.tld

przez

*

Bądź świadomy wad, które potencjalnie pozwalają * na wyłudzanie informacji rozszerzonych. Dokumentacja na temat CORS, tego samego pochodzenia, img i czcionek, cdn jest dostępna, ale jest bardzo mało na temat szczegółów crossorigin tagów skryptowych.

spoutnik
źródło
1
„* .mydomain.tld” nie jest prawidłową wartością dla atrybutu crossorigin developer.mozilla.org/en-US/docs/Web/HTML/…
icenac
1

W Chrome pojawia się również „Błąd skryptu” (w wierszu 0) podczas ładowania zarówno HTML, jak i Javascript file://. Nie dzieje się tak w przeglądarce Firefox. Prawdopodobnie nadgorliwa ochrona tego samego pochodzenia Chrome.

Wszystko jest dobrze, gdy ładujesz ten sam HTML i JavaScript przez HTTP.

Myrne Stol
źródło
1

Co powiesz na to poniżej? Błąd skryptu nie jest dostępny przez JavaScript, więc po prostu wyizoluj tę konkretną sprawę i postępuj z nią jak najlepiej.

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        alert(msg, url, lineNo, columnNo, error);
    }
  return false;
};
Ronnie Royston
źródło
jak logujesz to na karmie?
CommonSenseCode
Czy mówisz, że konsola przeglądarki ma szczegóły, ale onerror nie?
Michael Freidgeim
0

Zarówno Chrome, jak i Firefox na iOS są oparte na przeglądarce Safari Webview, ale wstaw kilka niestandardowych skryptów do każdej ładowanej strony. Jeśli w którymkolwiek z tych skryptów coś pójdzie nie tak, zostanie również zgłoszone s Script error on line 0. (Skrypty wstawione do przeglądarki są również liczone jako cross origin)

Jak już wyśledziłem i udokumentowałem w tym innym wątku SO, zarówno Chrome, jak i Firefox na iOS mają problemy ze swoimi niestandardowymi skryptami poprawnie obsługującymi elementy SVG. Oprócz wszystkich innych odpowiedzi w tym wątku: jeśli używasz elementów SVG i <a>tagów wewnątrz <svg>tagów na swojej stronie, spowoduje Script errorsto zgłoszenie w iOS Chrome i iOS Firefox.

Laszlo Korte
źródło
-1

Powiem ci, co to naprawiło dla mnie w Safari (WebKit): Jeśli umieszczę procedurę wywołania zwrotnego JS na stronie , to otrzymam pełne informacje. Jeśli dołączę go do pliku .js za pomocą tagu, po prostu pojawia się błąd „Błąd skryptu” (bez numeru bielizny itp.).

Może ma to związek z tym, co powiedział Broofa.

Anwyay, więc teraz mam małe oddzwanianie na stronie, a następnie resztę pliku poza stroną.

kbern
źródło
-2

Przeprowadziłem trochę wyszukiwania i wygląda na to, że „Błąd skryptu” oznacza, że ​​miał problem z załadowaniem pliku, o którego wyszukanie został poproszony. Może to być problem z buforowaniem po stronie klienta lub może to być problem z serwerem z powodu przeciążenia.

Najprawdopodobniej jest to spowodowane tym, że sam skrypt jest plikiem, którego nie można załadować, stąd błąd występujący w linii 0.

<script type="text/javascript" src="somescript.js"></script>
Nick Brunt
źródło
Dobra myśl, ale wyraźnie ignorujemy, gdy skrypt nie ładuje się. Wykryliśmy ten błąd i zignorowaliśmy go.
Mike Sherov
1
Jak wykryłeś, że skrypt się nie ładuje? W pewnym momencie pamiętam, że miałem z tym problem. script.onerrornie został zwolniony z powodu brakujących skryptów w niektórych przeglądarkach.
Charlie Kilian
„Błąd źródła”. (little-e) pojawia się zarówno w źródłach webkita, jak i FF. Zobacz moją odpowiedź powyżej. fwiw.
broofa
-3

Doświadczyłem

Błąd skryptu. wiersz 0

błędy przez pewien czas są zgłaszane z powrotem do naszego serwera, gdy wystąpił błąd w przeglądarkach klientów. Wczoraj po raz pierwszy (po wprowadzeniu "use strict";w naszym javascript) mogłem replikować ten problem w Safari i Chrome na Windows 7. Po zaśmieceniu naszego kodu instrukcjami alert () prześledziłem ten błąd aż do użycia niezdefiniowanej zmiennej! np. xx = 123;gdzie xx nie jest zdefiniowane za pomocą varinstrukcji.

Safari zgłosiło to jako

ReferenceError: Tryb ścisły zabrania niejawnego tworzenia właściwości globalnej „xx”

w programie Web Inspector, ale wykrywała funkcję window.onerror

Błąd skryptu. wiersz 0

Wandering Zombie
źródło
-11

Grepping kodu źródłowego Firefoksa ujawnia, że ​​nie ma "Script Error.". Dlatego bardzo prawdopodobne jest, że jakiś skrypt w Twojej witrynie zgłasza taki błąd:

throw new Error('Script Error.');

Prawdopodobnie to stwierdzenie jest dostępne tylko w Firefox i Chrome.

Nie jestem pewien, dlaczego nie ma numeru linii. Może jakiś eval()problem?

użytkownik123444555621
źródło
1
Próbowałem rzucić to dokładnie tak, jak zaleciłeś. Nie zgłasza „Błąd skryptu”. Zgłasza „Zgłoszono wyjątek wyjątku: Błąd skryptu”. Dobra myśl.
Mike Sherov
Może to być również jedno z rozszerzeń zainstalowanych przez użytkownika, który powoduje błąd.
Charlie Kilian
1
Nie ma mowy. „Błąd skryptu” zobaczysz w Internecie, jeśli spojrzysz na właściwe pola.
Amalgovinus
2
O nie. To właściwie „błąd skryptu”. z małym „e”. Dlatego nie znalazłem go w kodzie źródłowym.
user123444555621,