javascript - 在 Firefox 中检测到 "image corrupt or truncated"

标签 javascript firefox canvas local-storage picturefill

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

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

在回调中,我通过 Canvas 将图像数据转换为 dataURL,这样我就可以将图像数据缓存在 localStorage 中,以便用户即使在离线时也可以使用。

注意关于“离线”的部分。这就是我不能依赖浏览器缓存的原因。而且 HTML5 离线应用程序缓存不能满足我的需求,因为图像是响应式的。 (有关响应式图像与 HTML 离线应用程序缓存不兼容的解释,请参见 "Application Cache is a Douchebag"。)

在 Mac 上的 Firefox 14.0.1 上,如果我将浏览器的大小调整到非常大,然后在大图像有机会完全加载之前再次将其调整回小的大小,加载图像将会触发。它最终会在 Firebug 控制台中报告“图像损坏或被 chop ”,但不会抛出异常或触发错误事件。没有迹象表明代码中有任何错误。就在 Firebug 控制台中。同时,它将 chop 的图像存储在 localStorage 中。

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

下面是我如何循环遍历 picturefill div 以查找已由 picturefill 插入的 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 已更改以保护有罪的人:

Image corrupt or truncated: http://www.example.com/pf/external/imgs/extralarge.png

最佳答案

似乎在更改 srcimg 的属性标记,Firefox 触发 load事件。这与 HTML5 规范相反,即 says如果更改了 src 属性,则应该结束任何其他已经在进行的提取(Firefox 会这样做),并且不应发送任何事件。 load仅当提取成功完成时才应发送事件。所以我会说你得到一个 load 的事实事件是 Firefox 错误。

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

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

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

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

关于javascript - 在 Firefox 中检测到 "image corrupt or truncated",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11928878/

相关文章:

javascript - 选择选项时延迟滚动到 Div ID

javascript - jQuery DatePicker,在 iOS 上隐藏数据类型日期

javascript - 如何更改两个div的内容 - canvas

javascript - 带有两个 jquery 下拉菜单的依赖过滤

twitter-bootstrap - Twitter Bootstrap 崩溃 - Firefox >= 15 的问题

firefox - 如何使用带有 node.js 的 Selenium WebDriver 最大化 firefox 浏览器窗口

javascript - svg-insertAdjacentHTML 不适用于 firefox 35 及以下版本?

javascript - 如何解决 HTML5 全屏模式下 Canvas 上鼠标指针的偏移问题?

javascript - 动态 Canvas 形状未填充颜色

javascript - 如何为标题背景图像 onload 事件设置动画?