Javascript:检测何时无法通过src添加iframe

SRo*_*mes 5 javascript error-handling iframe

给定的第三方脚本在一定条件下会向DOM添加一个iframe。如果iframe正确加载,则说明一切完成。但是,有时,该iframe的src会导致404,网络超时或其他错误。第三方脚本无法正常处理。

我想在我的脚本中对此进行监视,并且每当iframe加载失败时,都会触发我的脚本。有什么办法吗?它看起来像这样:

function callWhenElementFails(element) {
   if (element is_a iframe)
        invoke_my_handler;
   else
        do nothing
}
Run Code Online (Sandbox Code Playgroud)

一个简单的问题:给定一个iframe元素,我如何检查它是否已加载或失败?我可以在开发人员工具的“网络”标签下看到src失败;如何以编程方式查询此内容。

请注意,我的代码不是加载iframe的代码,并且很难修改第三方代码并向其中添加一些内容。

检测iframe src是否是可显示的抓斗,并且存在类似的问题,但不能成功。

突变观察者可能是一种方法,尽管我希望更简单的方法会更好。

Mas*_*son 3

function badIframe(iframe) {
    return new Promise(resolve => {
        // This uses the new Fetch API to see what happens when the src of the iframe is fetched from the webpage.
        // This approach would also work with XHR. It would not be as nice to write, but may be preferred for compatibility reasons.
        fetch(iframe.src)
            .then(res => {
                // the res object represents the response from the server

                // res.ok is true if the repose has an "okay status" (200-299)
                if (res.ok) {
                    resolve(false);
                } else {
                    resolve(true);
                }

                /* Note: it's probably possible for an iframe source to be given a 300s
                status which means it'll redirect to a new page, and this may load
                property. In this case the script does not work. However, following the
                redirects until an eventual ok status or error is reached would be much
                more involved than the solution provided here. */
            })
            .catch(()=> resolve(true));
    });
}

new MutationObserver(async records => {
    // This callback gets called when any nodes are added/removed from document.body.
    // The {childList: true, subtree: true} options are what configures it to be this way.

    // This loops through what is passed into the callback and finds any iframes that were added.
    for (let record of records) {
        for (let node of record.addedNodes) {
            if (node.tagName === `IFRAME` && await badIframe(node)) {
                // invoke your handler
            }
        }
    }
}).observe(document.body, {childList: true, subtree: true});
Run Code Online (Sandbox Code Playgroud)