onerror本身不自动重试,需手动实现带计数限制、退避延迟和缓存规避的安全重试逻辑,避免无限循环与资源浪费。

onerror 事件本身不会自动循环,必须手动控制重试逻辑
浏览器原生的 onerror 只在资源加载失败时触发一次,它不是轮询机制,也不会自动重试。所谓“用计数器控制循环”,本质是:监听失败 → 手动修改 src/href → 触发新加载 → 再次监听。关键在于避免无限递归和资源浪费。
如何安全实现带计数限制的图片重试
常见于 CDN 图片加载不稳定、临时 404 或跨域拒绝场景。直接在 onerror 里反复赋值 src 极易陷入死循环(比如网络彻底不通时)。
- 必须用闭包或 data 属性保存当前重试次数,不能依赖全局变量(多个图片会互相干扰)
- 每次重试应加退避延迟(如
setTimeout),否则瞬间打满请求 - 重试前检查是否已达上限,达到后应停止并可 fallback 到占位图或提示
- URL 需带时间戳或随机参数(如
?t=1712345678),否则浏览器可能直接返回缓存的失败响应
示例:
https://cdn.example.com/photo.jpg?t=${timestamp}
script 标签的 onerror 不能靠 src 循环重试
<script onerror="..." src="..."></script> 的 onerror 触发后,再次设置 src 不会重新执行脚本加载流程(多数浏览器会忽略)。这是容易踩的坑——你以为能重试,其实只是静默失败。
- 正确做法是动态创建
<script></script>元素,并在onerror回调中新建一个 - 必须清除旧的
onerror绑定,否则多次重试后回调堆积 - 注意 CSP 策略可能阻止内联脚本或动态创建 script,需提前配置
script-src 'self' 'unsafe-inline'
CSS @import 和 link rel="stylesheet" 的错误不可捕获
HTML 中的 和 CSS 内的 @import **没有 onerror 事件支持**,即使写了也不会触发。这是规范限制,不是浏览器 bug。
- 无法用计数器做 CSS 加载重试
- 可行替代:用
fetch()预加载 CSS 文本,成功后再注入;失败则走 JS 降级逻辑 - 若必须依赖 link 标签,只能靠服务端兜底(如 Nginx 返回 200 空 CSS)或监控日志人工介入
真正难处理的从来不是怎么写循环,而是判断「该不该重试」——网络超时?权限拒绝?路径永久失效?计数器只解决表象,背后得结合状态码、响应头或业务语义做决策。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











