कैसे बताएं कि कोई <script> टैग लोड करने में विफल रहा या नहीं


111

मैं गतिशील रूप <script>से एक पृष्ठ पर टैग जोड़ रहा हूं <head>, और मैं यह बताना चाहूंगा कि क्या लोडिंग किसी तरह से विफल रही - 404, भरी हुई स्क्रिप्ट में एक स्क्रिप्ट त्रुटि, जो भी हो।

फ़ायरफ़ॉक्स में, यह काम करता है:

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 या सफारी में काम नहीं करता है।

क्या किसी को फ़ायरफ़ॉक्स के अलावा अन्य ब्राउज़रों में यह काम करने का तरीका पता है?

(मुझे नहीं लगता कि एक समाधान के लिए .js फ़ाइलों के भीतर विशेष कोड रखने की आवश्यकता होती है, यह एक अच्छा है। यह अयोग्य और अनम्य है।)


4
बड़ी वेबसाइट, अजाक्स के माध्यम से भरी हुई सामग्री के लिए निर्भरता का स्वत: लोड। if+ मतदान कष्टप्रद है कि मुझे सभी जेएस में नहीं डालना है।
डेविड

2
स्क्रिप्ट टैग इंजेक्शन का उपयोग करते हुए JSONP अनुरोध करने पर आप लोड विफलता की जांच भी कर सकते हैं ...
schellsan

जवाबों:


36

स्क्रिप्ट टैग के लिए कोई त्रुटि ईवेंट नहीं है। आप यह बता सकते हैं कि यह कब सफल है, और मान लें कि यह समय समाप्त होने के बाद लोड नहीं हुआ है:

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

7
"त्रुटि" श्रोता को निकाल दिया जाएगा भले ही एक जावास्क्रिप्ट त्रुटि हो।
लुका मैटिस

38
ठीक है, हाँ अगर फ़ाइल लोड होती है और फ़ाइल में कोई त्रुटि होती है, लेकिन यदि फ़ाइल को सेवा नहीं दी जाती है, तो ऑनलोड कभी भी फायर नहीं करेगा।
डायोडस - जेम्स मैकफर्लेन

1
हाँ, यह सच है, इसीलिए मैंने और अधिक विशिष्ट होने के लिए कहा कि वह किस प्रकार की त्रुटि की तलाश में है।
लुका मैटिस

1
लेकिन पृष्ठ के कोडर द्वारा सही समय प्रदान किया जाना है? तो कोडर ब्राउज़र के लिए एक अलग टाइमआउट चुन सकता है, स्क्रिप्ट लोड समय समाप्त मान सकता है, और फिर बाद में थोड़ा सफल हुआ है। या नहीं?
हिप्पिट्रैसिल

6
स्क्रिप्ट टैग के लिए onerror evnt है। संसाधन नहीं मिलने पर यह आग लगाएगा।
गुयेन ट्रैन

24

आप केवल एचटीएमएल 5 ब्राउज़रों आप त्रुटि घटना का उपयोग कर सकते हैं के बारे में परवाह है (क्योंकि यह केवल त्रुटि से निपटने के लिए है, यह केवल KISS IMHO के लिए अगले जनरल ब्राउज़रों पर इसे समर्थन करने के लिए ठीक होना चाहिए)।

कल्पना से:

यदि src विशेषता का मान खाली स्ट्रिंग है या यदि इसे हल नहीं किया जा सकता है, तो उपयोगकर्ता एजेंट को तत्व में एक साधारण घटना को त्रुटि नाम देने के लिए एक कार्य को कतारबद्ध करना होगा , और इन चरणों को निरस्त करना होगा।

~

यदि लोड में त्रुटि हुई (उदाहरण के लिए DNS त्रुटि, या HTTP 404 त्रुटि) स्क्रिप्ट ब्लॉक को निष्पादित करने के लिए तत्व में एक साधारण घटना नाम की त्रुटि को फायर करना शामिल है।

