Críptico "Erro de script". relatado em Javascript no Chrome e Firefox

199

Eu tenho um script que detecta erros de Javascript no meu site e os envia ao meu back-end para geração de relatórios. Ele relata o primeiro erro encontrado, o número da linha suposta e a hora.

EDIT para incluir 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>

Devido a esse script, estou ciente de quaisquer erros de javascript que estão acontecendo no meu site. Um dos maiores infratores é o "Erro de script". na linha 0. no Chrome 10+ e Firefox 3+. Este erro não existe (ou pode ser chamado de outra coisa?) No Internet Explorer.

Correção (23/05/2013): Este erro "Erro de script, linha 0" está aparecendo no IE7 e possivelmente em outras versões do IE. Possivelmente resultado de um patch de segurança recente do IE, pois esse comportamento não existia anteriormente.

Alguém tem alguma idéia do que esse erro significa ou o que causa? Isso acontece em cerca de 0,25% do meu total de carregamentos de páginas e representa metade dos erros relatados.

Mike Sherov
fonte
Qual é o seu doctype? Se você não está declarando um tipo de documento XHTML, não precisa do CDATA, e pode ser por isso que existem erros de script.
James
Agradeço a ajuda ... Adicionado o doctype: XHTML. Além disso, porém, só acontece em 0,25% dos carregamentos de páginas ... eu acho que é algo mais exótico.
Mike Sherov
3
@ jayp: Apenas mencionando. O doctype XHTML ainda é um analisador de HTML. Você precisa enviar o conteúdo application/xhtml+xmlpara executá-lo no analisador XHTML (como a especificação XHTML diz). Existe um monte de conteúdo que afirma ser XHTML, mas envia um tipo de documento HTML normal. Devido à forma como os criadores de conteúdo incorretamente usam XHTML, os navegadores decidiram usar apenas o analisador XML application/xhtml+xml(é realmente um analisador estrito). O hixie.ch/advocacy/xhtml e webdevout.net/articles/beware-of-xhtml diz por que não usar o analisador de HTML com XHTML.
Konrad Borowski
11
Suspiro ... pelo amor de Deus, quem estiver lendo isso, faça suas mensagens de erro explicarem exatamente o que deu errado! Ao economizar 30 segundos de esforço para escrevê-lo, você está desperdiçando o mundo em homens-ano!
Roman Starkov
1
Você está ignorando Erro ao carregar erros de script. Por quê? Eles são seguros para ignorar?
rampr

Respostas:

261

O "erro de script". acontece no Firefox, Safari e Chrome quando uma exceção viola a política de mesma origem do navegador - ou seja, quando o erro ocorre em um script hospedado em um domínio que não seja o domínio da página atual.

Esse comportamento é intencional, para impedir que scripts vazem informações para domínios externos. Para um exemplo de por que isso é necessário, imagine uma visita acidental evilsite.com, que serve uma página com <script src="yourbank.com/index.html">. (sim, apontamos essa tag de script para html, não para JS). Isso resultará em um erro de script, mas o erro é interessante porque pode nos dizer se você está logado ou não. Se você estiver logado, o erro pode ser 'Welcome Fred...' is undefined, enquanto se não estiver, pode ser 'Please Login ...' is undefined. Algo nesse sentido.

Se evilsite.com fizer isso para as 20 principais instituições bancárias, elas terão uma boa idéia de quais sites bancários você visitar e poderão fornecer uma página de phishing muito mais direcionada. (Este é apenas um exemplo, é claro. Mas ilustra por que os navegadores não devem permitir que nenhum dado ultrapasse os limites do domínio.)

Eu testei isso nas últimas versões do Safari, Chrome e Firefox - todos eles fazem isso. O IE9 não - trata as exceções de origem x da mesma forma que as exceções de mesma origem. (E o Opera não suporta onerror.)

Da boca do cavalo: fonte do WebKit que verifica a origem ao passar exceções para onerror (). E a fonte do Firefox que verifica .

ATUALIZAÇÃO (21/10/11) : o bug do Firefox que acompanha esse problema inclui um link para a postagem do blog que inspirou esse comportamento.

ATUALIZAÇÃO (02/12/14) : agora você pode ativar o relatório completo de erros entre domínios em alguns navegadores, especificando um crossoriginatributo nas tags de script e solicitando que o servidor envie os cabeçalhos de resposta HTTP CORS apropriados .

