7

CDN加载失败自动切换为加载本地静态资源

 1 year ago
source link: https://www.wyr.me/post/744
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在Web开发中,我们通常使用CDN(内容分发网络)来加速网站的静态资源(如CSS和JavaScript文件)加载。然而,CDN有时可能会失效,导致网站加载速度变慢或者无法正常运行。本文将详细介绍一种优化方案,当HTML中引入的style或JavaScript静态资源CDN失效时,自动切换为加载本地js/css。我们还将介绍一个名为 "CDN to Local Fallback for HTML Files" 的VSCode插件,帮助您更轻松地实现这个方案。

前端静态资源CDN加载失败的优化方案

要实现这个优化方案,我们需要在HTML文件中添加一个特殊的<script>标签,当CDN资源加载失败时,该脚本将自动切换到使用本地资源。具体实现方法如下:

loadFallbackResource函数实现及原理

首先,我们需要实现loadFallbackResource函数,该函数接受两个参数:一个是发生错误的元素(<link><script>标签),另一个是本地资源的相对路径。函数的实现代码如下:

function loadFallbackResource(element, fallbackUrl) {
  if (!element || !fallbackUrl) {
    return;
  }
  const url = new URL(fallbackUrl, window.location.href);
  if (element.tagName === 'LINK') {
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = url.href;
    document.head.appendChild(link);
  } else if (element.tagName === 'SCRIPT') {
    var script = document.createElement('script');
    script.src = url.href;
    document.body.appendChild(script);
  }
}

函数首先检查传入的参数是否有效。然后根据element的标签名(LINKSCRIPT),创建一个新的<link><script>元素,并将其hrefsrc属性设置为本地资源的完整URL。最后,将新创建的元素添加到<head><body>中。

方案实现步骤

  1. 遍历HTML文件中所有引用外部CSS和JavaScript资源的<link><script>标签。
  2. 下载这些标签所指向的CDN资源,并将其保存到本地目录。
  3. 在每个<link><script>标签中添加一个onerror属性,该属性指向一个名为loadFallbackResource的函数。
  4. 在HTML文件中添加一个<script>标签,该标签包含loadFallbackResource函数的实现,以及一个在页面加载完成后遍历所有带有onerror属性的元素并调用loadFallbackResource的事件监听器。

CDN to Local Fallback for HTML Files插件开发过程

为了简化实现上述方案的过程,我们开发了一个名为 "CDN to Local Fallback for HTML Files" 的VSCode插件。插件的开发过程包括以下几个步骤:

  1. 使用axioscheerio库分析和操作HTML文件。
  2. 下载CDN资源并保存到本地目录。
  3. 修改HTML文件中的<link><script>标签,添加onerror属性和data-fallback-url属性。
  4. loadFallbackResource函数及事件监听器添加到HTML文件中。

下面是插件的核心代码以及详细说明:

首先,我们导入所需的模块:

import * as vscode from 'vscode';
import axios from 'axios';
import * as cheerio from 'cheerio';
import * as fs from 'fs';
import * as path from 'path';
import * as url from 'url';

然后,我们实现一个download函数,用于下载CDN资源:

async function download (url: string, dest: string): Promise<void> {
  const response = await axios.get(url, { responseType: 'arraybuffer' });
  fs.writeFileSync(dest, new Buffer(response.data), 'binary');
}

接下来,我们定义插件的主要功能,并注册为一个VSCode命令:

export function activate (context: vscode.ExtensionContext) {
  let disposable = vscode.commands.registerCommand(
    'cdntolocal.downloadAndAddFallback',
    async () => {
      // ...
    }
  );
  context.subscriptions.push(disposable);
}

插件的核心逻辑包括以下部分:

  1. 检查当前活动编辑器和文档类型,确保它们是有效的HTML文件。
  2. 加载HTML文件并使用cheerio库解析为DOM结构。
  3. 遍历所有引用外部CSS和JavaScript资源的<link><script>标签,下载CDN资源并保存到本地目录。同时,修改标签的属性,添加onerrordata-fallback-url属性。
  4. 将修改后的HTML文件写回到磁盘。
  5. 在HTML文件的<head>标签内插入loadFallbackResource函数及事件监听器。

完整的插件代码已经开源在GitHub仓库(https://github.com/yi-ge/cdntolocal),欢迎尝试并提出宝贵意见。

本文介绍了一种前端静态资源CDN加载失败的优化方案,当HTML中引入的style或JavaScript静态资源CDN失效时,可以自动切换为加载本地js/css。我们还介绍了一个名为 "CDN to Local Fallback for HTML Files" 的VSCode插件,帮助您更轻松地实现这个方案。

需要注意的是,虽然这个方案可以解决静态资源CDN失效的问题,但在实际应用中,您可能还需要手动重新初始化业务代码以确保应用正常运行。这个方案并不能解决所有CDN加载失败带来的问题,但它至少可以在某种程度上保证网站在CDN失效的情况下仍然可以正常显示和运行。

通过使用这个方案和插件,您可以更好地为您的用户提供稳定的服务,减少因CDN问题导致的访问失败和用户流失。我们鼓励您尝试这个方案和插件,并根据您的具体需求进行调整和优化。我们期待您的反馈和改进意见,以便我们不断改进这个方案和插件,为更多开发者提供帮助。

注意: 本文及相关代码完全由GPT4完成,人工修改及验证。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK