<script>タグの読み込みに失敗したかどうかを確認する方法


111

私は<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ファイル内に特別なコードを配置する必要があるソリューションは良いものではないと思います。それは洗練されておらず、柔軟性がありません。)


4
大きなWebサイト、ajaxを介して読み込まれたコンテンツの依存関係の自動読み込み。if+ポーリングは、私がすべてのJSに入れたいとは思わない、迷惑な粗末です。
デビッド

2
また、スクリプトタグインジェクションを使用してJSONPリクエストを作成するときに、ロードの失敗を確認することもできます...
schellsan

回答:


36

スクリプトタグのエラーイベントはありません。あなたはそれがいつ成功したかを知ることができ、タイムアウト後にロードされなかったと仮定します:

<script type="text/javascript" onload="loaded=1" src="....js"></script>

7
JavaScriptエラーが発生した場合でも、「onload」リスナーが起動されます。
Luca Matteis、

38
ファイルがロードされ、ファイル自体にエラーがある場合はそうですが、ファイルが提供されない場合、onloadは起動しません。
Diodeus-James MacFarlane 2009年

1
はい、そうです。それで、私は彼が探しているエラーの種類をより具体的に尋ねました。
Luca Matteis、

1
しかし、タイムアウトはページのコーダーによって提供されなければなりませんか?そのため、コーダーはブラウザーに対して別のタイムアウトを選択し、スクリプトのロードがタイムアウトしたと想定して、少し後で成功させることができます。か否か?
ヒッピートレイル

6
スクリプトタグにonerror evntがあります。リソースが見つからないときに発生します。
Nguyen Tran

24

html5ブラウザーのみに関心がある場合は、エラーイベントを使用できます(これはエラー処理のためだけなので、KISS IMHOの次世代ブラウザーでのみこれをサポートしても問題ありません)。

スペックから:

src属性の値が空の文字列の場合、または解決できない場合、ユーザーエージェントはタスクをキューに入れて、要素でerrorという名前の単純なイベントを発生させ、これらの手順を中止する必要があります。

ロードの結果がエラー(DNSエラー、HTTP 404エラーなど)になった場合、スクリプトブロックの実行は、要素でerrorという名前の単純なイベントを発生させることだけで構成する必要があります。

つまり、エラーが発生しやすいポーリングを実行する必要がなく、それをasyncおよびdefer属性と組み合わせて、スクリプトがページのレンダリングをブロックしていないことを確認できます。

async属性が指定されている場合でもdefer属性を指定すると、デフォルトの同期ブロッキング動作ではなく、遅延のみをサポートする(非同期ではない)レガシーWebブラウザーが遅延動作にフォールバックします。

http://www.w3.org/TR/html5/scripting-1.html#scriptの詳細


1
jQueryのようなJSONP実装のアイデアはこれをサポートしていますか?読み込みに関するJSONPの失敗を検出することについてここで読んだすべてのものは、それが検出できないことを示していますが、タイムアウトは回避策であり、タイムアウトはJSONPの最近のバージョンに追加されました。この答えはタイムアウトよりも良いものを提供しているようです-それは正しいですか?
ヒッピートレイル

1
例は可能ですか?
rogerdpack 2016年

13
<script src="nonexistent.js" onerror="alert('error!')"></script> フィドル
ルディー

@Rudey Uncaught SyntaxError: Unexpected token '<'(最新のChrome)
daleyjem

@daleyjemは、JavaScriptにHTMLタグを配置しようとしたようです。<script src="nonexistent.js" onerror="alert('error!')"></script>JSではなく、HTMLファイルに入れてください。
Rudey

21

Erwinusのスクリプトはうまく機能しますが、明確にコード化されていません。私はそれを片付け、それが何をしていたかを解読するために自由を取りました。私はこれらの変更を行いました:

  • 意味のある変数名
  • の使用prototype
  • require() 引数変数を使用します
  • alert()デフォルトではメッセージは返されません
  • 発生していた構文エラーとスコープの問題を修正しました

Erwinusのおかげで、機能自体は定評があります。

function ScriptLoader() {
}