broofa
fonte
3
Obrigado por isso. Eu gostaria de um pouco de esclarecimento. Vejo mensagens de erro detalhadas de scripts que incluo na minha página o tempo todo. Por exemplo, se eu incluir o jQuery no CDN do Google e usá-lo para manipular um elemento inexistente na minha página, recebo um erro que aponta para a CDN do Google. Você está dizendo que "Erro de script". está acontecendo porque o script remoto está lançando a exceção?
Mike Sherov 29/10
150
Você pensaria que alguém teria o bom senso de dizer "Um script remoto gerou um erro oculto devido à política de mesma origem", em vez de deixar você se perguntando o que deu errado, hein? ...
Roman Starkov
3
@broofa Isso significa que vou melhorar, exceto se eu hospedar o jquery no meu domínio, em vez de usar a CDN do Google?
precisa
6
Pequena atualização. Isso também acontece localmente quando uma página é carregada via file: // e o script é executado através de eval (). Caso de uso menor, mas ainda :)
Willem Mulder
6
Após alguma investigação, notei que isso Script Error.também ocorre se o usuário instalou uma extensão do Safari (provavelmente a mesma para os plug-ins do Firefox) que injeta código JavaScript com erros
Alex Hoppen
49

Uma atualização para aqueles que encontrarão essa pergunta no futuro: broofa está certa com a resposta e não há solução alternativa para isso.

Obviamente, outros tropeçaram nessa limitação e alguns bugs solicitando uma correção foram arquivados para Firefox: Bug 69301 e WebKit: Bug 70574

A boa notícia é que o bug foi resolvido no Firefox com o lançamento do Firefox 13. É assim que você o usa:

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

crossoriginé equivalente a crossorigin=anonymouse diz ao navegador para fazer uma busca CORS do script sem enviar credenciais.

Você deve garantir que o script seja enviado com um Access-Control-Allow-Originvalor de cabeçalho HTTP que corresponda ao domínio solicitante, por exemplo,

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

caso contrário, o navegador cancelará o carregamento do script .

Para o Apache:

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

(E veja exemplos do CORS para outros servidores da web .)

Se você estiver enviando scripts em PHP:

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

Eu testei isso e funciona como esperado. todos os erros do script.js serão capturados pelowindow.onerror manipulador com detalhes de mensagem, arquivo e linha.

O bug do WebKit ainda não foi corrigido, mas um patch foi proposto (e usa a mesma solução). Esperamos que a correção seja lançada em breve.

Mais informações sobre o CORS aqui: http://enable-cors.org/

adig
fonte
1
Re webkit. Se você quer dizer este, parece que está resolvido agora: bugs.webkit.org/show_bug.cgi?id=70574
UpTheCreek
3
Digamos que queremos monitorar erros de JS em mysite.com/index.php, que inclui um arquivo JS de uma parte externa (por exemplo, o servidor de um provedor de API apiprovider.com/api.js); nesse caso, não temos acesso a esse servidor, portanto não podemos adicionar o cabeçalho "Access-Control-Allow-Origin". Existe alguma maneira de obter mensagens de erro originadas do api.js?
Eugenio
23

Este demorou um pouco para descobrir.

Fizemos várias coisas para tentar resolvê-lo, incluindo fazer o envio de todo o corpo do documento de volta aos nossos servidores via Ajax para tentar descobrir.

Ainda não tenho certeza do que causa "Erro de script". (com o período BTW, é assim que aparece no nosso registrador Ajax) no Firefox, mas no Chrome, conseguimos reduzi-lo a ...

Rolo de tambor ...

O recurso de conversão automática do Google Chrome.

Muitas pessoas que falam inglês provavelmente nem conhecem esse recurso, mas para testá-lo, acho que visitam um site que não seja o inglês usando o Chrome. Ou melhor ainda, se você pesquisar nas opções do Chrome, há um local para alterar o idioma do navegador. Altere para algo que não seja o inglês, reinicie o navegador e visite um site em inglês.

Você deve obter a barra na parte superior perguntando se deseja que o Chrome traduza a página para você.

De qualquer forma, o tradutor estava causando o problema, pois injeta uma tag de script no corpo do documento e (adivinha aqui) usa algum tipo de sistema baseado em JS para enviar o conteúdo aos servidores do Google e fazer com que eles o traduzam.