इसका मतलब है कि आपको मतदान में कोई त्रुटि नहीं करनी है और इसे async और defer विशेषता के साथ जोड़ सकते हैं ताकि यह सुनिश्चित हो सके कि स्क्रिप्ट पेज रेंडरिंग को ब्लॉक नहीं कर रही है:

यदि Async विशेषता निर्दिष्ट की जाती है, तब भी आस्थगित विशेषता निर्दिष्ट की जा सकती है, विरासत वेब ब्राउज़रों को उत्पन्न करने के लिए जो केवल समकालिक अवरुद्ध व्यवहार के बजाय डिफर व्यवहार को वापस करने के लिए defer (और async) का समर्थन करते हैं जो कि डिफ़ॉल्ट है।

Http://www.w3.org/TR/html5/scripting-1.html#script पर अधिक


1
JSONP कार्यान्वयन का कोई भी विचार, जैसे कि jQuery इस का समर्थन करता है? सब कुछ मैंने यहां पाया है कि JSONP को लोड करने में विफलताओं के बारे में यह कहते हैं कि इसका पता नहीं लगाया जा सकता है, लेकिन टाइमआउट एक वर्कअराउंड हो सकता है, और JSONP के हाल के संस्करण में एक टाइमआउट जोड़ा गया था। ऐसा लगता है कि यह जवाब हालांकि टाइमआउट से कुछ बेहतर प्रदान करता है - क्या यह सही है?
hippietrail

1
कृपया संभव है?
रोजरपैक

13
<script src="nonexistent.js" onerror="alert('error!')"></script> फिडल
रुडी

@Rudey Uncaught SyntaxError: Unexpected token '<'(नवीनतम क्रोम में)
daleyjem

@daleyjem लगता है कि आपने जावास्क्रिप्ट में HTML टैग लगाने का प्रयास किया है। <script src="nonexistent.js" onerror="alert('error!')"></script>अपनी HTML फ़ाइल में जाना चाहिए, JS नहीं।
रुडी

21

एरविनस की स्क्रिप्ट बहुत अच्छी है, लेकिन बहुत स्पष्ट रूप से कोडित नहीं है। मैंने इसे साफ करने और जो कर रहा था उसे समझने के लिए स्वतंत्रता ली। मैंने ये बदलाव किए हैं:

  • सार्थक चर नाम
  • का उपयोग prototype
  • require() एक तर्क चर का उपयोग करता है
  • कोई भी alert()संदेश डिफ़ॉल्ट रूप से वापस नहीं किया जाता है
  • कुछ सिंटैक्स त्रुटियों और कार्यक्षेत्र समस्याओं को ठीक किया जो मुझे मिल रहा था

इरविनस के लिए फिर से धन्यवाद, कार्यक्षमता स्वयं पर है।

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 में एक यादृच्छिक int जोड़ सकते हैं और यह कैशिंग को हटा देगा।
अराम कोचरन

2
हाँ अराम, यह निश्चित रूप से चाल चलेगा, हालांकि यह ब्राउज़र की कैशिंग को भी अमान्य कर देगा, इसलिए इस तरह के मामले में ओवरहेड वास्तव में इसके लायक नहीं है;)
ज़थ्रस राइटर

@ZathrusWriter, तो jQuery के कार्यान्वयन का कार्य कैसे करता है?
पचेरियर

@Pacerier क्षमा करें, मैं एक jQuery कोर डेवलपर नहीं हूं, इसलिए मैं वास्तव में इसका जवाब नहीं दे सकता हूं कि
Zathrus लेखक

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"); });
मार्टिन विवेके

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 कहाँ से आया?
नावफली उर्फ ​​नील

1
और यह भी, यह एक क्रॉस-ब्राउज़र समाधान है ;-)
कोडविट