ScriptLoader.prototype = {

    timer: function (times, // number of times to try
                     delay, // delay per try
                     delayMore, // extra delay per try (additional to delay)
                     test, // called each try, timer stops if this returns true
                     failure, // called on failure
                     result // used internally, shouldn't be passed
            ) {
        var me = this;
        if (times == -1 || times > 0) {
            setTimeout(function () {
                result = (test()) ? 1 : 0;
                me.timer((result) ? 0 : (times > 0) ? --times : times, delay + ((delayMore) ? delayMore : 0), delayMore, test, failure, result);
            }, (result || delay < 0) ? 0.1 : delay);
        } else if (typeof failure == 'function') {
            setTimeout(failure, 1);
        }
    },

    addEvent: function (el, eventName, eventFunc) {
        if (typeof el != 'object') {
            return false;
        }

        if (el.addEventListener) {
            el.addEventListener(eventName, eventFunc, false);
            return true;
        }

        if (el.attachEvent) {
            el.attachEvent("on" + eventName, eventFunc);
            return true;
        }

        return false;
    },

    // add script to dom
    require: function (url, args) {
        var me = this;
        args = args || {};

        var scriptTag = document.createElement('script');
        var headTag = document.getElementsByTagName('head')[0];
        if (!headTag) {
            return false;
        }

        setTimeout(function () {
            var f = (typeof args.success == 'function') ? args.success : function () {
            };
            args.failure = (typeof args.failure == 'function') ? args.failure : function () {
            };
            var fail = function () {
                if (!scriptTag.__es) {
                    scriptTag.__es = true;
                    scriptTag.id = 'failed';
                    args.failure(scriptTag);
                }
            };
            scriptTag.onload = function () {
                scriptTag.id = 'loaded';
                f(scriptTag);
            };
            scriptTag.type = 'text/javascript';
            scriptTag.async = (typeof args.async == 'boolean') ? args.async : false;
            scriptTag.charset = 'utf-8';
            me.__es = false;
            me.addEvent(scriptTag, 'error', fail); // when supported
            // when error event is not supported fall back to timer
            me.timer(15, 1000, 0, function () {
                return (scriptTag.id == 'loaded');
            }, function () {
                if (scriptTag.id != 'loaded') {
                    fail();
                }
            });
            scriptTag.src = url;
            setTimeout(function () {
                try {
                    headTag.appendChild(scriptTag);
                } catch (e) {
                    fail();
                }
            }, 1);
        }, (typeof args.delay == 'number') ? args.delay : 1);
        return true;
    }
};

$(document).ready(function () {
    var loader = new ScriptLoader();
    loader.require('resources/templates.js', {
        async: true, success: function () {
            alert('loaded');
        }, failure: function () {
            alert('NOT loaded');
        }
    });
});

4
私はjQueryの使用を余儀なくされた$ .getScriptをこの関数は生憎、MSIE8-にキャッシュされたスクリプトで失敗なかったとして、
Zathrusライター

@ZathrusWriter、それはおそらくより良いアイデアです、私たちに知らせてくれてありがとう!このコードでURLにランダムな整数を追加すると、キャッシュが削除されます。
Aram Kocharyan 2013年

2
はい、確かにそれで
うまくいき

@ZathrusWriter、それではjQuery実装の仕組みはどのように機能しますか?
Pacerier 2014年

@Pacerier申し訳ありませんが、私はjQueryコア開発者ではないため、実際には答えられません
Zathrus Writer

18

私の作業クリーンソリューション(2017)

function loaderScript(scriptUrl){
   return new Promise(function (res, rej) {
    let script = document.createElement('script');
    script.src = scriptUrl;
    script.type = 'text/javascript';
    script.onError = rej;
    script.async = true;
    script.onload = res;
    script.addEventListener('error',rej);
    script.addEventListener('load',res);
    document.head.appendChild(script);
 })

}

マーティンが指摘したように、そのように使用されます:

const event = loaderScript("myscript.js")
  .then(() => { console.log("loaded"); })
  .catch(() => { console.log("error"); });

または

try{
 await loaderScript("myscript.js")
 console.log("loaded"); 
}catch{
 console.log("error");
}

1
次のようにそれを使用してください:loaderScript("myscript.js").then(() => { console.log("loaded"); }).catch(() => { console.log("error"); });
マーティンWantke

17

私はこれが古いスレッドであることを知っていますが、私はあなたに良い解決策を手に入れました(私はそう思います)。すべてのAJAXを処理する私のクラスからコピーされます。

