在 Javascript 中检测图像 404

Posted

技术标签:

【中文标题】在 Javascript 中检测图像 404【英文标题】:Detecting an image 404 in Javascript 【发布时间】:2011-03-02 10:28:21 【问题描述】:

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

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

【问题讨论】:

IIRC,图像有一个错误事件...devguru.com/technologies/javascript/10916.asp 见***.com/questions/92720/… @Dorathoto 为什么要赏金?最赞成的答案是要走的路:***.com/questions/3019077/… 【参考方案1】:

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

【讨论】:

@xal: 请确保在设置src 属性之前 挂钩error 事件(如果您使用new Image 或@987654327 执行此操作@ 而不是通过 html 字符串)。否则,您将处于竞争状态,并且该事件可能会在您开始处理之前触发(就像 load 事件一样)。 @T.J:不一定。 Javascript 在 UI 线程上运行,因此如果您在设置 src 后立即处理事件,应该没有任何风险。不过,你还是对的, Javascript 在 Javascript 线程上运行,在一些浏览器上也是 UI 线程。它不一定是下载线程。我已经帮助人们修复了由此引起的错误,在设置load 处理程序之前设置src。那里有一个比赛条件。如果您已经注册了处理程序,则事件处理代码会将其放在执行堆栈上,以便在 JS 线程可用于执行其他操作时运行。如果你不这样做,你可能会错过这个活动。 代码示例:maisonbisson.com/post/12150/… 我想对此发表评论,尽管它在这一点上有些过时,仅仅是因为它是一个非常受欢迎的问题和答案。如果<img> 返回404,但响应中包含图像(例如占位符图像),则error 事件不会被触发。【参考方案2】:

第一个选项:

<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)

Fidler 中的示例

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

【讨论】:

摇滚,为“第一选择”。非常轻巧,而且很重要。 @tonejac 是的..但是如果你想放入所有图像,我推荐第二种选择,保存最后的代码行和 kb。【参考方案3】:

发件人: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)需要使用随机查询字符串参数加载图像。 链接失效。应修改此答案以包含内容或将其绿色勾去掉。 KISS(又名保持超级简单) 我会将 isType 函数更改为简单的typeof cfg.x==='function'。它比 'f' 更具可读性,而且速度更快 - 请参阅此处:jsperf.com/typeof-variations 如果请求返回 HTTP 404 和后备图像,这不起作用【参考方案4】:

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

$(myimgvar).bind('error',function(ev)
    //error has been thrown
    $(this).attr('src','/path/to/no-artwork-available.jpg');
).attr('src',urlvar);

【讨论】:

这假定所有失败的加载都是 404 的。 OP特意说404。【参考方案5】:

这对我有用(我的在 coffeescript 中)。当然,您需要用微调器替换。

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);

【讨论】:

【参考方案6】:

我刚刚做了

if ($('#img')[0].naturalWidth > 0) 

我注意到,如果图像 404'd,则没有 naturalWidth。

但是,我可以理解想要使用上述方法。

【讨论】:

以上是关于在 Javascript 中检测图像 404的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 图像 URL 验证

使用javascript进行图像模糊检测

javascript 简单的脚本,从可检测图像的文件名中删除尾随的“垃圾”

JavaScript 图像预加载和 403 错误

JavaScript 检测图像是否已加载

Javascript检测屏幕分辨率,更改css,相应裁剪图像