html本身无异常捕获机制,js可捕获的错误仅发生在可执行上下文(如脚本加载、dom操作、资源读取等);需在具体环节用对应方式拦截,而非给html加try-catch。

HTML 本身没有“异常捕获”机制——try-catch 对纯 HTML 标签无效,onerror 也不是万能开关。真正能被 JS 捕获的错误,只发生在可执行上下文中:脚本加载、DOM 操作、资源读取、网络请求、媒体解码等环节。关键不是“给 HTML 加 try”,而是明确哪一步会出错、在哪一层拦截。
哪些 HTML 相关操作实际会抛 JS 异常
浏览器不会因为写错一个 <div class="missing-quote 就报错,但以下场景会真实触发 JS 可捕获的异常:
document.getElementById(" nonexistent> 返回 <code>null,后续调用.innerText会抛TypeError-
new Audio("broken.mp3").play()在不支持格式或文件损坏时可能 reject Promise 或触发error事件(不是 throw) -
fetch("/api/data")网络失败或 500 响应不会 throw,但response.ok === false需手动检查 -
FileReader.readAsText(blob)出错时触发reader.onerror,而非抛出同步异常 -
import("./chunk.js")失败时 Promise reject,不是语法错误,需.catch() - JS 脚本执行期错误(
ReferenceError、TypeError) - 未处理的 Promise rejection(需配合
window.onunhandledrejection) - 静态资源加载失败(
<script src="404.js"></script>),但仅限同域或带crossorigin属性的跨域脚本 -
<img>:必须用img.onerror = () => { ... },window.onerror不触发 -
<video></video>:监听error事件,再读e.target.error.code判断是 404 还是解码失败 -
<link rel="stylesheet">:无标准 error 事件,可用link.onload/link.onerror(Chrome 支持,Firefox 需降级用document.styleSheets.length检查) -
<iframe></iframe>:监听load和error,但跨域 iframe 的error可能静默(受同源策略限制) - 后端渲染时做预校验(如用
parse5或cheerio检查模板输出) - 前端动态插入 HTML 时,用
DOMParser显式解析并检查parsererror:const parser = new DOMParser();<br>const doc = parser.parseFromString(htmlString, "text/html");<br>if (doc.querySelector("parsererror")) {<br> console.warn("HTML 解析警告,存在 malformed 结构");<br>} - 避免用
innerHTML = "<script>..."</script>插入含脚本的字符串——脚本会执行,但错误仍归入window.onerror,且上下文丢失
window.onerror 能捕获什么,不能捕获什么
window.onerror 是最常被误用的“全局兜底”。它只能捕获三类同步/异步错误:
它无法捕获:<img src="404.jpg"> 的加载失败(要用 img.onerror)、<video></video> 解码错误(要用 video.addEventListener("error"))、fetch 的 HTTP 错误状态(要检查 response.status)。
资源类错误必须绑定到具体元素实例
HTML 元素自身不抛 JS 异常,但多数内置资源加载器提供了事件接口。依赖全局监听等于放弃精准定位:
HTML 解析错误根本不在 JS 执行层
服务端返回的 HTML 如果有严重语法错误(如未闭合 <script></script>),浏览器会按容错规则自动修复,不会向 JS 抛异常。你无法在前端“捕获 HTML 解析失败”。唯一可控点是:
真正容易被忽略的是:很多你以为的“HTML 错误”,其实是网络请求失败、CSP 拦截、MIME 类型不匹配(比如服务器返回 text/plain 却当 JS 加载)或 CORS 阻断——这些都得靠对应层级的机制去发现,而不是指望 HTML 自己报错。











