如何捕获返回占位图的img 404错误且无需额外发起HTTP请求
服务器返回404但附带占位图的加载状态判断方案
首先明确结论:浏览器的img元素本身没有暴露对应HTTP请求的状态码属性,因此没有完全无开销的原生API可以直接判定该类加载异常。error事件仅会在资源无法被解析为有效图片格式时触发,服务器404状态下返回的有效占位图会触发load事件而非error事件,因此无法通过原有方案监听。
以下是不需要额外发起HTTP请求的实现方案,尤其适配你提到的YouTube缩略图场景:
方案1:图片尺寸校验(性能最优)
如果服务端返回的默认占位图尺寸和正常业务图片尺寸完全不同,可以在load事件中读取图片的真实宽高做对比,匹配则判定为返回了占位图:
const fallbackImageUrl = 'https://via.placeholder.com/320x180'; const images = document.body.querySelectorAll('img'); for (const img of images) { img.addEventListener('error', function() { this.src = fallbackImageUrl; }); img.addEventListener('load', function() { // 仅校验YouTube域名的缩略图,可根据需求调整 if (this.src.includes('ytimg.com')) { // 示例值:YouTube无效缩略图返回的占位图宽高为120*90,可自行实测准确值替换 if (this.naturalWidth === 120 && this.naturalHeight === 90) { this.src = fallbackImageUrl; } } }); }
对应HTML需要给YouTube域名的图片添加crossorigin="anonymous"属性避免跨域限制:
<p>正常可加载的图片:</p> <img src="https://www.example.com/valid-image.jpg" /> <p>404但返回占位图的YouTube缩略图:</p> <img src="https://i1.ytimg.com/vi/blahblah/mqdefault.jpg" crossorigin="anonymous" />
方案2:像素特征校验(准确率最高)
如果占位图和正常图片尺寸一致,可以通过Canvas读取图片固定位置的像素特征,和预先统计的占位图像素值匹配判断:
// 预先统计的YouTube默认占位图特征像素,可自行采集多个点位提高准确率 const YOUTUBE_FALLBACK_FEATURE = [ {x: 10, y: 10, rgba: [246, 246, 246, 255]}, {x: 160, y: 90, rgba: [221, 221, 221, 255]} ]; const fallbackImageUrl = 'https://via.placeholder.com/320x180'; const images = document.body.querySelectorAll('img'); for (const img of images) { img.addEventListener('error', function() { this.src = fallbackImageUrl; }); img.addEventListener('load', function() { if (!this.src.includes('ytimg.com')) return; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = this.naturalWidth; canvas.height = this.naturalHeight; ctx.drawImage(this, 0, 0); let isFallback = true; for (const point of YOUTUBE_FALLBACK_FEATURE) { const pixel = ctx.getImageData(point.x, point.y, 1, 1).data; if (pixel[0] !== point.rgba[0] || pixel[1] !== point.rgba[1] || pixel[2] !== point.rgba[2] || pixel[3] !== point.rgba[3]) { isFallback = false; break; } } if (isFallback) { this.src = fallbackImageUrl; } }); }
该方案的缺点是需要处理跨域画布污染问题,YouTube的缩略图默认支持跨域访问,仅需要给img元素添加crossorigin="anonymous"属性即可正常使用。
如果你的场景不涉及固定特征的服务端占位图,没有通用的无额外请求的解决方案,只能通过单独发起HTTP请求读取状态码判断。
内容的提问来源于stack exchange,提问作者Quangdao Nguyen
相关产品推荐
相关产品推荐

