link标签不支持onerror事件,css加载失败静默无提示;应改用preload+onerror探测,配合禁用link启用与fallback.css内联方案实现容灾。

link 标签本身不支持 onerror 回调,强行写上也不会触发——这是最常踩的坑。浏览器对 CSS 加载失败是静默处理的,link.onerror 在 Chrome、Firefox、Safari 中均被忽略,只有 preload 支持可靠的 onerror 事件。
为什么 link rel="stylesheet" 的 onerror 不生效
CSS 加载不走 JavaScript 错误传播机制,也不抛异常,更不会触发 DOM 元素的 error 事件。它只是“没加载”,页面照常渲染,控制台通常零提示。你写的 <link rel="stylesheet" href="x.css" onerror="alert(1)"> 永远不会弹窗。
- 规范层面:HTML 标准未定义
link[rel=stylesheet]的 error 事件语义 - 实现层面:所有主流浏览器都跳过该监听,连
addEventListener('error', ...)都无效 - 替代方案必须绕开
link直接加载,改用preload做探测
用 preload + onerror 实现真实容灾
核心思路是:先预加载资源并监听成败,成功则启用正式 link,失败则切换备用地址。这要求两步配合,缺一不可:
- 第一步:
<link rel="preload" as="style" href="https://cdn.a/main.css" onload="enableMainCSS()" onerror="loadFallback()"> - 第二步:
<link id="main-css" rel="stylesheet" href="https://cdn.a/main.css" disabled> -
enableMainCSS()中执行document.getElementById('main-css').disabled = false -
loadFallback()中可设document.getElementById('main-css').href = '/css/fallback.css'再启用
注意:preload 必须带 as="style",否则浏览器不识别为样式资源,onload/onerror 不会按预期触发。
fallback.css 必须满足三个硬性条件
回退样式不是随便找个本地文件就行,它得扛住首次渲染和后续降级场景:
- 文件体积要小(建议 ≤2KB),避免二次加载延迟导致 FOUC(Flash of Unstyled Content)
- 不能含
@import或外部字体/图片链接,否则 fallback 本身也会静默失败 - 最好内联进 HTML 的
<style></style>标签里,彻底规避请求环节 —— 尤其在弱网或 DNS 失败时更可靠
例如:<style id="fallback-style">body{margin:0;padding:16px;font-family:sans-serif;}</style>……
IE 和旧安卓 WebView 需单独兜底
preload 在 IE 完全不支持,在 Android 4.4–6.0 的 WebView 中行为不稳定。如果目标用户包含这类环境,必须加一层检测:
- 用
document.createElement('link').relList.supports('preload')判断是否可用 - 不可用时,直接启用本地
fallback.css或内联样式,跳过 CDN 尝试 - 不要试图 polyfill
preload,成本高且不可靠;降级逻辑越早执行越好
真正容易被忽略的是 fallback 的“自包含性”——哪怕 CDN 挂了、DNS 污染了、甚至整个外网断了,fallback.css 里的每一条规则都得能独立生效,不依赖任何外部响应。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











