iframe 不支持原生 onerror 属性,需用 load 事件加超时兜底或 window.error 捕获同源 JS 错误;重试须清理定时器和监听器;跨域 iframe 加载失败无法可靠检测。

iframe 的 onerror 为什么根本不会触发
iframe 标签**不支持原生 onerror 属性**,这是最常被误用的点。写 完全无效——浏览器会忽略该属性,既不报错也不执行。它不像 或 <script></script> 那样有标准化的加载失败事件钩子。
真正能捕获 iframe 加载失败的两种方式
必须绕过 onerror 这个伪方案,改用以下任一可靠路径:
-
监听
load+ 超时兜底:iframe加载成功必触发load;若超时未触发,则大概率失败(如 404、跨域拒绝、DNS 失败)。需手动设setTimeout并在load触发时清除。 -
全局
window.addEventListener('error', ...)捕获:仅对同源iframe内 JS 报错有效,且需配合try/catch或window.onerror在子页面内主动上报;对加载层面失败(如 HTML 404)无能为力。
避免 onload + timeout 逻辑陷入无限重试
常见错误是:检测到超时后直接 iframe.src = newUrl,却不清理旧的 timeout 和 load 监听器,导致多次重试叠加,内存泄漏甚至重复插入相同内容。
正确做法是每次重试前先清理:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 用
iframe._loadTimer或data-timer-id存储当前 timeout ID - 在重试前调用
clearTimeout(iframe._loadTimer) - 用
iframe.removeEventListener('load', handler)移除旧监听(或每次用新函数绑定,避免重复) - 重试次数应按
iframe.src的pathname计数,而非全局计数
跨域 iframe 的失败检测本质不可靠
当 iframe 指向不同源时,父页面无法读取其 contentDocument、无法监听其 load 是否完成(部分浏览器会静默失败)、也无法通过 document.readyState 判断状态。此时所谓“检测失败”只能靠间接信号:
- 设置固定宽高 + 占位文字,视觉上不白屏
- 用
postMessage要求子页主动上报就绪状态,失败则不响应 - 服务端返回的 fallback 页面(如
404.html)内嵌一段parent.postMessage('ready'),作为最小可行性确认
不要试图用 iframe.contentWindow.location.href 或 iframe.contentDocument 去判断——跨域下它们要么抛 SecurityError,要么返回空值,无法区分“加载中”和“加载失败”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










