在火狐中检测“图像损坏或截断”

Detect "image corrupt or truncated" in Firefox

本文关键字:损坏 图像 火狐 检测      更新时间:2023-09-26

(先发制人的罢工:如果您想将其标记为重复项,请注意,其他问题似乎在问"为什么我会收到此错误?我知道为什么我会收到此错误;我想知道如何检测JavaScript代码中的错误。它只出现在Firebug控制台中,当然,在加载图像时对用户来说是显而易见的。

我正在使用图片填充响应式图像。我有一个为图像上的加载事件触发的回调。因此,每次有人调整浏览器窗口的大小以便通过图片填充加载不同的图像时,回调都会运行。

在回调中,我通过画布将图像数据转换为 dataURL,以便我可以将图像数据缓存在本地存储中,以便用户即使在离线时也可以使用它。

请注意有关"离线"的部分。这就是为什么我不能依赖浏览器缓存的原因。HTML5离线应用程序缓存不能满足我的需求,因为图像是响应式的。(有关响应式图像与 HTML 脱机应用程序缓存不兼容的说明,请参阅"应用程序缓存是一个 Douchebag"。

在 Mac 上的 Firefox 14.0.1 上,如果我将浏览器大小调整为非常大的内容,然后在大图像有机会完全加载之前再次将其大小调整为小大小,加载图像将触发。它最终会在 Firebug 控制台中报告"映像损坏或截断",但不会引发异常或触发错误事件。没有迹象表明代码中有任何错误。就在Firebug控制台中。 同时,它将截断的图像存储在本地存储中。

如何在 JavaScript 中可靠有效地检测此问题,以便不缓存该图像?

以下是我如何遍历图片填充div以查找图片填充插入的img标签:

    var errorLogger = function () {
        window.console.log('Error loading image.');
        this.removeEventListener('load', cacheImage, false);
    };
    for( var i = 0, il = ps.length; i < il; i++ ){
        if( ps[ i ].getAttribute( "data-picture" ) !== null ){
            image = ps[ i ].getElementsByTagName( "img" )[0];
            if (image) {
                if ((imageSrc = image.getAttribute("src")) !== null) {
                    if (imageSrc.substr(0,5) !== "data:") {
                        image.addEventListener("load", cacheImage, false);
                        image.addEventListener('error', errorLogger, false);
                    }
                }
            }
        }
    }

以下是cacheImage()回调的样子:

var cacheImage = function () {
    var canvas,
        ctx,
        imageSrc;
    imageSrc = this.getAttribute("src");
    if ((pf_index.hasOwnProperty('pf_s_' + imageSrc)) ||
        (imageSrc.substr(0,5) === "data:") ||
        (imageSrc === null) || (imageSrc.length === 0)) {
            return;
    }
    canvas = w.document.createElement("canvas");
    canvas.width = this.width;
    canvas.height = this.height;
    ctx = canvas.getContext("2d");
    ctx.drawImage(this, 0, 0);
    try {
        dataUri = canvas.toDataURL();
    } catch (e) {
        // TODO: Improve error handling here. For now, if canvas.toDataURL()
        //   throws an exception, don't cache the image and move on.
        return;
    }
    // Do not cache if the resulting cache item will take more than 128Kb.
    if (dataUri.length > 131072) {
        return;
    }
    pf_index["pf_s_"+imageSrc] = 1;
    try {
        localStorage.setItem("pf_s_"+imageSrc, dataUri);
        localStorage.setItem("pf_index", JSON.stringify(pf_index));
    } catch (e) {
        // Caching failed. Remove item from index object so next cached item
        //   doesn't wrongly indicate this item was successfully cached.
        delete pf_index["pf_s_"+imageSrc];
    }
};

最后,以下是我在Firebug中看到的全文,其中URL已更改以保护有罪者:

映像损坏或截断:http://www.example.com/pf/external/imgs/extralarge.png

似乎在更改img标签的src属性时,Firefox 会触发一个load事件。这与HTML5规范相反,HTML5规范规定,如果src属性被更改,那么任何其他已经在进行的获取都应该结束(Firefox就是这样做的),并且不应该发送任何事件。仅当提取成功完成时,才应发送 load 事件。所以我想说的是,你得到一个load事件的事实是一个火狐错误。

但是,图像应该知道它是否完全可用,您可以尝试使用 complete 属性:

if (this.complete === false) {
  return;
}

不幸的是,Firefox this.complete设置为true,所以这也不是一个选择。

最好的选择可能是在每次要更改src属性时创建一个新的<img>元素。

我自己今天对这个问题目瞪口呆。 一切都工作正常(图像按预期直观加载),除了错误不断出现在Firefox错误控制台中 - IE或Chrome中没有此类错误。

就我而言,我将图像插入一个完整的 jquery 处理程序中带有 innerHtml 的div。 当我抢占 jquery 调用时,错误停止了:

var image_holder = new Image();
image_holder.src = img_path;//path of image that's going to be plugged in  

它对我有用,但仍然没有意义。我认为这与时间有关,因为此代码在到达实际将其插入页面的代码之前启动要加载的图像。