js脚本加载失败问题解决办法

 更新时间:2023年06月08日 11:54:42   作者:H5前端练习生  
在项目中经常会用到动态加载js,下面这篇文章主要给大家介绍了关于js脚本加载失败问题的解决办法,文中通过实例代码介绍的非常详细,对大家学习或者使用js具有一定的参考学习价值,需要的朋友可以参考下

当我们在运行某一个项目时,它的某些JavaScript脚本可能加载不出来,报错。 像现在单页界面应用基本上都是通过js来构建,一旦加载不出,这个项目就不能运行了,那怎么办?我们如何解决这个问题?

这里采用的方案是,重新加载JavaScript脚本。那么什么时候去重新加载js,如何重新加载js?在js脚本加载不出来时,就需要去重试加载。那我们怎么知道js有没有加载失败,我们可以在<script src="https://cdn.topskys.org/v0/loadjs.js"></script>标签上添加一个监听加载失败的事件 οnerrοr="console.log('error')",当出现错误会触发onerror事件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script onerror="console.log('error')" src="https://cdn.topskys.org/v0/loadjs.js"></script>
</body>
</html>

 可以看到,当加载js出现错误时,onerror监听到了错误。但是在工程化的环境,这些<script></script>标签元素都是自动生成的,给这些标签添加上onerror事件,这种方式又特别麻烦。我们可以给整个window添加error监听事件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="https://cdn.topskys.org/v0/loadjs.js"></script>
    <script>
        window.addEventListener("error",e=>{
            console.log("error loading")
        });
    </script>
</body>
</html>

但上一个js脚本加载出现错误,window监听error事件还有没有注册,所以说我们需要把它写在最前边,放到<head></head>里,一开始就去监听。当然,写到最前边它也不会触发,因为它不会事件冒泡,只能在捕获阶段就拿到该事件,在监听事件函数后加“, true”:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.addEventListener("error", e => {
            console.log("error loading")
        },true); // 捕获阶段拿到事件
    </script>
</head>
<body>
    <script src="https://cdn.topskys.org/v0/loadjs.js"></script>
</body>
</html>

 触发error的事件类型也很多,如图片加载错误、在js中throw 1报错也会触发error。我么怎么样缩小触发error的范围,只监听到那些<script src=""></script> 加载js不出来的情况?我们发现error事件中,参数e输入的target是script元素:

但是呢,throw 在error事件里报的是ErrorEvent错误,里面包含各种属性,故我们可以准确地找到某一种错误。

    <script>
        throw 1;
    </script>

 我们需要在window监听error事件里面作一个判断:

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.addEventListener("error", e => {
            const tag=e.target
            if(tag.tagName==='SCRIPT' && !(e instanceof ErrorEvent)) {
                console.log("JS 加载错误")
            }
        },true);
    </script>
</head>

到这里页面解决了,什么时候去重新加载js的问题,还剩下如何重试加载js。

首先,我们需要引入多个新地址的script标签加载js,当某一个js加载失败时,就会被触发window监听事件error,执行重试更换域名生成新的script标签加载js,需要靠document.write()才能阻塞后面的js加载,不阻塞后续js加载,会造成js加载顺序混乱。

注意,在使用document.write()写入script标签时,需要对标签结束符进行转译,否则会被认为是上个标签的结束符。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        const domains = ["https://cdn.topskys.org/v0", "https://cdn.topskys1.org/v1", "https://cdn.topskys2.org/v2"]; // 重试域名数组
        const maxRetry=3; // 最多重试次数 
        const retryInfo={}; // 记录重试次数及下一个重试的域名数组下标{times:1,nextIndex:2}
        window.addEventListener("error", e => {
            const tag = e.target
            if (tag.tagName === 'SCRIPT' && !(e instanceof ErrorEvent)) {
                // console.log("JS 加载错误")
                const url=new URL(tag.src) // 拿到script标签的src域名
                if(!retryInfo[url.pathname]){
                    retryInfo[url.pathname]={
                        times:0,
                        nextIndex:0,
                    }
                }
                const info=retryInfo[url.pathname]; // 取出文件路径 ./loadjs.js ./js.js ./y.js
                 const script=document.createElement("script")
                 url.host=domains[info.nextIndex]; // 更换域名
                 document.write(`<script src="${url.toString()}">\<\/script>`); //  新加载script元素,需要阻塞后面的script加载js,否则加载js顺序会乱。注意转译</script>,否则会被认为上面的script结束标签。
                 script.src=url.toString(); 
                 document.body.insertBefore(script,tag); // 将新的script标签插入加载错误标签前
                //  修改重试信息
                info.times++;
                info.nextIndex=(info.nextIndex+1)%domains.length;
            }
        }, true);
    </script>
