网页文件加载失败如何重试

news/2024/9/20 3:04:49/文章来源:https://www.cnblogs.com/chatrun/p/18304802

本文由 ChatMoney团队出品
在我们开发网站应用时,我们可能会遇到脚本加载失败的情况,导致脚本加载失败的原因有很多,比如用户的网络问题、终端设备问题、用户浏览器版本等诸多因素。
解决方案
在 JavaScript 中,我们可以创建一个监听来监听脚本加载失败的情况,然后针对加载失败的脚本进行重新加载。
重新加载的方案,一般是通过更换域名来解决。我们给每个脚本添加一个映射关系表,用来在加载失败时匹配新的域名进行重试。
具体的解决方案,下面我一步一步讲解,另外希望大家可以仔细阅读注释中的内容

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>脚本加载失败如何重试</title><script>window.addEventListener("error", // 监听全局错误function (e) {console.log(e);},true // 由于脚本加载失败不会冒泡,所以我们要在捕获阶段进行监听);</script></head><body><script src="https://www.zowlsat.com/api/1.js"></script><script src="https://www.qqqqqqq.com/api/2.js"></script><script src="https://www.zowlsat.com/api/3.js"></script></body>
</html>

此时我们可以在浏览器控制台看到以下效果

但是这个监听方法会监听到很多其他的错误,我们只需要监听脚本加载失败的错误,所以我们要通过这个监听事件的参数 e 来判断了

根据上图我们可以发现,普通错误的类型是 ErrorEvent,而脚本加载失败的类型是 Event,并且他的 target 会指向 script 标签,所以我们根据这个区别过滤掉其他的错误,这样剩下的情况才是我们需要处理的。

window.addEventListener("error",function (e) {if (e.target.tagName !== "SCRIPT" || e instanceof ErrorEvent) return;console.log(e);},true
);

接下来就是如何来实现重新加载,我们先给需要重新加载的域名建立一个映射关系,用于替换映射关系表中的域名。然后就是挨个匹配,当还是加载失败时继续匹配下一个,直到成功为止。

const domainList = ["www.aaaaa.com", "www.bbbbb.com", "www.zowlsat.com"];
const retry = {};
window.addEventListener("error",function (e) {if (e.target.tagName !== "SCRIPT" || e instanceof ErrorEvent) return;// 创建一个URL对象const url = new URL(e.target.src);// 获取文件路径const key = url.pathname;// 假如映射表中没有这个文件路径,那么就初始化一个映射键if (!(key in retry)) {retry[key] = 0;}// 假如匹配完整个映射表都没重新加载成功,则放弃const index = retry[key];if (index >= domainList.length) {return;}// 获取新的完整路径const domain = domainList[index];// 替换域名url.host = domain;// 创建新的script标签const script = document.createElement("script");script.src = url.toString();// 将新的script标签追加到加载失败的script标签之前document.body.insertBefore(script, e.target);retry[key]++;},true // 由于脚本加载失败不会冒泡,所以我们要在捕获阶段进行监听
);

到此为止,我们功能已经基本实现,效果如下图

但是有一个很关键的问题,就是假如我 2.js 这个文件中的内容,在 3.js 中要使用,那这样的话,2.js 就必须加载到 3.js 之前,否则就会报错。此时,我们就需要在 2.js 加载失败时,阻塞浏览器的解析,知道重新加载完成或者放弃重新加载时,再继续渲染之后的内容。
那这样的话我们该怎么做呢?🤔

其实很简单,在我们入门 js 时就学到过一个知识点,就是使用document.write
document.write这个方法在解析期间使用的话,会阻塞浏览器的解析,而我们现在就是需要阻塞浏览器解析,那此时我们只需要将创建 script 标签的方法更换为document.write方法即可。

修改之后的代码如下:

const domainList = ["www.aaaaa.com", "www.bbbbb.com", "www.zowlsat.com"];
const retry = {};
window.addEventListener("error",function (e) {if (e.target.tagName !== "SCRIPT" || e instanceof ErrorEvent) return;const url = new URL(e.target.src);const key = url.pathname;if (!(key in retry)) {retry[key] = 0;}const index = retry[key];if (index >= domainList.length) {return;}const domain = domainList[index];url.host = domain;// 此处加上转译是因为防止编译器识别script标签为结束标签报错document.write(`\<script src="${url.toString()}">\<\/script>`);//   const script = document.createElement("script");//   script.src = url.toString();//   document.body.insertBefore(script, e.target);retry[key]++;},true
);

现在我们再打开控制台查看,现在js文件按它原来的顺序执行了,这样既不会改变原有的代码逻辑,又可以在可控范围内进行重新加载。
效果如下图:

以上是简单实现了一个js文件重新加载错误的方案,其实这个方案也可以运用到其他很多类型的文件,不限于js文件。
然后我们还需要更加细化这个方法的话,我们可能还需要考虑到这个script标签是否带有async、defer等属性,还有诸多需要考虑的点,但是沿着这个方向解决的话,大体是没有问题的。
关于我们
本文由ChatMoney团队出品,ChatMoney专注于AI应用落地与变现,我们提供全套、持续更新的AI源码系统与可执行的变现方案,致力于帮助更多人利用AI来变现,欢迎进入ChatMoney获取更多AI变现方案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/744600.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rust各种库

ndarray ndarray 是 NumPy 库中的一个核心数据结构,它是一个用于表示多维数组的对象。ndarray 在存储和操作大型多维数组时非常高效,广泛应用于科学计算、数据分析、机器学习等领域。 在 Rust 开发中,ndarray 库可以作为替代 NumPy 库。 Github 地址:https://github.com/r…

mormot2 api-jwt签名和验签

mormot2 api-jwt签名和验签api-jwt签名和验签 1)根据指定的参数来生成签名2)验证签名并获取参数的值 本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/18304797

记一次Burp与NEW_xp_CAPTCHA工具联动爆破验证码

首先下载NEW_xp_CAPTCHA工具 地址:https://github.com/smxiazi 我下载的是大佬直接发布的打包好的环境,包括对应python3.6.6与NEW_xp_CAPTCHA工具脚本下载完后直接点击运行即可本地访问http://127.0.0.1:8899/,看到这个页面,证明没问题然后就是burp导入插件jar。这里要下载…

nginx对访问路径进行限制【部分接口可以内外网访问、剩余接口只可以内网访问】

前言 最近这段时间的项目被查出了安全漏洞、然后做了一些安全措施的整改。整改后、BOSS又提了个很有意思的思路。 涉及到小程序端的请求接口、内外网都可以访问。 涉及到后台管理的请求接口、只允许内网访问。开干开干 由于项目引进了gateway网关、一开始的时候。我…

ASP.NET Core-本地化

1.安装扩展ResXManager用于管理本地化资源文件 2.添加资源文件Resource.resx 使用工具ResXManager增加其他资源文件,具体参考ResXManager使用 3.注册本地化public static class ServiceCollectionExtensions {public static IServiceCollection AddLanguage(this IServiceColl…

vit的自注意力机制的范围

在Vision Transformer (ViT) 中,自注意力机制的范围是指模型在处理图像块时,每个图像块能够与其他哪些图像块进行交互。ViT的自注意力机制具有全局范围,这意味着在自注意力层中,每个图像块都可以与其他所有图像块进行交互,而不管它们在原始图像中的空间位置如何。以下是Vi…

如何通过ip地址来获取主机名字,查看IP和MAC地址的命令

[基于MS]查看MAC地址命令: 1、使用ipconfig /all,可以看到具体配置。 (查看IP地址,网关,DNS MAC地址等 ) 2、如果和局域网中的其它计算机通信过的话,可以用arp -a命令查看其MAC地址。 3、另外还可以用nbtstat -a [IP] ,不过只能查看某台具体机器的MAC地址(查看其他机器的…

核客任务实战-WEB服务器攻防篇教程

前言 网站服务器的核客攻防一直是网络安全中最重要的一部分,本书作者在经过数月的努力之后,终于将网站服务器的攻防以深入浅出、简单易懂的方式呈现在您的眼前,让您不必具有高深的网络知识和经验,只要依照本书的操作说明来按图索骥的进行,就能让您充分了解与感受到高手的技…

音视频同步原理及实现(转载)

# 音视频同步原理及实现本文主要描述音视频同步原理,及常见的音视频同步方案,并以代码示例,展示如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放。内容如下:* 1.音视频同步简单介绍* 2.DTS和PTS简介 * 2.1I/P/B帧 * 2.2时间戳DTS、PTS* 3.常用同步…

外卖霸王餐系统怎么快速盈利赚钱?

微客云外卖霸王餐系统,作为近年来外卖行业中的一股新兴力量,以其独特的商业模式和营销策略,迅速吸引了大量消费者的目光。该系统通过提供显著的折扣和返利,让顾客能够以极低的价格甚至免费享受到美味的外卖,同时,也为外卖商家带来了可观的收益和市场曝光度。那么,外卖霸…

博客园配置留存

博客园配置留存 博客皮肤:SimpleMeory 侧边栏公告 <script type="text/javascript">window.cnblogsConfig = {info: {blogIcon: https://pic.cnblogs.com/avatar/3370073/20240107144051.png, // 请自己添加一个图片链接(网页标签),如果不需要的话可以删掉na…

ResXManager 使用

1.在扩展中安装ResXManager 2.添加一个资源文件Resource.resx 3.工具中找到ResXManager打开点击左边的刷新按钮加载资源文件,勾选需要使用的资源文件4.添加需要本地化资源 资源名称一般选择使用英文,为了使各个区域人能够理解 5.选择需要本地化的语言 添加的每一项语言都会加…