1
@Erwinus मैंने हेडर की जांच नहीं की, यह सिर्फ एक त्वरित क्रॉस-ब्राउज़र की जांच थी जिसे मैंने प्रदर्शन किया और $ .getScript हमेशा समस्याओं के बिना चला, इसलिए मैं इसके साथ फंस गया ... आप खुद का प्रयास करने के लिए स्वागत करते हैं, मैं W7 का उपयोग कर रहा हूं। XAMPP यहां
Zathrus लेखक

19
यह काम करता है या नहीं, यह पढ़ने के लिए दर्दनाक है - अकेले डिबग करें। यह कुछ बहुत खराब स्वरूपण और वास्तव में अत्याचारी कोडिंग शैली है। अकेले नामकरण एक गड़बड़ है।
Thor84no

7
यदि आपको पठनीय कोड का मूल्य नहीं दिखता (और आप वास्तव में निष्पादित कोड में कोई बदलाव किए बिना उस पठनीय को बना सकते हैं), तो मुझे हर एक व्यक्ति के लिए खेद है जो आपको और आपके कोड के साथ काम करना है।
Thor84no

10

में जावास्क्रिप्ट यह जाँचने के लिए nonexistant.jsलौट आए कोई त्रुटि आप एक चर के अंदर जोड़ने के लिए http://fail.org/nonexistant.jsकी तरह var isExecuted = true;है और फिर जाँच यदि वह मौजूद है जब स्क्रिप्ट टैग भरी हुई है।

हालाँकि यदि आप केवल यह जांचना चाहते हैं कि nonexistant.js404 के बिना दिया गया (मतलब यह मौजूद है), तो आप एक 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
यह काम करता है, लेकिन वास्तव में मैं जो चाहता हूं वह नहीं करता - उस मामले में विफलता कभी भी एक घटना को आग नहीं देगी। मैं एक चर के लिए चुनाव नहीं करना चाहता हूं और, अगर यह कुछ सेकंड के बाद भी गलत है, तो ऑन-फेल कॉलबैक को आग दें।
डेविड

आप किस तरह की त्रुटि को पुनः प्राप्त करने की कोशिश कर रहे हैं? लोड करने में विफलता? किसी को भी xxstant.js में जावास्क्रिप्ट निष्पादित करने में विफलता? HTTP रिस्पांस त्रुटि? कृपया अधिक विवरणात्मक बनें।
लुका मैटिस

उपरोक्त में से कोई भी अच्छा होगा। मैं विशेष रूप से एक 404 त्रुटि के बारे में परवाह करता हूं, हालांकि।
डेविड

404, जिसका अर्थ है कि आप जांचना चाहते हैं कि फाइल noxistant.js मौजूद नहीं है? लेकिन अगर यह जांचना चाहता है कि क्या इसमें कोई त्रुटि नहीं है?
लुका मैटिस 21

हे डेविड, आपको यह मानने में सक्षम होना चाहिए कि अगर यह पहले से ही / ... सच नहीं है, तो स्क्रिप्ट लोड करने में विफल रही। मूल रूप से एक onrror।
कोड़ी

7