スクリプトを読み込めない場合は、エラーハンドラーを設定しますが、エラーハンドラーがサポートされていない場合は、15秒間エラーをチェックするタイマーにフォールバックします。

function jsLoader()
{
    var o = this;

    // simple unstopable repeat timer, when t=-1 means endless, when function f() returns true it can be stopped
    o.timer = function(t, i, d, f, fend, b)
    {
        if( t == -1 || t > 0 )
        {
            setTimeout(function() {
                b=(f()) ? 1 : 0;
                o.timer((b) ? 0 : (t>0) ? --t : t, i+((d) ? d : 0), d, f, fend,b );
            }, (b || i < 0) ? 0.1 : i);
        }
        else if(typeof fend == 'function')
        {
            setTimeout(fend, 1);
        }
    };

    o.addEvent = function(el, eventName, eventFunc)
    {
        if(typeof el != 'object')
        {
            return false;
        }

        if(el.addEventListener)
        {
            el.addEventListener (eventName, eventFunc, false);
            return true;
        }

        if(el.attachEvent)
        {
            el.attachEvent("on" + eventName, eventFunc);
            return true;
        }

        return false;
    };

    // add script to dom
    o.require = function(s, delay, baSync, fCallback, fErr)
    {
        var oo = document.createElement('script'),
        oHead = document.getElementsByTagName('head')[0];
        if(!oHead)
        {
            return false;
        }

        setTimeout( function() {
            var f = (typeof fCallback == 'function') ? fCallback : function(){};
            fErr = (typeof fErr == 'function') ? fErr : function(){
                alert('require: Cannot load resource -'+s);
            },
            fe = function(){
                if(!oo.__es)
                {
                    oo.__es = true;
                    oo.id = 'failed';
                    fErr(oo);
                }
            };
            oo.onload = function() {
                oo.id = 'loaded';
                f(oo);
            };
            oo.type = 'text/javascript';
            oo.async = (typeof baSync == 'boolean') ? baSync : false;
            oo.charset = 'utf-8';
            o.__es = false;
            o.addEvent( oo, 'error', fe ); // when supported

            // when error event is not supported fall back to timer
            o.timer(15, 1000, 0, function() {
                return (oo.id == 'loaded');
            }, function(){ 
                if(oo.id != 'loaded'){
                    fe();
                }
            });
            oo.src = s;
            setTimeout(function() {
                try{
                    oHead.appendChild(oo);
                }catch(e){
                    fe();
                }
            },1); 
        }, (typeof delay == 'number') ? delay : 1);  
        return true;
    };

}

$(document).ready( function()
{
    var ol = new jsLoader();
    ol.require('myscript.js', 800, true, function(){
        alert('loaded');
    }, function() {
        alert('NOT loaded');
    });
});

4
... jQueryはどこから来たのですか?
Naftali別名Neal 2011

1
また、クロスブラウザソリューションです;-)
Codebeat

1
@Erwinusヘッダーをチェックしませんでした。私が実行したのは簡単なクロスブラウザーチェックであり、$。getScriptは常に問題なく実行されたので、私はそれで立ち往生しました... XAMPPはこちら
Zathrus Writer 2013

19
これが機能するかどうかにかかわらず、デバッグは言うまでもなく、読むのは大変です。これは、かなり貧弱な書式設定と本当にひどいコーディングスタイルです。変数の名前付けだけでは混乱します。
Thor84no 2014年

7
読み取り可能なコードの値が表示されない場合(および実際に実行されたコードを変更せずに読み取り可能にすることができる場合)、私はあなたとあなたのコードで作業する必要のあるすべての人に謝罪します。
Thor84no 2014年

10

javascriptがnonexistant.jsエラーを返さなかったかどうかを確認するには、http://fail.org/nonexistant.jslike 内に変数を追加var isExecuted = true;し、スクリプトタグが読み込まれたときに変数が存在するかどうかを確認する必要があります。

ただしnonexistant.js、404なしで返されたことを確認するだけの場合(存在することを意味します)、isLoaded変数で試すことができます...

var isExecuted = false;
var isLoaded = false;
script_tag.onload = script_tag.onreadystatechange = function() {
    if(!this.readyState ||
        this.readyState == "loaded" || this.readyState == "complete") {
        // script successfully loaded
        isLoaded = true;

        if(isExecuted) // no error
    }
}