Mesmo que o erro no console fosse algo não referenciado, a mensagem que estava sendo enviada para window.onerror era "Erro de script".

De qualquer forma, existe uma cura.

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

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

Isso fará duas coisas (até onde sabemos, talvez mais?):

a) Desative a barra de conversão de aparecer no Chrome.

b) Desative a tradução da página em translate.google.com.

De qualquer maneira, em nossa situação, isso resolveu MUITAS "Erros de script". problemas que estávamos enfrentando.

Desculpe os erros ortográficos nesta postagem. Ainda estou no modo não inglês no Chrome, e o verificador ortográfico não está definido como inglês;) Hora de voltar.

Aproveitar!

anônimo-um
fonte
4
A razão direta é provavelmente que o script do tradutor foi executado em um domínio diferente da página da web e onerror(pelo menos no Firefox) apenas diz "Erro de script" nesse caso.
Tgr 11/10
10

Devido ao baixo%, você pode assumir que eles não são usuários normais. Provavelmente usuários com scripts de usuários, bookmarklets ou até mesmo brincando com o console no site. Ter todo o HTML de uma página onde isso acontece pode ajudar a testar essa teoria. Bem como o erro completo. Deve fornecer um URL, é sempre o mesmo? A linha é realmente 0 ou apenas indefinida?

Eu não acho que definir valores padrão em você no erro seja uma boa idéia e o 0 provavelmente vem parseInt(ln || 0)quando o erro não está realmente na página (veja os exemplos acima).

Adicionar um if para ver se a linha é conhecida no JavaScript por ignorar esses erros (porque provavelmente não provém do seu próprio código) ou no código do servidor para cuidar deles separadamente seria melhor .

=== EDIT === Chegou a: http://www.xavierm02.net/AZE/ Instale o arquivo user.js (eu fiz no Chrome, mas também deve funcionar no Firefox). Em seguida, abra a página html no mesmo navegador. Ele mostrará o erro (apenas mudei esse instinto de relatar ao servidor, ele o grava na página). Com 0 como número da linha.

xavierm02
fonte
O URL é distribuído igualmente entre as páginas do meu site. Suponho que bookmarklets ou mesmo extensões ou temas também, considerando FF e Chrome. No entanto, eu adoraria poder reproduzir esta mensagem de erro exatamente antes de ignorá-la com segurança.
Mike Sherov
Substitua sua linha por (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url) + "&ln=" + parseInt(ln) + "&r=" + (+new Date());e você provavelmente não verá nenhum URL (porque é uma extensão ou algo local para que o navegador não mostre) e nenhum número de linha.
Xavierm02 11/11/11
E, por outro lado, você deve obter o carimbo de data e hora com o servidor, e não com o JS (e talvez apenas a versão, em vez do carimbo de data e hora).
Xavierm02 11/11
1
De fato, o JS deve apenas enviar os dados brutos e o PHP deve ignorar os erros de carregamento e assim por diante.
Xavierm02 11/11
Eu faço algum processamento no lado JS porque eu quero apenas relatar o PRIMEIRO erro relevante, portanto, reatribuio a função onerror de volta a nada após a entrada de um erro real. Isso também impede que erros que estão acontecendo em loops causem ddos ​​no servidor. .
Mike Sherov
3

Eu tive um problema semelhante: meus scripts são servidos por um subdomínio e se enquadram na mesma restrição de origem. No entanto, resolvi isso da seguinte maneira:

1) adicionando todas as tags de script assim:

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

2) modificando o apache httpd.conf adicionando o seguinte dentro de cada vhost (você deve ativar mod_headers):

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

Espero que isto ajude ...

EDITAR

Em um dos meus servidores, não pude tornar isso funcional, exceto substituindo

*.mydomain.tld

de

*

Esteja ciente das falhas ao permitir * phishing informações estendidas. Documentação sobre CORS, mesma origem, img e fontes, cdn está disponível, mas muito menos sobre detalhes sobre a origem de tags de script está disponível.

spoutnik
fonte
1
"* .mydomain.tld" não é um valor válido para o atributo crossorigin developer.mozilla.org/en-US/docs/Web/HTML/…
icenac
1

No Chrome, também recebo "Erro de script" (na linha 0) ao carregar o HTML e o Javascript file://. Isso não acontece no Firefox. Provavelmente proteção excessivamente zelosa do Chrome da mesma origem.