मुझे उम्मीद है कि यह कम नहीं हुआ है, क्योंकि विशेष परिस्थितियों में यह समस्या को हल करने का सबसे विश्वसनीय तरीका है। किसी भी समय सर्वर आपको CORS ( http://en.wikipedia.org/wiki/Cross-origin_resource_sharing ) का उपयोग करके एक जावास्क्रिप्ट संसाधन प्राप्त करने की अनुमति देता है , आपके पास ऐसा करने के लिए विकल्पों की एक समृद्ध सरणी है।

संसाधनों को लाने के लिए XMLHttpRequest का उपयोग करना IE सहित सभी आधुनिक ब्राउज़रों में काम करेगा। चूंकि आप जावास्क्रिप्ट लोड करना चाह रहे हैं, इसलिए आपके पास पहली जगह में जावास्क्रिप्ट उपलब्ध है। आप रेडीस्टेट ( http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener ) का उपयोग करके प्रगति को ट्रैक कर सकते हैं । अंत में, एक बार जब आप फ़ाइल की सामग्री प्राप्त करते हैं, तो आप इसे eval () के साथ निष्पादित कर सकते हैं। हां, मैंने स्पष्ट कहा - क्योंकि सुरक्षा-वार यह सामान्य रूप से स्क्रिप्ट को लोड करने से अलग नहीं है। वास्तव में, इसी तरह की तकनीक का सुझाव जॉन रेजिग ने निक्कर टैग ( http://ejohn.org/blog/demission-script-tags/ ) के लिए दिया है।

यह विधि आपको लोडिंग को eval से अलग करने की अनुमति देती है, और eval होने से पहले और बाद में फ़ंक्शन निष्पादित करती है। समानांतर में स्क्रिप्ट लोड करते समय यह बहुत उपयोगी हो जाता है, लेकिन एक के बाद एक उनका मूल्यांकन करना - कुछ ब्राउज़र HTML में टैग लगाने पर आसानी से कर सकते हैं, लेकिन जावास्क्रिप्ट के साथ रन-टाइम पर स्क्रिप्ट जोड़कर आपको ऐसा करने की अनुमति नहीं है।

लोडिंग स्क्रिप्ट ( http://en.wikipedia.org/wiki/XMLHttpRequest#Cross-domain_requests ) के लिए CORS JSONP के लिए भी बेहतर है । हालाँकि, यदि आप अन्य साइटों में एम्बेडेड होने के लिए अपना स्वयं का तृतीय-पक्ष विजेट विकसित कर रहे हैं, तो आपको वास्तव में अपने स्वयं के iframe में अपने डोमेन से जावास्क्रिप्ट फ़ाइलों को लोड करना चाहिए (फिर से, AJAX का उपयोग करके)

संक्षेप में:

  1. यह देखने की कोशिश करें कि क्या आप AJAX GET का उपयोग करके संसाधन लोड कर सकते हैं

  2. इसे सफलतापूर्वक लोड करने के बाद eval का उपयोग करें

इसे सुधारने के लिए:

  1. कैश-कंट्रोल हेडर भेजे जाने की जाँच करें

  2. यदि आप की जरूरत है, तो सामग्री को स्थानीयस्टोरेज में कैशिंग करें

  3. क्लीनर कोड के लिए Resig की "अपमानजनक जावास्क्रिप्ट" देखें

  4. आवश्यकता की जाँच करें


NB कि इस तरह से मूल सर्वर को CORS सक्षम होना चाहिए, जो हमेशा मामला या नियंत्रणीय नहीं होता है: |
रोजरपैक

5

इस ट्रिक ने मेरे लिए काम किया, हालाँकि मैं मानता हूँ कि यह शायद इस समस्या को हल करने का सबसे अच्छा तरीका नहीं है। यह प्रयास करने के बजाय, आपको यह देखना चाहिए कि javascripts लोड क्यों नहीं कर रहे हैं। अपने सर्वर में स्क्रिप्ट की एक स्थानीय प्रतिलिपि रखने की कोशिश करें, आदि या तीसरे पक्ष के विक्रेता के साथ जांचें जहां से आप स्क्रिप्ट डाउनलोड करने का प्रयास कर रहे हैं।

वैसे भी, यहाँ पर वर्कअराउंड: 1) एक वेरिएबल को झूठा 2 के लिए आरंभ करें) जब जावास्क्रिप्ट लोड हो या HTML बॉडी लोड हो जाए तो यह जाँचें कि क्या सही है या ओवलोड विशेषता का उपयोग करके) इसे सही पर सेट करें।

<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

यह समाधान मेरे परीक्षण में काम करता है, जब तक स्क्रिप्ट टैग को दस्तावेज़ स्रोत में सीधे रखा जाता है। जब तक पृष्ठ स्रोत में संदर्भित सभी संसाधन पहले से लोड (या विफल) नहीं हो जाते, तब तक दस्तावेज़ के ऑनलोड ईवेंट में आग नहीं लगती। यदि आपको बाद में DOM में स्क्रिप्ट सम्मिलित करने की आवश्यकता है, हालाँकि, आपको एक और दृष्टिकोण की आवश्यकता है।
जॅमी शार्प