</head>
<body>
    <script src="https://cdn.topskys.org/v0/js.js"></script>
    <script src="https://cdn.xx1.cn/y.js"></script>
    <script src="https://cdn.xx2.com/loadjs.js"></script>
</body>
</html>

那么,如何解决js加载失败的问题就解决了。但如果script标签上有defer、async及工程化项目中呢,有如何该解决?

总结

到此这篇关于js脚本加载失败问题解决办法的文章就介绍到这了,更多相关js脚本加载失败内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • php register_shutdown_function函数详解

    php register_shutdown_function函数详解

    register_shutdown_function() 函数可实现当程序执行完成后执行的函数,其功能为可实现程序执行完成的后续操作,需要的朋友可以参考下
    2017-07-07
  • js实现的捐赠管理完整实例

    js实现的捐赠管理完整实例

    这篇文章主要介绍了js实现的捐赠管理完整实例,包括了html页面、js脚本及css样式的完整实现代码,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • 纯JavaScript手写图片轮播代码

    纯JavaScript手写图片轮播代码

    图片轮播效果在各大网站都可以见到,应用非常广泛,今天小编给大家分享纯js实现手写图片轮播的代码,非常不错具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-10-10
  • js实现拉伸拖动iframe的具体代码

    js实现拉伸拖动iframe的具体代码

    这篇文章介绍了js实现拉伸拖动iframe的具体代码,有需要的朋友可以参考一下
    2013-08-08
  • js中的关联数组与普通数组详解

    js中的关联数组与普通数组详解

    下面小编就为大家带来一篇js中的关联数组与普通数组详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • 一文详解JavaScript的事件监听(最新整理)

    一文详解JavaScript的事件监听(最新整理)

    Web页面需要经常和用户之间进行交互,而交互的过程中我们可能想要捕捉这个交互的过程,比如用户点击了某个按钮、用户在输入框里面输入了某个文本、用户鼠标经过了某个位置,下面介绍下JavaScript的事件监听,感兴趣的朋友一起看看吧
    2024-01-01
  • js自定义trim函数实现删除两端空格功能

    js自定义trim函数实现删除两端空格功能

    这篇文章主要介绍了js自定义trim函数实现删除两端空格功能,结合实例形式分析了javascript基于正则替换实现类似trim函数删除字符串两端空格的相关操作技巧,并附带jQuery类似功能函数使用方法,需要的朋友可以参考下
    2018-02-02
  • 使用JS实现在空白页上展示出一个有趣的时钟

    使用JS实现在空白页上展示出一个有趣的时钟

    在我们日常的网页浏览中,空白的页面往往会被视为一种无趣的事物,一片等待填充的空间,今天我们来学习一下如何使用JS在空白的网页上展示出一个有趣的时钟吧,感兴趣的小伙伴跟着小编一起来看看吧
    2024-04-04
  • 测试你的JS的掌握程度的代码

    测试你的JS的掌握程度的代码

    先不讲文章的主题是什么,大家先来做做这些题目,看你能做对多少。这也是反映了你对JS基础知识的掌握程度!
    2009-12-12
  • js图片卷帘门导航菜单特效代码分享

    js图片卷帘门导航菜单特效代码分享

    这篇文章主要介绍了js图片卷帘门导航菜单特效,一款很新颖的图片导航菜单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-09-09

最新评论