如何实现主脚本不可用时客户端自动加载备用脚本并执行
脚本加载失败自动切换备用脚本实现方案
核心思路是通过动态脚本注入+事件监听捕获加载状态,完全在客户端侧完成检测和切换,不需要服务端改动,仅使用主、备用两个脚本文件,完全符合限制条件。
推荐实现(带可用性校验)
这个方案不仅能捕获脚本加载失败(404、超时、跨域等)的情况,还能识别“脚本加载成功但执行报错、全局变量未注入”的异常场景,更可靠。
代码实现
// 通用脚本加载函数:返回Promise,加载并校验通过则resolve,否则reject function loadScript(src, checkGlobalKey) { return new Promise((resolve, reject) => { // 避免重复加载同一脚本 if (document.querySelector(`script[src="${src}"]`)) { return checkGlobalKey && window[checkGlobalKey] ? resolve() : reject(new Error('已存在的脚本不可用')) } const scriptEl = document.createElement('script') scriptEl.src = src scriptEl.async = true // 加载完成后校验脚本是否真的可用 scriptEl.onload = () => { if (checkGlobalKey && !window[checkGlobalKey]) { return reject(new Error('脚本加载成功但内容异常')) } resolve() } // 加载失败直接触发错误 scriptEl.onerror = () => reject(new Error('脚本资源加载失败')) document.body.appendChild(scriptEl) }) } // 业务初始化逻辑:等任意一个脚本加载成功后执行 async function runApp() { const MAIN_JS = '你的主脚本地址.js' const FALLBACK_JS = '你的备用脚本地址.js' // 脚本约定会挂载的全局变量名,用来校验可用性 const SCRIPT_GLOBAL_KEY = '你的脚本全局命名空间' try { // 优先加载主脚本 await loadScript(MAIN_JS, SCRIPT_GLOBAL_KEY) } catch (err) { console.warn('主脚本不可用,切换备用脚本:', err.message) // 主脚本失败则加载备用脚本 await loadScript(FALLBACK_JS, SCRIPT_GLOBAL_KEY) } // 在这里写所有依赖该脚本的业务逻辑,保证脚本加载完成后才执行 // 例:new window.你的脚本全局命名空间.init() } // DOM就绪后再启动初始化逻辑 document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', runApp) : runApp()
轻量实现(仅检测加载失败)
如果不需要校验脚本执行后的可用性,仅需要处理资源加载失败的场景,可以直接在HTML中写主脚本的静态标签,配合onerror事件实现:
<!-- 主脚本标签,绑定加载失败回调 --> <script src="你的主脚本地址.js" id="main-script" onerror="loadFallback()"></script> <script> // 主脚本加载成功直接执行业务 document.getElementById('main-script').onload = runApp // 主脚本加载失败时加载备用脚本 function loadFallback() { const fallback = document.createElement('script') fallback.src = '你的备用脚本地址.js' // 备用脚本加载完成后再执行业务 fallback.onload = runApp document.body.appendChild(fallback) } function runApp() { // 业务逻辑写在这里 } </script>
注意事项
- 不要把业务逻辑直接写在页面全局作用域的顶层、或者依赖静态脚本的
defer/async事件之外,否则可能出现脚本还没加载完就执行报错的问题,所有业务逻辑都要放在loadScript的resolve回调、或者脚本的onload回调里执行 checkGlobalKey参数是强烈建议添加的校验:部分场景下可能出现资源返回200但内容是错误页、或者脚本执行中途报错的情况,仅靠onload事件无法识别这类异常,校验约定的全局变量是否存在可以大幅提升可靠性- 该方案完全在客户端执行,不需要服务端做任何配置,符合提出的两个限制条件
内容的提问来源于stack exchange,提问作者IPShow
相关产品推荐
相关产品推荐

