在 Javascript 中检测图像 404

IT技术 javascript jquery cross-browser dom-events
2021-03-18 18:22:15

在用户上传文件后,我们必须对图像进行一些额外的处理,例如调整大小并上传到 S3。这最多可能需要 10 秒的额外时间。显然,我们在后台执行此操作。但是,我们希望立即向用户显示结果页面,并简单地显示旋转器,直到图像在 s3 上到达他们的永久主页。

我正在寻找一种方法来检测某个图像无法以跨浏览器的方式正确加载(404)。如果发生这种情况,我们希望使用 JS 在它的位置显示一个微调器并每隔几秒钟重新加载图像,直到它可以从 s3 成功加载。

6个回答

处理<img>元素的onerror事件。

@xal:请务必设置属性之前挂钩该error事件(如果您使用而不是通过 HTML 字符串执行此操作)。否则,您将处于竞争状态,并且事件可能会在您开始处理之前触发(就像事件一样)。srcnew Imagedocument.createElement("img")load
2021-04-26 18:22:15
Javascript 运行在 Javascript 线程上,在某些浏览器上它也是 UI 线程。它不一定是下载线程。我已经帮助人们修复了由此引起的错误,src在设置load处理程序之前进行设置那里有一个竞争条件。如果您已经注册了处理程序,则一旦 JS 线程可以执行其他操作,事件处理代码就会将其放在执行堆栈中以运行。如果你不这样做,你可能会错过这次活动。
2021-04-28 18:22:15
2021-04-28 18:22:15
我想对此发表评论,尽管它在这一点上有些过时,只是因为它是一个非常受欢迎的问题和答案。如果 an<img>返回 a 404,但响应包含图像(例如占位符图像),error不会触发事件
2021-05-04 18:22:15
@TJ:不一定。Javascript 在 UI 线程上运行,因此如果您在设置后立即处理该事件src,应该不会有任何风险。不过你还是对的
2021-05-16 18:22:15

第一个选项:

<img src="picture1.gif" onerror="this.onerror=null;this.src='missing.gif';"/>

第二种选择:

<html>
<head>
<script type="text/javascript">
    function ImgError(source){
        source.src = "/noimage.gif";
        source.onerror = "";
        return true;
    }
</script>
</head>
<body>
    <img src="image_example1.jpg" onerror="ImgError(this)" />
</body>
</html>

PS:它是纯javascript!你不需要任何图书馆。(香草JS)

Fiddle 中的示例

https://jsfiddle.net/dorathoto/8z4Ltzp8/71/

继续前进,为“第一选择”。所以非常轻巧,切中要害。
2021-05-07 18:22:15
@tonejac 是的..但是如果你想放入所有图像,我推荐第二个选项,保存最后的代码行和 kb。
2021-05-21 18:22:15

来自:http : //lucassmith.name/2008/11/is-my-image-loaded.html

// First a couple helper functions
function $(id) {
    return !id || id.nodeType === 1 ? id : document.getElementById(id);
}
function isType(o,t) {    return (typeof o).indexOf(t.charAt(0).toLowerCase()) === 0;}

// Here's the meat and potatoes
function image(src,cfg) {    var img, prop, target;
    cfg = cfg || (isType(src,'o') ? src : {});

    img = $(src);
    if (img) {
        src = cfg.src || img.src;
    } else {
        img = document.createElement('img');
        src = src || cfg.src;
    }

    if (!src) {
        return null;
    }

    prop = isType(img.naturalWidth,'u') ? 'width' : 'naturalWidth';
    img.alt = cfg.alt || img.alt;

    // Add the image and insert if requested (must be on DOM to load or
    // pull from cache)
    img.src = src;

    target = $(cfg.target);
    if (target) {
        target.insertBefore(img, $(cfg.insertBefore) || null);
    }

    // Loaded?
    if (img.complete) {
        if (img[prop]) {
            if (isType(cfg.success,'f')) {
                cfg.success.call(img);
            }
        } else {
            if (isType(cfg.failure,'f')) {
                cfg.failure.call(img);
            }
        }
    } else {
        if (isType(cfg.success,'f')) {
            img.onload = cfg.success;
        }
        if (isType(cfg.failure,'f')) {
            img.onerror = cfg.failure;
        }
    }

    return img;
}

以及如何使用它:

image('imgId',{
    success : function () { alert(this.width); },
    failure : function () { alert('Damn your eyes!'); },
});

image('http://somedomain.com/image/typooed_url.jpg', {
    success : function () {...},
    failure : function () {...},
    target : 'myContainerId',
    insertBefore : 'someChildOfmyContainerId'
});
这提出了一个很好的观点。您 (OP) 需要使用随机查询字符串参数加载图像。
2021-04-21 18:22:15
链接失效了。应修改此答案以包含内容或取消其绿色勾号。
2021-05-11 18:22:15
如果请求返回 HTTP 404 和后备图像,这将不起作用
2021-05-11 18:22:15
我会将 isType 函数更改为简单的typeof cfg.x==='function'. 它比“f”更具可读性,而且速度更快 - 请参见此处:jsperf.com/typeof-variations
2021-05-15 18:22:15
吻(又名保持超级简单)
2021-05-19 18:22:15

只需在错误事件上绑定 attr 触发器。

$(myimgvar).bind('error',function(ev){
    //error has been thrown
    $(this).attr('src','/path/to/no-artwork-available.jpg');
}).attr('src',urlvar);
OP专门说404。
2021-04-22 18:22:15
这假设所有失败的加载都是 404 的。
2021-05-08 18:22:15

这对我有用(我的是咖啡脚本)。当然,您需要用微调器替换。

checkImages = ->
  $("img").each ->
    $(this).error ->
      $(this).attr("src", "../default/image.jpg")

$(document).on('page:load', checkImages)

我猜 javascript 等价物类似于

function checkImages() {
  $("img").each(function() {
    $(this).error(function() {
      $(this).attr("src", "../default/image.jpg");
    });
  });
};

$(document).on("page:load", checkImages);