cdn的加载有时候因为第三方的服务出问题,造成项目加载不了对应js,导致项目出问题。
解决方案:将错误的cdn地址替换为备用cdn地址。
项目结构
demo
--index.html
--js/a.js
--js/b.js
a.js
console.log("a.js");
b.js
console.log("b.js");
index.html 。此版本有js加载顺序的问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
const domains = ["cdn.jsdelivr.n", "cdn.jsdelivr.ne", "cdn.jsdelivr.net"];
const retry = {};
window.addEventListener(
"error",
(e) => {
if (e.target.tagName !== "SCRIPT" || e instanceof ErrorEvent) {
return;
}
const url = new URL(e.target.src);
const name = url.pathname;
if (!(name in retry)) {
retry[name] = 0;
}
const index = retry[name];
if (index >= domains.length) {
return;
}
const newDomain = domains[index];
const script = document.createElement("script");
url.host = newDomain;
script.src = url.toString();
document.body.insertBefore(script, e.target);
retry[name]++;
},
true
);
</script>
</head>
<body>
<script src="./js/a.js"></script>
<script src="https://xxxx/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script src="./js/b.js"></script>
</body>
</html>
期望的执行顺序应该是 a.js -> echarts.min.js -> c.js。但是以下的执行顺序是
- a.js 加完完毕
- echarts.min.js 报错重试,失败
- b.js 加完完毕
- echarts.min.js 再次报错重试,失败
- echarts.min.js 再次报错重试,成功
所以最后的执行顺序是 a.js -> b.js ->echarts.min.js
同步执行最重要的是使用document.write。
解决方案如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
const domains = ["cdn.jsdelivr.n", "cdn.jsdelivr.ne", "cdn.jsdelivr.net"];
const retry = {};
window.addEventListener(
"error",
(e) => {
if (e.target.tagName !== "SCRIPT" || e instanceof ErrorEvent) {
return;
}
const url = new URL(e.target.src);
const name = url.pathname;
if (!(name in retry)) {
retry[name] = 0;
}
const index = retry[name];
if (index >= domains.length) {
return;
}
const newDomain = domains[index];
url.host = newDomain;
document.write(`\<script src="${url}">\<\/script>`);
retry[name]++;
},
true
);
</script>
</head>
<body>
<script src="./js/a.js"></script>
<script src="https://xxxx/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script src="./js/b.js"></script>
</body>
</html>
- 期望的执行顺序应该是 a.js -> echarts.min.js -> c.js
- 实际的执行顺序应该是 a.js -> echarts.min.js -> c.js