Estoy agregando <script>
etiquetas dinámicamente a una página <head>
, y me gustaría poder saber si la carga falló de alguna manera: un 404, un error de secuencia de comandos en la secuencia de comandos cargada, lo que sea.
En Firefox, esto 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);
Sin embargo, esto no funciona en IE o Safari.
¿Alguien conoce alguna forma de hacer que esto funcione en navegadores distintos a Firefox?
(No creo que una solución que requiera colocar un código especial dentro de los archivos .js sea buena. Es poco elegante e inflexible).
javascript
onerror
script-tag
David
fuente
fuente
if
+ el sondeo es un problema molesto que no quiero tener que poner en todo JS.Respuestas:
No hay ningún evento de error para la etiqueta de secuencia de comandos. Puede saber cuándo tiene éxito y asumir que no se ha cargado después de un tiempo de espera:
fuente
Si solo le interesan los navegadores html5, puede usar el evento de error (ya que esto es solo para el manejo de errores, debería estar bien admitir esto solo en los navegadores de próxima generación para KISS en mi humilde opinión).
De la especificación:
~
Esto significa que no tiene que realizar ningún sondeo propenso a errores y puede combinarlo con el atributo async y defer para asegurarse de que el script no esté bloqueando la representación de la página:
Más en http://www.w3.org/TR/html5/scripting-1.html#script
fuente
<script src="nonexistent.js" onerror="alert('error!')"></script>
violínUncaught SyntaxError: Unexpected token '<'
(en la última versión de Chrome)<script src="nonexistent.js" onerror="alert('error!')"></script>
debe ir en su archivo HTML, no en JS.El guión de Erwinus funciona muy bien, pero no está codificado con mucha claridad. Me tomé la libertad de limpiarlo y descifrar lo que estaba haciendo. Hice estos cambios:
prototype
.require()
usa una variable de argumentoalert()
se devuelven mensajes de forma predeterminadaGracias de nuevo a Erwinus, la funcionalidad en sí es perfecta.
fuente
mi solución de trabajo limpia (2017)
Como señaló Martin, usado así:
O
fuente
loaderScript("myscript.js").then(() => { console.log("loaded"); }).catch(() => { console.log("error"); });
Sé que este es un hilo antiguo, pero tengo una buena solución para ti (creo). Está copiado de una clase mía, que maneja todas las cosas de AJAX.
Cuando el script no se puede cargar, establece un controlador de errores, pero cuando el controlador de errores no es compatible, recurre a un temporizador que busca errores durante 15 segundos.
fuente
Para verificar si el javascript
nonexistant.js
no devolvió ningún error, debe agregar una variable dentro dehttp://fail.org/nonexistant.js
likevar isExecuted = true;
y luego verificar si existe cuando se carga la etiqueta del script.Sin embargo, si solo desea verificar que se
nonexistant.js
devolvió sin un 404 (lo que significa que existe), puede probar con unaisLoaded
variable ...Esto cubrirá ambos casos.
fuente
Espero que esto no sea rechazado, porque en circunstancias especiales es la forma más confiable de resolver el problema. En cualquier momento que el servidor le permita obtener un recurso de Javascript usando CORS ( http://en.wikipedia.org/wiki/Cross-origin_resource_sharing ), tiene una amplia gama de opciones para hacerlo.
El uso de XMLHttpRequest para recuperar recursos funcionará en todos los navegadores modernos, incluido IE. Ya que está buscando cargar Javascript, tiene Javascript disponible para usted en primer lugar. Puede realizar un seguimiento del progreso mediante readyState ( http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener ). Finalmente, una vez que reciba el contenido del archivo, puede ejecutarlo con eval (). Sí, dije eval, porque en términos de seguridad no es diferente de cargar el script normalmente. De hecho, John Resig sugiere una técnica similar para tener etiquetas más agradables ( http://ejohn.org/blog/degrading-script-tags/ ).
Este método también le permite separar la carga de la evaluación y ejecutar funciones antes y después de que ocurra la evaluación. Se vuelve muy útil cuando se cargan scripts en paralelo, pero se evalúan uno tras otro, algo que los navegadores pueden hacer fácilmente cuando coloca las etiquetas en HTML, pero no le permiten agregar scripts en tiempo de ejecución con Javascript.
CORS también es preferible a JSONP para cargar scripts ( http://en.wikipedia.org/wiki/XMLHttpRequest#Cross-domain_requests ). Sin embargo, si está desarrollando sus propios widgets de terceros para incrustarlos en otros sitios, debería cargar los archivos Javascript de su propio dominio en su propio iframe (nuevamente, usando AJAX)
En breve:
Intente ver si puede cargar el recurso usando AJAX GET
Utilice eval después de que se haya cargado correctamente
Para mejorarlo:
Consulte los encabezados de control de caché que se envían
Busque almacenar en caché el contenido en localStorage, si es necesario
Consulte el "javascript degradante" de Resig para obtener un código más limpio
Echa un vistazo a require.js
fuente
Este truco me funcionó, aunque admito que probablemente esta no sea la mejor manera de resolver este problema. En lugar de intentar esto, debería ver por qué no se cargan los javascripts. Intente mantener una copia local del script en su servidor, etc. o consulte con el proveedor externo desde donde está intentando descargar el script.
De todos modos, aquí está la solución: 1) Inicialice una variable en falso 2) Configúrelo en verdadero cuando se cargue el javascript (usando el atributo onload) 3) verifique si la variable es verdadera o falsa una vez que se haya cargado el cuerpo HTML
fuente
Aquí hay otra solución basada en JQuery sin temporizadores:
Gracias a: https://stackoverflow.com/a/14691735/1243926
Uso de muestra (muestra original de la documentación de JQuery getScript ):
fuente
cache:true
para la llamada $ .getScript (está desactivado de forma predeterminada). De esta manera, para la mayoría de las solicitudes, utiliza automáticamente la versión en caché para la llamada getScript (ahorrándole latencia)Esto se puede hacer de forma segura utilizando promesas.
y usa así
fuente
La razón por la que no funciona en Safari es porque está utilizando la sintaxis de atributos. Sin embargo, esto funcionará bien:
... excepto en IE.
Si desea verificar la secuencia de comandos ejecutada con éxito, simplemente configure una variable usando esa secuencia de comandos y verifique que esté configurada en el código externo.
fuente
<script>
. Si intenta agregarlo antes, obtendrá un error de que la etiqueta no existe, y si lo agrega después, el script ya se ejecutó y activó sus eventos. La única forma es buscar los efectos secundarios causados por el guión.Se propuso establecer un tiempo de espera y luego asumir una falla de carga después de un tiempo de espera.
El problema con ese enfoque es que la suposición se basa en el azar. Una vez que expira el tiempo de espera, la solicitud sigue pendiente. Es posible que se cargue la solicitud del script pendiente, incluso después de que el programador haya asumido que no se cargará.
Si la solicitud se puede cancelar, entonces el programa podría esperar un período y luego cancelar la solicitud.
fuente
Así es como utilicé una promesa para detectar errores de carga que se emiten en el objeto de la ventana:
fuente
Bueno, la única forma en que puedo pensar en hacer todo lo que quieres es bastante fea. Primero realice una llamada AJAX para recuperar el contenido del archivo Javascript. Cuando esto se complete, puede verificar el código de estado para decidir si fue exitoso o no. Luego tome el responseText del objeto xhr y envuélvalo en un try / catch, cree dinámicamente una etiqueta de secuencia de comandos, y para IE puede establecer la propiedad de texto de la etiqueta de secuencia de comandos en el texto JS, en todos los demás navegadores debería poder agregue un nodo de texto con el contenido a la etiqueta del script. Si hay algún código que espera que una etiqueta de secuencia de comandos contenga realmente la ubicación src del archivo, esto no funcionará, pero debería estar bien para la mayoría de las situaciones.
fuente
evento de error
* Actualización de agosto de 2017: Chrome y Firefox activan un error. onload es disparado por Internet Explorer. Edge no dispara ni sobre error ni sobrecarga. No usaría este método, pero podría funcionar en algunos casos. Ver también
<link> onerror no funciona en IE
*
Definición y uso El evento onerror se activa si ocurre un error al cargar un archivo externo (por ejemplo, un documento o una imagen).
Consejo: cuando se usa en medios de audio / video, los eventos relacionados que ocurren cuando hay algún tipo de alteración en el proceso de carga de medios son:
En HTML:
elemento onerror = "myScript">
En JavaScript , usando el método addEventListener ():
object.addEventListener ("error", myScript);
Nota: El método addEventListener () no es compatible con Internet Explorer 8 y versiones anteriores.
Ejemplo Ejecute un JavaScript si ocurre un error al cargar una imagen:
img src = "image.gif" onerror = "myFunction ()">
fuente