脚本加载失败重试机制

概述

前端脚本资源加载的时候可能会出错,特别是cdn资源,因此我们可以写一个js资源加载失败的重试机制,根据备用域名依次加载资源,最大程度提高用户体验。

效果

问题点

  1. 什么时间重试?

    在script加载事件出错的时候进行事件拦截处理

  2. 如何重试?

通过全局Err事件监听,然后根据script加载出错处理

  1. script插入方式?

通过document.write(会阻塞页面保证脚本顺序)插入最新的脚本请求到页面,注意:如果js加载过程中,严格区分前后加载顺序就不能动态创建script的形式重试

实现

html 复制代码
<!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 backupsDomain = [
            "https://cdn.bootcdn.newt",
            "https://cdnjs.cloudflare.com",
            "https://cdn.bootcdn.net",
        ]


        const nextDomain = {}

        window.addEventListener("error", (e) => {
            if (e.target.tagName === "SCRIPT") {
                const target = new URL(e.target.src)
                const pathName = target.pathname
                if (nextDomain[pathName] >= backupsDomain.length) {
                    console.log("所有域名均不可用")
                    return
                }
                if (!nextDomain[pathName]) {
                    nextDomain[pathName] = 0
                }
                const index = nextDomain[pathName]
                const domain = backupsDomain[index]
                const newUrl = new URL(domain + target.pathname + target.search);

                console.log("target", newUrl)
                // 方式1(不区分顺序可以用这种)
                const script = document.createElement("script")
                script.src = newUrl.toString()
                // e.target.parentElement.insertBefore(script, e.target)
                // 方式2(严格按照页面js脚本引入顺序加载)
                document.write(`\<script src="${newUrl.toString()}"><\/script>`)
                e.target.remove()
                nextDomain[pathName]++

            }
        }, true)
    </script>
</head>

<body>
    <script src="https://cdn.bootcdn.net1/ajax/libs/vue/3.5.20/vue.global.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/socket.io/4.8.1/socket.io.min.js"></script>

    <div id="app"></div>
    <script>
        console.log("结束", Vue)

        Vue.createApp({
            data() {
                return {
                    message: 'Hello Vue!',
                    count: 0
                }

            },
            methods: {
                test() {
                    console.log("test")
                    this.count++
                    this.message = 'Button clicked ' + this.count + ' times.'
                }
            },
            template: `<div @click="test">{{ message }}</div>`
        }).mount('#app')
    </script>

</body>

</html>

注意

document.write() 是 JavaScript 中用于向文档写入内容的方法,支持插入文本、HTML 标签或 JavaScript 代码。以下是其核心要点及使用场景:

核心功能

  • 写入内容‌:接受字符串参数(如文本、HTML 或 JavaScript 代码),并将其插入到文档流中。 ‌
  • 应用场景‌:动态生成页面内容、注入脚本、测试调试等。 ‌

注意事项

  • 页面加载期间使用‌:仅在页面加载过程中有效,若在文档加载完成后使用会导致整个页面内容被清空。 ‌
  • 阻塞解析‌:同步操作会阻塞页面解析,不建议用于异步加载或页面加载完成后。 ‌
  • 内容覆盖‌:会覆盖原有内容,需谨慎使用以避免意外覆盖重要信息。 ‌
相关推荐
人工智能训练11 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪11 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi92212 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin12332213 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头882114 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas13614 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠14 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
2601_9498333915 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
珑墨15 小时前
【Turbo】使用介绍
前端
军军君0116 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three