捕获脚本标签404

Is it possible to catch <script type="text/javascript" src=".."> 404 with JavaScript so that I could correct src?

window.onerror doesn't seem to catch these.

重要的提示!该脚本是由第三方库动态添加到主体中的,因此我无法控制它。

It would be so nice if I could detect the script insertion or src setting and update it with correct src like I could do with image but I think it's not possible with script element?

  var NativeImage = window.Image;

  class MyImage {
    constructor (w, h) {
      var nativeImage = new NativeImage(w, h);

      var handler = {
        set: function (obj, prop, value) {
          if (prop === 'src') {
            return nativeImage[prop] = '/correct/image/path.jpg';
          }
          return nativeImage[prop] = value;
        },
        get: function (target, prop) {
          return target[prop];
        }
      };

      return new Proxy(nativeImage, handler);
    }
  }

  window.Image = MyImage;
评论
  • 妮听咱话
    妮听咱话 回复

    You can check the HTTP Status of your script src by sending a XMLHttpRequest: HTTP Status Code from URL in Javascript

    function getStatus(url) {
        var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
        if (request.readyState === 4){
           return request.status;
    };
        request.open("GET", url, true);
        request.send(); 
    } 
    
  • ncum
    ncum 回复

    You can detect the script's insertion with MutationObserver and add an error listener to the tag:

    // Your code (run this before the external script)
    new MutationObserver((mutations, observer) => {
      for (const mutation of mutations) {
        for (const node of mutation.addedNodes) {
          // Add additional checks here if needed
          // to identify if the script is the one added by the library
          if (node.nodeType === 1 && node.matches('script')) {
            node.addEventListener('error', () => {
              console.log('Script could not be loaded');
            });
            // Remove the observer, since its purpose is fulfilled
            observer.disconnect();
            return;
          }
        }
      }
    })
      // Watch for elements that are added as children to document.body:
      .observe(document.body, { childList: true });
    <script>
    // External script:
    window.addEventListener('DOMContentLoaded', () => {
      const script = document.createElement('script');
      script.src = 'doesntexist';
      document.body.appendChild(script);
    });
    </script>