CDN 容灾
CDN(Content Delivery Network),即内容分发网络。
CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。
不同资源的容灾方案
JS
对于直接放在 HTML 中的 script 标签,可以通过 onerror 事件来捕获错误,并更换 src 属性为备用 HOST 的 URL。
<body>
<script>
function handleError(e) {
console.error('Script load failed', e.srcElement);
e.srcElement.src = /* 使用备用 HOST 的 URL */'';
}
</script>
<!-- 直接放在 HTML 中的 script 标签 -->
<script src="https://example.com/nonexistent-script.js" onerror="handleError(event)"></script>
</body>
<!-- 或者 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
scripts[i].addEventListener('error', function () {
console.error('Script load failed:', this.src)
this.src = /* 使用备用 HOST 的 URL */''
})
}
})
</script>对于动态插入的 JS 文件,可以通过 onerror 事件来捕获错误,并更换 src 属性为备用 HOST 的 URL。
function loadScript(url, callback) {
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = url
script.onload = function () {
callback(null) // 加载成功
}
script.onerror = function () {
script.src = /* 使用备用 HOST 的 URL */''
}
document.head.appendChild(script)
}
loadScript('https://example.com/script.js')CSS
同上面 JS 的容灾方案。
图片
同上面 JS 的容灾方案,支持 new Image() 的方式:
const OriginalImage = Image
// 重写 Image 构造函数
window.Image = function () {
const img = new OriginalImage()
img.onerror = function () {
// 更换 src 属性为备用 HOST 的 URL
this.src = /* 使用备用 HOST 的 URL */''
}
return img
}Ajax
针对于请求的重试,需要统一请求的方式,使用封装好的 axios 或者 fetch 请求,例如,在 axios,针对请求失败后更换域名的重试如下:
// 添加一个响应拦截器
instance.interceptors.response.use(null, (error) => {
const originalRequest = error.config
// 如果请求失败并且响应状态码为 500 或者 503
if (error.response.status === 500 || error.response.status === 503) {
// 更换域名
originalRequest.baseURL = 'https://new-domain.com'
// 重试请求
return instance(originalRequest)
}
return Promise.reject(error)
})CSS / Style 中的资源
例如字体,背景图等,思路为:
- 为 link 标签添加 crossorigin 属性,允许跨域资源可读;
- 定时轮询新增的样式表(document.stylesheets)
- 更换样式表中 url() 函数的CDN异常域名,在样式表尾部追加样式规则覆盖。