これは両方のケースをカバーします。


1
それは機能しますが、本当に私が望むことをしません-その場合の失敗は決してイベントを発生させません。変数をポーリングする必要がないので、数秒たってもまだfalseの場合は、失敗時コールバックを起動します。
デビッド

どのようなエラーを取得しようとしていますか?ロードに失敗しましたか?nonexstant.jsでJavaScriptの実行に失敗しましたか?HTTP応答エラー?より説明的にしてください。
Luca Matteis、

上記のどれでも良いでしょう。私は特に404エラーを気にしています。
デビッド

404、nonexistant.jsファイルが存在しないかどうかを確認したいですか?しかし、エラーが返されなかったかどうかを確認したい場合はどうでしょうか。
Luca Matteis、

Davidさん、this.readyState / ...がtrueでない場合、スクリプトの読み込みに失敗したと想定できるはずです。基本的にはonErrorです。
コーディ

7

特別な状況ではそれが問題を解決するための最も信頼できる方法であるため、これが反対投票にならないことを願っています。サーバーでCORS(http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)を使用してJavascriptリソースを取得できる場合はいつでも、豊富なオプションを利用できます。

XMLHttpRequestを使用してリソースをフェッチすると、IEを含むすべての最新のブラウザーで機能します。Javascriptをロードしようとしているので、そもそもJavascriptを利用できます。進行状況は、readyState(http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener)を使用して追跡できます。最後に、ファイルの内容を受け取ったら、eval()を使用して実行できます。はい、私はevalと言いました。セキュリティに関しては、スクリプトを正常にロードすることと何の違いもないためです。実際、同様の手法がJohn Resigによって提案され、より優れたタグが付けられています(http://ejohn.org/blog/degrading-script-tags/)。

このメソッドでは、読み込みをevalから分離し、evalが発生する前後に関数を実行することもできます。これは、スクリプトを並行して読み込んで次々に評価する場合に非常に役立ちます。ブラウザーでタグをHTMLに配置すると、ブラウザーで簡単に実行できますが、JavaScriptを使用して実行時にスクリプトを追加することはできません。

CORSは、スクリプトをロードするためにJSONPよりも望ましい(http://en.wikipedia.org/wiki/XMLHttpRequest#Cross-domain_requests)。ただし、他のサイトに埋め込む独自のサードパーティ製ウィジェットを開発している場合は、実際に独自のドメインから独自のiframeにJavaScriptファイルをロードする必要があります(ここでも、AJAXを使用します)。

要するに:

  1. AJAX GETを使用してリソースをロードできるかどうかを確認してください

  2. 正常に読み込まれた後にevalを使用します

それを改善するには:

  1. 送信されるキャッシュ制御ヘッダーを確認する

  2. 必要に応じて、localStorageのコンテンツをキャッシュする方法を調べます。

  3. よりクリーンなコードについては、Resigの「degrading javascript」を確認してください

  4. require.jsを確認してください


この方法では、元のサーバーでCORSが有効になっている必要があることに注意してください。常にそうであるとは限らず、制御可能でもありません。
rogerdpack 2016年

5

このトリックは私にとってはうまくいきましたが、これはおそらくこの問題を解決する最良の方法ではないことを認めます。これを試す代わりに、JavaScriptがロードされない理由を確認してください。サーバーなどにスクリプトのローカルコピーを保存するか、スクリプトのダウンロード元のサードパーティベンダーに確認してください。

とにかく、ここに回避策があります:1)変数をfalseに初期化します2)JavaScriptが読み込まれたときにtrueに設定します(onload属性を使用)3)HTML本体が読み込まれたら変数がtrueまたはfalseかどうかを確認します

<html>
  <head>
    <script>
      var scriptLoaded = false;

      function checkScriptLoaded() {
        if (scriptLoaded) {
          // do something here
        } else {
          // do something else here!
        }
      }
    </script>
    <script src="http://some-external-script.js" onload="scriptLoaded=true;" />
  </head>
  <body onload="checkScriptLoaded()">
    <p>My Test Page!</p>
  </body>
</html>

1
スクリプトがまだ読み込まれている場合はどうなりますか?ファイルが見つからなかったか、単に待機する必要があるかどうかをどうやって確認しますか?
osa