Tudo é bom ao carregar o mesmo HTML e Javascript sobre HTTP.

Myrne Stol
fonte
1

Que tal o abaixo. O erro de script não está disponível via JavaScript; basta isolar esse caso específico e lidar com ele da melhor maneira possível.

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
fonte
como você registra isso no carma?
CommonSenseCode
Você está dizendo que o console do navegador tem os detalhes, mas o onerror não?
Michael Freidgeim 7/11
0

O Chrome e o Firefox no iOS são baseados no Safari Webview, mas insere vários scripts personalizados em cada página carregada. Se em algum desses scripts algo der errado, será relatado queScript error on line 0 . (Os scripts inseridos pelo navegador também contam como origem cruzada)

Como eu rastreei e documentei nesse outro segmento SO, o Chrome e o Firefox no iOS têm problemas em seus scripts personalizados que manipulam os elementos SVG corretamente. Portanto, além de todas as outras respostas neste tópico: Se você usar elementos e <a>tags SVG dentro de <svg>tags na sua página, isso será Script errorsreportado no iOS Chrome e no iOS Firefox.

Laszlo Korte
fonte
-1

Vou lhe dizer o que foi corrigido para mim no Safari (WebKit): se eu colocar a rotina de retorno de chamada JS realmente na página , receberei informações completas. Se eu incluí-lo em um arquivo .js por meio de uma tag, recebo o erro "Erro de script" (sem número de roupa etc.).

Talvez isso esteja relacionado ao que Broofa disse.

De qualquer forma, agora tenho um pequeno retorno de chamada na página e o restante do arquivo fora da página.

kbern
fonte
-2

Pesquisei um pouco e parece que um "Erro de script" significa que houve problemas ao carregar um arquivo que foi solicitado a procurar. Isso pode ser um problema de armazenamento em cache no lado do cliente ou pode ser um problema no servidor devido à sobrecarga.

Provavelmente, é causado por algo assim, onde o próprio script é o arquivo que não pode carregar, daí o erro que ocorre na linha 0.

<script type="text/javascript" src="somescript.js"></script>
Nick Brunt
fonte
Bom pensamento, mas ignoramos explicitamente quando um script falha ao carregar. Detectamos esse erro especificamente e o ignoramos.
Mike Sherov
1
Como você detectou quando um script falha ao carregar? Lembro-me de ter problemas com isso em um ponto. script.onerrornão foi demitido por falta de scripts em alguns navegadores.
Charlie Kilian
"Erro na fonte." (little-e) aparece nas fontes webkit e FF. Veja minha resposta acima. fwiw.
broofa
-3

Eu experimentei

Erro de script. linha 0

erros há algum tempo relatados ao nosso servidor quando ocorreu o erro nos navegadores do cliente. Ontem, pela primeira vez (depois de introduzir "use strict";nosso javascript), consegui replicar esse problema no Safari e no Chrome no Windows 7. Depois de colocar nosso código com instruções alert (), localizei esse erro no uso de uma variável indefinida! por exemplo, xx = 123;onde xx não está definido com uma vardeclaração.

O Safari relatou isso como

ReferenceError: O modo estrito proíbe a criação implícita da propriedade global 'xx'

no Web Inspector, mas a função window.onerror estava detectando

Erro de script. linha 0

Zumbi Errante
fonte
-11

Grepping o código fonte do Firefox revela que não existe "Script Error.". Portanto, é muito provável que algum script no seu site esteja lançando um erro não detectado como este:

throw new Error('Script Error.');

Provavelmente, esta afirmação é alcançada apenas no Firefox e Chrome.

Não sei por que não há número de linha. Talvez algum eval()problema?

user123444555621
fonte
1
Eu tentei jogar isso exatamente como você recomendou. Não relata "Erro de script". Ele relata "Exceção lançada não capturada: erro de script.". Bom pensamento embora.
Mike Sherov
Também pode ser uma das extensões instaladas pelo usuário que está causando o erro.
Charlie Kilian
1
De jeito nenhum. Você verá "Erro de script" em toda a Web se procurar as placas corretas.
Amalgovinus
2
Oh não. Na verdade, é "erro de script". com um pequeno "e". Por isso não o encontrei no código fonte.
user123444555621