背景:一次 CDN 故障引发的线上问题
最近接到客户反馈,系统部分功能无法使用。排查后发现是项目中引用的公共 JS 工具类加载失败。该资源托管在某个 CDN 节点上,由于节点故障导致资源不可用,进而影响了页面交互。
JS 文件加载失败在前端开发中并不罕见,特别是在弱网环境或依赖第三方服务时。既然定位了问题,我们就需要一套健壮的兜底机制。
原因分析
为什么会出现 JS 加载失败?网络请求本身具有不确定性,常见原因包括:
- 网络波动:用户侧网络不稳定,请求超时。
- CDN 故障:特定节点宕机,返回 404 或服务不可用。
- 缓存污染:浏览器或代理服务器缓存了错误的资源版本。
这些问题很难完全避免,但我们可以从代码层面构建容错能力。
核心策略
面对加载失败,核心思路有两个方向:
- 自动重试:当首次加载失败时,尝试再次发起请求。
- 多源备份:准备多个 CDN 地址,主地址失效时自动切换备用源。
实现:基础重试机制
我们利用 script 标签动态加载资源,并监听 onerror 事件来实现重试逻辑。这里封装了一个通用的 loadScript 函数。
function loadScript(url, options = {}) {
const { maxRetry = 3, timeout = 5000 } = options;
let attempt = 0;
return new Promise((resolve, reject) => {
const load = () => {
attempt++;
const script = document.createElement("script");
// 添加时间戳参数防止缓存干扰重试
script.src = url + (url.includes("?") ? "&" : "?") + "retry=" + attempt;
script.async = true;
let timer = ( {
script.();
(attempt < maxRetry) {
.();
();
} {
( ());
}
}, timeout);
script. = {
(timer);
();
};
script. = {
(timer);
script.();
(attempt < maxRetry) {
.();
();
} {
( ());
}
};
..(script);
};
();
});
}


