Estou adicionando <script>
tags dinamicamente a uma página <head>
e gostaria de poder dizer se o carregamento falhou de alguma forma - um 404, um erro de script no script carregado, qualquer coisa.
No Firefox, isso funciona:
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);
No entanto, isso não funciona no IE ou Safari.
Alguém conhece uma maneira de fazer isso funcionar em outros navegadores além do Firefox?
(Não acho que uma solução que exija a colocação de um código especial nos arquivos .js seja boa. É deselegante e inflexível.)
javascript
onerror
script-tag
David
fonte
fonte
if
+ polling é algo irritante que não quero colocar em todo o JS.Respostas:
Não há evento de erro para a tag do script. Você pode dizer quando foi bem-sucedido e supor que não foi carregado após um tempo limite:
fonte
Se você se preocupa apenas com os navegadores html5, pode usar o evento de erro (uma vez que é apenas para tratamento de erros, deve estar tudo bem em apenas suportar isso nos navegadores de próxima geração para KISS IMHO).
Da especificação:
~
Isso significa que você não precisa fazer nenhuma pesquisa sujeita a erros e pode combiná-la com o atributo async e defer para garantir que o script não esteja bloqueando a renderização da página:
Mais em http://www.w3.org/TR/html5/scripting-1.html#script
fonte
<script src="nonexistent.js" onerror="alert('error!')"></script>
violinoUncaught SyntaxError: Unexpected token '<'
(no Chrome mais recente)<script src="nonexistent.js" onerror="alert('error!')"></script>
deve ir em seu arquivo HTML, não JS.O script de Erwinus funciona muito bem, mas não está codificado de forma clara. Tomei a liberdade de limpar e decifrar o que estava acontecendo. Fiz estas mudanças:
prototype
.require()
usa uma variável de argumentoalert()
mensagem é retornada por padrãoGraças novamente a Erwinus, a funcionalidade em si está no local.
fonte
minha solução de trabalho limpa (2017)
Como Martin apontou, usado assim:
OU
fonte
loaderScript("myscript.js").then(() => { console.log("loaded"); }).catch(() => { console.log("error"); });
Eu sei que este é um tópico antigo, mas eu tenho uma boa solução para você (eu acho). É copiado de uma classe minha, que lida com todas as coisas AJAX.
Quando o script não pode ser carregado, ele define um manipulador de erros, mas quando o manipulador de erros não é suportado, ele recorre a um cronômetro que verifica se há erros por 15 segundos.
fonte
Para verificar se o javascript
nonexistant.js
não retornou nenhum erro você deve adicionar uma variável dentro dohttp://fail.org/nonexistant.js
likevar isExecuted = true;
e então verificar se ela existe quando a tag do script é carregada.No entanto, se você deseja apenas verificar se o
nonexistant.js
retornou sem um 404 (o que significa que existe), você pode tentar com umaisLoaded
variável ...Isso cobrirá os dois casos.
fonte
Espero que isso não seja rejeitado, porque em circunstâncias especiais é a forma mais confiável de resolver o problema. Sempre que o servidor permitir que você obtenha um recurso Javascript usando CORS ( http://en.wikipedia.org/wiki/Cross-origin_resource_sharing ), você tem uma ampla gama de opções para fazer isso.
Usar XMLHttpRequest para buscar recursos funcionará em todos os navegadores modernos, incluindo o IE. Já que você está procurando carregar o Javascript, você tem o Javascript disponível para você em primeiro lugar. Você pode acompanhar o progresso usando o readyState ( http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener ). Finalmente, depois de receber o conteúdo do arquivo, você pode executá-lo com eval (). Sim, eu disse eval - porque em termos de segurança não é diferente de carregar o script normalmente. Na verdade, uma técnica semelhante é sugerida por John Resig para ter tags mais agradáveis ( http://ejohn.org/blog/degrading-script-tags/ ).
Este método também permite separar o carregamento do eval e executar funções antes e depois de o eval acontecer. Torna-se muito útil ao carregar scripts em paralelo, mas avaliando-os um após o outro - algo que os navegadores podem fazer facilmente quando você coloca as tags em HTML, mas não permitem adicionar scripts em tempo de execução com Javascript.
CORS também é preferível a JSONP para carregar scripts ( http://en.wikipedia.org/wiki/XMLHttpRequest#Cross-domain_requests ). No entanto, se você estiver desenvolvendo seus próprios widgets de terceiros para serem incorporados em outros sites, você deve realmente carregar os arquivos Javascript de seu próprio domínio em seu próprio iframe (novamente, usando AJAX)
Em resumo:
Tente ver se você pode carregar o recurso usando AJAX GET
Use eval após carregar com sucesso
Para melhorar:
Verifique os cabeçalhos de controle de cache que estão sendo enviados
Procure, de outra forma, armazenar em cache o conteúdo em localStorage, se precisar
Verifique o "degrading javascript" de Resig para obter um código mais limpo
Confira require.js
fonte
Esse truque funcionou para mim, embora eu admita que essa provavelmente não seja a melhor maneira de resolver o problema. Em vez de tentar isso, você deve ver porque os javascripts não estão carregando. Tente manter uma cópia local do script em seu servidor, etc. ou verifique com o fornecedor terceirizado de onde você está tentando fazer o download do script.
De qualquer forma, esta é a solução alternativa: 1) Inicialize uma variável como falsa 2) Defina como verdadeira quando o javascript carregar (usando o atributo onload) 3) verifique se a variável é verdadeira ou falsa quando o corpo do HTML for carregado
fonte
Aqui está outra solução baseada em JQuery sem nenhum temporizador:
Agradecimentos a: https://stackoverflow.com/a/14691735/1243926
Amostra de uso (amostra original da documentação JQuery getScript ):
fonte
cache:true
adotei essa abordagem, mas recomendo usar para a chamada $ .getScript (desativada por padrão). Desta forma, para a maioria das solicitações, ele usa automaticamente a versão em cache para a chamada getScript (economizando latência)Isso pode ser feito com segurança usando promessas
e usar assim
fonte
O motivo pelo qual não funciona no Safari é porque você está usando a sintaxe de atributos. Isso vai funcionar bem:
... exceto no IE.
Se você quiser verificar se o script foi executado com sucesso, apenas defina uma variável usando esse script e verifique se ela está definida no código externo.
fonte
<script>
. Se você tentar adicioná-lo antes, receberá um erro informando que a tag não existe e, se adicioná-lo depois, o script já foi executado e acionou seus eventos. A única maneira é procurar os efeitos colaterais causados pelo script.evento onerror
* Atualização de agosto de 2017: onerror é acionado pelo Chrome e Firefox. onload é acionado pelo Internet Explorer. Edge não dispara onerror nem onload. Eu não usaria esse método, mas pode funcionar em alguns casos. Veja também
<link> onerror não funciona no IE
*
Definição e uso O evento onerror é acionado se ocorrer um erro ao carregar um arquivo externo (por exemplo, um documento ou uma imagem).
Dica: Quando usado em mídia de áudio / vídeo, os eventos relacionados que ocorrem quando há algum tipo de perturbação no processo de carregamento de mídia são:
Em HTML:
elemento onerror = "myScript">
Em JavaScript , usando o método addEventListener ():
object.addEventListener ("erro", myScript);
Observação: o método addEventListener () não é compatível com o Internet Explorer 8 e versões anteriores.
Exemplo: Execute um JavaScript se ocorrer um erro ao carregar uma imagem:
img src = "image.gif" onerror = "myFunction ()">
fonte
Foi proposto definir um tempo limite e, em seguida, assumir a falha de carga após um tempo limite.
O problema com essa abordagem é que a suposição se baseia no acaso. Depois que o tempo limite expirar, a solicitação ainda estará pendente. A solicitação do script pendente pode carregar, mesmo depois que o programador presumiu que o carregamento não acontecerá.
Se a solicitação pudesse ser cancelada, o programa poderia aguardar um período e, em seguida, cancelar a solicitação.
fonte
Foi assim que usei uma promessa para detectar erros de carregamento que são emitidos no objeto janela:
fonte
Bem, a única maneira que consigo pensar em fazer tudo o que você quer é muito feia. Primeiro execute uma chamada AJAX para recuperar o conteúdo do arquivo Javascript. Quando isso for concluído, você pode verificar o código de status para decidir se foi bem-sucedido ou não. Em seguida, pegue o responseText do objeto xhr e envolva-o em um try / catch, crie dinamicamente uma tag de script e para o IE você pode definir a propriedade text da tag de script para o texto JS, em todos os outros navegadores você deve ser capaz de acrescente um nó de texto com o conteúdo da tag de script. Se houver algum código que espera que uma tag de script realmente contenha a localização src do arquivo, isso não funcionará, mas deve funcionar na maioria das situações.
fonte