I would like to detect in a web page when some of its javascript or css elements have failed to load, and alert the user. I have the below but it does not work.
(The actual use-case involves end-users needing certain certificates installed and if elements fail to load, the page will give them instructions on how to update their browser/OS. But this is a minimum reproducible testcase on my way to that solution.)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lorum Title Ipsus</title>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
// Monitor <script> elements
document.querySelectorAll('script[src]').forEach(script => {
script.addEventListener('error', function() {
alert('Failed to load script:', script.src);
}, true);
});
// Monitor <link rel="stylesheet"> elements
document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
link.addEventListener('error', function() {
alert('Failed to load stylesheet:', link.href);
}, true);
});
});
</script>
<!-- **** NOTE THE OBVIOUS ERROR BELOW -->
<link href="https://ERRRORcdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</head>
<body>
Lorum Ipsus
</body>
</html>
For synchronous scripts, the DOMContentLoaded
event will fire only after they have been (attempted to be) loaded and evaluated, so you're missing the error
event.
You could try a mutation observer to detect the creation of the scripts and immediately attach your error handlers, or try to attach your error event
handlers on the window
or document
or document.head
itself (although it should not bubble).