Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect a script load of a file:// URL fails in Firefox?

I want to detect if a script tag (that was dynamically created and added to the DOM) fails to load. The onerror event works, except with file:// URLs in Firefox.

Unfortunately none of the techniques described here (except timeouts, which are unacceptable in my case) seem to work in Firefox if the src of the script tag is a file:// URL (or relative URL and the page was loaded via a file:// URL)

Test case:

var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', 'doesnotexist.js');
script.onerror = function() { alert("Loading failed!"); }
document.getElementsByTagName('head')[0].appendChild(script);

Load this in an HTML page with a file:// URL. The onerror event won't execute in Firefox. Load from a webserver, or on Safari or Chrome, and it will.

This seems like a bug to me. Is there any known way around it?

like image 815
tlrobinson Avatar asked Nov 11 '10 00:11

tlrobinson


2 Answers

var loadScript = function(scriptURL, failureCallback) {
    var script = document.createElement('script'),
        scriptProtocol = scriptURL.match(/^([a-zA-Z]+:)\/\//);
    script.setAttribute('type', 'text/javascript');

    if (navigator.product === 'Gecko' &&
        navigator.userAgent.indexOf('KHTML') === -1 &&
        window.location.protocol === 'file:' &&
        (!scriptProtocol || scriptProtocol[1] === 'file:')) {

        var req = new XMLHttpRequest();
        req.open('GET', scriptURL, true);
        req.onreadystatechange = function () {
            if (req.readyState === 4) {
                if (req.status === 0)
                    script.textContent = req.responseText;
                else
                    failureCallback();
            }
        };
        try {
            req.send(null);
        }
        catch (e) {
            failureCallback();
        }
    }
    else {
        script.setAttribute('src', scriptURL);
        script.onerror = failureCallback; 
    }

    document.getElementsByTagName('head')[0].appendChild(script);
};

loadScript('doesnotexist.js', function() { alert('Loading failed!'); });

Bit of a hack, but it seems to work.

like image 83
Paul Baumgart Avatar answered Nov 07 '22 07:11

Paul Baumgart


What if you used Pauls solution to retrieve the document but ignored the result. If it loads the create your script tag. The downside is the file would load twice.

like image 34
Terry Riegel Avatar answered Nov 07 '22 05:11

Terry Riegel