スクリプトタグがドキュメントソースに直接配置されている限り、このソリューションは私のテストで機能します。ドキュメントのonloadイベントは、ページソースで参照されているすべてのリソースが既に読み込まれる(または失敗する)まで発生しません。ただし、後でDOMにスクリプトを挿入する必要がある場合は、別の方法が必要です。
Jamey Sharp

素晴らしいソリューション。なぜ賛成されなかったのか分かりません。
Lotfi 2014

これは、スクリプトが同期的に読み込まれ、他のすべてをブロックすることを前提としていますが、常にそうであるとは限りません。実際、スクリプトをロードする方法としてはお勧めできません。
Vitim.us

4

次に、タイマーのない別のjQueryベースのソリューションを示します。

<script type="text/javascript">
function loadScript(url, onsuccess, onerror) {
$.get(url)
    .done(function() {
        // File/url exists
        console.log("JS Loader: file exists, executing $.getScript "+url)
        $.getScript(url, function() {
            if (onsuccess) {
                console.log("JS Loader: Ok, loaded. Calling onsuccess() for " + url);
                onsuccess();
                console.log("JS Loader: done with onsuccess() for " + url);
            } else {
                console.log("JS Loader: Ok, loaded, no onsuccess() callback " + url)
            }
        });
    }).fail(function() {
            // File/url does not exist
            if (onerror) {
                console.error("JS Loader: probably 404 not found. Not calling $.getScript. Calling onerror() for " + url);
                onerror();
                console.error("JS Loader: done with onerror() for " + url);
            } else {
                console.error("JS Loader: probably 404 not found. Not calling $.getScript. No onerror() callback " + url);
            }
    });
}
</script>

おかげで:https : //stackoverflow.com/a/14691735/1243926

使用例(JQuery getScriptドキュメントの元のサンプル):

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>jQuery.getScript demo</title>
  <style>
  .block {
     background-color: blue;
     width: 150px;
     height: 70px;
     margin: 10px;
  }
  </style>
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>

<button id="go">&raquo; Run</button>
<div class="block"></div>

<script>


function loadScript(url, onsuccess, onerror) {
$.get(url)
    .done(function() {
        // File/url exists
        console.log("JS Loader: file exists, executing $.getScript "+url)
        $.getScript(url, function() {
            if (onsuccess) {
                console.log("JS Loader: Ok, loaded. Calling onsuccess() for " + url);
                onsuccess();
                console.log("JS Loader: done with onsuccess() for " + url);
            } else {
                console.log("JS Loader: Ok, loaded, no onsuccess() callback " + url)
            }
        });
    }).fail(function() {
            // File/url does not exist
            if (onerror) {
                console.error("JS Loader: probably 404 not found. Not calling $.getScript. Calling onerror() for " + url);
                onerror();
                console.error("JS Loader: done with onerror() for " + url);
            } else {
                console.error("JS Loader: probably 404 not found. Not calling $.getScript. No onerror() callback " + url);
            }
    });
}


loadScript("https://raw.github.com/jquery/jquery-color/master/jquery.color.js", function() {
  console.log("loaded jquery-color");
  $( "#go" ).click(function() {
    $( ".block" )
      .animate({
        backgroundColor: "rgb(255, 180, 180)"
      }, 1000 )
      .delay( 500 )
      .animate({
        backgroundColor: "olive"
      }, 1000 )
      .delay( 500 )
      .animate({
        backgroundColor: "#00f"
      }, 1000 );
  });
}, function() { console.error("Cannot load jquery-color"); });


</script>
</body>
</html>

いいセルゲイ!では、.get()を使用してファイルが存在するかどうかを確認し、.getScript()を使用してエラーなしで実行/ロードできるかどうかを確認していますか?
jjwdesign 2013年

2
はい。覚えていますが、このアプローチには制限があります。クロスドメインスクリプティングの制限のため、正しく覚えていれば、多くのスクリプトをこの方法で読み込むことはできません。
osa

jQuery(または別のライブラリ)を使用する際の問題は、最初にそのライブラリをロードする必要があることです。では、そのライブラリのロードに失敗したかどうかをどのように確認しますか?
Pacerier 2014年

私もこのアプローチを採用しcache:trueましたが、$。getScript呼び出しに使用することをお勧めします(これはデフォルトではオフになっています)。このように、ほとんどのリクエストで、getScript呼び出しにキャッシュされたバージョンを自動的に使用します(レイテンシを節約します)
Laurens Rietveld