महान समाधान। मुझे समझ में नहीं आता कि इसे क्यों नहीं बनाया गया है।
लॉटफी

यह मानता है कि स्क्रिप्ट को अन्य सभी चीजों को अवरुद्ध करके समान रूप से लोड किया जाएगा, जो हमेशा सच नहीं होता है। वास्तव में, यह स्क्रिप्ट लोड करने का अनुशंसित तरीका नहीं है।
विटिम।

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

2
हाँ। जैसा कि मुझे याद है, इस दृष्टिकोण की सीमाएँ हैं: आप इस तरह से कई स्क्रिप्ट लोड नहीं कर पाएंगे --- अगर मुझे सही याद है, तो क्रॉस-डोमेन स्क्रिप्टिंग प्रतिबंधों के कारण।
osa

JQuery (या किसी अन्य लाइब्रेरी) का उपयोग करने में समस्या यह है कि आपको पहले उस लाइब्रेरी को लोड करना होगा। तो अगर आप उस पुस्तकालय को लोड करने में विफल रहे तो आप कैसे जांच करेंगे ?
पचेरियर

मैंने इस दृष्टिकोण को भी लिया है, लेकिन मैं cache:true$ .getScript कॉल के लिए उपयोग करने की सलाह देता हूं (यह डिफ़ॉल्ट रूप से बंद है)। इस तरह, अधिकांश अनुरोधों के लिए, यह स्वचालित रूप से गेटस्क्रिप्ट कॉल के लिए कैश्ड संस्करण का उपयोग करता है (आपको विलंबता से बचाते हुए)
लॉरेंस

2

यह सुरक्षित रूप से वादों का उपयोग करके किया जा सकता है

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

कारण यह सफारी में काम नहीं करता है क्योंकि आप विशेषता वाक्यविन्यास का उपयोग कर रहे हैं। हालांकि यह ठीक काम करेगा:

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

... आईई को छोड़कर।

यदि आप सफलतापूर्वक निष्पादित स्क्रिप्ट की जांच करना चाहते हैं, तो बस उस स्क्रिप्ट का उपयोग करके एक चर सेट करें और इसे बाहरी कोड में सेट करने के लिए जांचें।


कि वास्तव में सफारी के लिए कोई फर्क नहीं पड़ता है - यह अभी भी त्रुटि हैंडलर फायर नहीं करता है।
डेविड

मुझे सफारी में एक ऑनक्लिक हैंडलर के साथ एक समस्या थी और यह वही था जो इसे तय करता था, इसलिए मुझे लगा कि यह ऑनरोर के लिए भी यही होगा। जाहिरा तौर पर नहीं ...

1
क्या यह काम स्क्रिप्ट के टैग्स के लिए भी किया जाना चाहिए, या सिर्फ डायनामिक तरीके से इंजेक्ट किया जाना चाहिए? मैंने अभी यह पता लगाने के लिए इसका उपयोग करने की कोशिश की कि क्या jQuery लोड करने में विफल रहा, लेकिन यह काम नहीं किया। मुझे यकीन नहीं है कि अगर मैं इसे गलत कर रहा हूं या यह सिर्फ इस मामले में काम नहीं करता है।
हिप्पिएट्रैल

1
@hippietrail - एक ईवेंट श्रोता कभी भी स्थिर HTML पर काम नहीं करेगा <script>। यदि आप इसे जोड़ने से पहले कोशिश करते हैं तो आपको एक त्रुटि मिलती है कि टैग मौजूद नहीं है, और यदि आप इसे जोड़ते हैं तो स्क्रिप्ट के पहले से ही चलने और इसके ईवेंट ट्रिगर हो जाते हैं। स्क्रिप्ट के कारण होने वाले दुष्प्रभावों को देखने का एकमात्र तरीका है।

