Как определить, не удалось ли загрузить тег <script> - PullRequest
102 голосов
/ 11 февраля 2009

Я динамически добавляю <script> теги к <head> страницы, и я хотел бы иметь возможность определить, не удалось ли загрузить каким-либо образом - 404, ошибка скрипта в загруженном скрипте, что угодно .

В Firefox это работает:

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);

Однако это не работает в IE или Safari.

Кто-нибудь знает, как заставить это работать в браузерах, отличных от Firefox?

(Я не думаю, что решение, которое требует размещения специального кода в файлах .js, является хорошим. Оно не элегантное и негибкое.)

Ответы [ 15 ]

1 голос
/ 18 февраля 2010

Ну, единственный способ, которым я могу думать о том, чтобы делать все, что ты хочешь, довольно уродлив. Сначала выполните AJAX-вызов, чтобы получить содержимое файла Javascript. Когда это завершится, вы можете проверить код состояния, чтобы решить, было ли это успешно или нет. Затем возьмите responseText из объекта xhr и оберните его в try / catch, динамически создайте тег script, и для IE вы можете установить свойство text тега script для текста JS, во всех других браузерах вы сможете добавить текстовый узел с содержимым к тегу скрипта. Если есть какой-либо код, который ожидает, что тег script на самом деле содержит местоположение src файла, это не сработает, но в большинстве случаев это подойдет.

1 голос
/ 12 февраля 2009

Причина, по которой он не работает в Safari, заключается в том, что вы используете синтаксис атрибута. Это будет хорошо работать, хотя:

script_tag.addEventListener('error', function(){/*...*/}, true);

... кроме как в IE.

Если вы хотите проверить, успешно ли выполнен скрипт, просто установите переменную, используя этот скрипт, и проверьте, чтобы он был установлен во внешнем коде.

0 голосов
/ 23 апреля 2019

Событие ошибки

* Обновление август 2017: Chrome и Firefox запускают onerror. onload запускается Internet Explorer. Edge не запускает ни ошибки, ни загрузки. Я бы не использовал этот метод, но он мог бы работать в некоторых случаях. Смотри также

ошибка не работает в IE

*

Определение и использование Событие onerror вызывается, если при загрузке внешнего файла (например, документа или изображения) произошла ошибка.

Подсказка: При использовании на аудио / видео носителях связанные события, которые происходят, когда есть какое-то нарушение в процессе загрузки носителя:

  • онаборт
  • односторонне
  • установлено
  • onsuspend

В HTML:

element onerror = "myScript">

В JavaScript , используя метод addEventListener ():

object.addEventListener («ошибка», myScript);

Примечание: Метод addEventListener () не поддерживается в Internet Explorer 8 и более ранних версиях.

* +1047 * Пример Выполните JavaScript, если при загрузке изображения возникает ошибка:

img src = "image.gif" onerror = "myFunction ()">

0 голосов
/ 23 декабря 2018

Вот как я использовал обещание для обнаружения ошибок загрузки, которые генерируются в объекте окна:

<script type='module'>
window.addEventListener('error', function(error) {
  let url = error.filename
  url = url.substring(0, (url.indexOf("#") == -1) ? url.length : url.indexOf("#"));
  url = url.substring(0, (url.indexOf("?") == -1) ? url.length : url.indexOf("?"));
  url = url.substring(url.lastIndexOf("/") + 1, url.length);
  window.scriptLoadReject && window.scriptLoadReject[url] && window.scriptLoadReject[url](error);
}, true);
window.boot=function boot() {
  const t=document.createElement('script');
  t.id='index.mjs';
  t.type='module';
  new Promise((resolve, reject) => {
    window.scriptLoadReject = window.scriptLoadReject || {};
    window.scriptLoadReject[t.id] = reject;
    t.addEventListener('error', reject);
    t.addEventListener('load', resolve); // Careful load is sometimes called even if errors prevent your script from running! This promise is only meant to catch errors while loading the file.
  }).catch((value) => {
    document.body.innerHTML='Error loading ' + t.id + '! Please reload this webpage.<br/>If this error persists, please try again later.<div><br/>' + t.id + ':' + value.lineno + ':' + value.colno + '<br/>' + (value && value.message);
  });
  t.src='./index.mjs'+'?'+new Date().getTime();
  document.head.appendChild(t);
};
</script>
<script nomodule>document.body.innerHTML='This website needs ES6 Modules!<br/>Please enable ES6 Modules and then reload this webpage.';</script>
</head>

<body onload="boot()" style="margin: 0;border: 0;padding: 0;text-align: center;">
  <noscript>This website needs JavaScript!<br/>Please enable JavaScript and then reload this webpage.</noscript>
0 голосов
/ 29 января 2010

Было предложено установить тайм-аут, а затем предположить сбой загрузки после тайм-аута.

setTimeout(fireCustomOnerror, 4000);

Проблема этого подхода заключается в том, что предположение основано на случайности. После истечения времени ожидания запрос все еще находится на рассмотрении. Запрос на ожидающий сценарий может загружаться даже после того, как программист предположил, что загрузка не произойдет.

Если запрос может быть отменен, то программа может подождать некоторое время, а затем отменить запрос.

...