2

これはpromiseを使用して安全に行うことができます

function loadScript(src) {
  return new Promise(function(resolve, reject) {
    let script = document.createElement('script');
    script.src = src;

    script.onload = () => resolve(script);
    script.onerror = () => reject(new Error("Script load error: " + src));

    document.head.append(script);
  });
}

そしてこのように使います

let promise = loadScript("https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js");

promise.then(
  script => alert(`${script.src} is loaded!`),
  error => alert(`Error: ${error.message}`)
);

1

Safariで機能しないのは、属性構文を使用しているためです。これはうまくいきます:

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

... IEを除く。

スクリプトが正常に実行されたことを確認したい場合は、そのスクリプトを使用して変数を設定し、外部コードで設定されていることを確認します。


これは実際にはSafariに影響を与えません-それでもエラーハンドラーを起動しません。
デビッド

サファリのonclickハンドラーに問題があり、これがそれを修正したので、onerrorの場合も同じだと思いました。どうやら...

1
これは静的に含まれるスクリプトタグでも機能しますか、それとも動的に挿入されたものだけですか?私はjQueryがロードに失敗したかどうかを検出するためにそれを使用しようとしましたが、機能しませんでした。私がそれを間違っているのか、それともこの場合はうまくいかないのかわかりません。
ヒッピートレイル

1
@hippietrail-イベントリスナーは静的HTMLでは機能しません<script>。前に追加しようとすると、タグが存在しないというエラーが発生します。その後追加すると、スクリプトはすでに実行されており、イベントがトリガーされています。唯一の方法は、スクリプトによって引き起こされる副作用を探すことです。

どうもありがとう。JSエラーではなく、404でのみ機能することは残念です。スクリプト内で変数を設定することは、常に実用的であるとは限りません。
Jo Liss

0

タイムアウトを設定し、タイムアウト後にロード障害を想定することが提案されました。

setTimeout(fireCustomOnerror, 4000);

そのアプローチの問題は、仮定が偶然に基づいていることです。タイムアウトの期限が切れても、リクエストはまだ保留中です。プログラマがロードが発生しないと想定した後でも、保留中のスクリプトのリクエストがロードされる場合があります。

リクエストをキャンセルできる場合、プログラムはしばらく待機してからリクエストをキャンセルできます。


0

これは、ウィンドウオブジェクトで発生する読み込みエラーを検出するためにpromiseを使用した方法です。

<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

まあ、私があなたが望むすべてをすることを考えることができる唯一の方法はかなり醜いです。最初にAJAX呼び出しを実行して、JavaScriptファイルのコンテンツを取得します。これが完了すると、ステータスコードをチェックして、これが成功したかどうかを判断できます。次に、xhrオブジェクトからresponseTextを取得して、それをtry / catchでラップし、スクリプトタグを動的に作成します。IEの場合、スクリプトタグのtextプロパティをJSテキストに設定できます。他のすべてのブラウザーでは、内容を含むテキストノードをスクリプトタグに追加します。スクリプトタグが実際にファイルのsrcの場所を含むことを期待するコードがある場合、これは機能しませんが、ほとんどの状況で問題ありません。


このソリューションは、最新のブラウザでは時代遅れです。
Simon_Weaver

0

onerrorイベント

* 2017年8月更新:onerrorはChromeとFirefoxによって起動されます。onloadはInternet Explorerによって起動されます。Edgeはonerrorもonloadも起動しません。この方法は使用しませんが、場合によっては機能します。こちらもご覧ください

<link> onerrorがIEで機能しない

*

定義と使用法 onerrorイベントは、外部ファイル(ドキュメントや画像など)のロード中にエラーが発生した場合にトリガーされます。

ヒント:オーディオ/ビデオメディアで使用した場合、メディアの読み込みプロセスになんらかの妨害があるときに発生する関連イベントは次のとおりです。

  • onabort
  • 空にされた
  • ストールした
  • 一時停止

HTML:

要素onerror = "myScript">

JavaScriptでは、addEventListener()メソッドを使用します

object.addEventListener( "error"、myScript);

注: addEventListener()メソッドは、Internet Explorer 8以前のバージョンではサポートされていません。

画像の読み込み中にエラーが発生した場合にJavaScriptを実行します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.