आभार आभार। बहुत बुरा है कि यह केवल 404 के लिए काम करता है, जेएस त्रुटियों के लिए नहीं। स्क्रिप्ट के अंदर एक चर सेट करना हमेशा व्यावहारिक नहीं होता है।
जो लिस

0

यह एक टाइमआउट सेट करने और फिर एक टाइमआउट के बाद लोड विफलता मानने का प्रस्ताव था।

setTimeout(fireCustomOnerror, 4000);

उस दृष्टिकोण के साथ समस्या यह है कि धारणा मौका पर आधारित है। आपके समय समाप्त होने के बाद, अनुरोध अभी भी लंबित है। लंबित स्क्रिप्ट के लिए अनुरोध लोड हो सकता है, भले ही प्रोग्रामर ने मान लिया हो कि लोड नहीं होगा।

यदि अनुरोध रद्द किया जा सकता है, तो कार्यक्रम एक अवधि तक इंतजार कर सकता है, फिर अनुरोध को रद्द करें।


0

इस तरह से मैंने विंडो ऑब्जेक्ट पर उत्सर्जित लोडिंग त्रुटियों का पता लगाने के लिए एक वादे का उपयोग किया:

<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 कॉल करें। जब यह पूरा हो जाता है तो आप यह निर्धारित करने के लिए कि यह सफल था या नहीं, यह जानने के लिए आप स्टेटस कोड की जांच कर सकते हैं। फिर प्रतिक्रिया वस्तु को xhr ऑब्जेक्ट से लें और इसे एक कोशिश / कैच में लपेटें, गतिशील रूप से एक स्क्रिप्ट टैग बनाएं, और IE के लिए आप स्क्रिप्ट टैग की पाठ संपत्ति को जेएस पाठ में सेट कर सकते हैं, अन्य सभी ब्राउज़रों में आप का जवाब देने में सक्षम होना चाहिए स्क्रिप्ट टैग की सामग्री के साथ एक पाठ नोड संलग्न करें। यदि कोई ऐसा कोड है जो स्क्रिप्ट टैग की अपेक्षा करता है जिसमें वास्तव में फ़ाइल का src स्थान होता है, तो यह काम नहीं करेगा, लेकिन यह अधिकांश स्थितियों के लिए ठीक होना चाहिए।


यह समाधान आधुनिक ब्राउज़रों के साथ अप्रचलित है।
साइमन_वेक

0

ऑनरर इवेंट

* अद्यतन अगस्त 2017: onerror क्रोम और फ़ायरफ़ॉक्स द्वारा निकाल दिया गया है। onload इंटरनेट एक्सप्लोरर द्वारा निकाल दिया जाता है। एज न तो ऑनरर और न ही ऑनलोड। मैं इस विधि का उपयोग नहीं करूंगा, लेकिन यह कुछ मामलों में काम कर सकता है। यह सभी देखें

<link> onerror IE में काम नहीं करता है

*

परिभाषा और उपयोग एक बाहरी फ़ाइल (जैसे एक दस्तावेज़ या एक छवि) को लोड करते समय यदि कोई त्रुटि होती है, तो ऑनरोर घटना चालू हो जाती है।

युक्ति: जब ऑडियो / वीडियो मीडिया पर उपयोग किया जाता है, तो संबंधित घटनाएं जो तब होती हैं जब मीडिया लोड करने की प्रक्रिया में किसी प्रकार की गड़बड़ी होती है, ये हैं:

  • onabort
  • onemptied
  • onstalled
  • onsuspend

HTML में:

तत्व onerror = "myScript">

जावास्क्रिप्ट में , addEventListener () विधि का उपयोग कर:

object.addEventListener ("त्रुटि", myScript);

नोट: AddEventListener () विधि Internet Explorer 8 और पुराने संस्करणों में समर्थित नहीं है।

उदाहरण छवि लोड करते समय त्रुटि होने पर जावास्क्रिप्ट निष्पादित करें:

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.