当前位置: 首页 > ai >正文

解决 jsdelivr CDN不可用问题

文章目录

      • 问题
      • 替代 CDN
      • 对已有项目的 jsdelivr CDN 进行批量替换
        • 查看已有项目的 jsdelivr CDN 使用情况并记录
        • 替换规律总结
          • 首先尝试 `cdnjs.cloudflare.com`
          • 兜底使用 `unpkg.com`
        • 执行替换
        • 使用脚本统一完成替换
      • 附记

问题

这两天搞 IPv6 地址相关的东东,才发现:jsdelivr CDN 在IPv4下无法访问,仅在IPv6(或双线)下才可以访问!

是的,这个最常被使用的 CDN 被墙了。查了下,它申请的备案好像在前些年就过期了,估计是因为它自动缓存了GitHub好些内容吧,也是不容易。。

PS,对比才发现 IPv6 还真是个好东西~关于IPv6的更多概念和详细情况参见 IPv6简记,现在运营商已经在入户宽带中普及IPv6了,测试网站:IP地址 | 域名 | MAC地址工具集,如果一切正常应该看到双栈IP显示。家庭网络没生效IPv6的直接参照这篇文章进行设置:家庭宽带正确设置IPv6的方法。

替代 CDN

jsdelivr CDN 在中国也有不少私建镜像,但是,考虑到稳定性,均不建议使用。

经测试,无论在IPv4或IPv6下,均可以访问的国际知名 CDN 有:

  • Cloudflare:全球领先的CDN与网络安全服务商,通过覆盖200多个国家的节点网络提供网站加速、DDoS防护、免费SSL证书和边缘计算等服务,兼顾性能与安全。
    • 缺点:不会默认覆盖全网 npm 资源,需开发者主动接入域名。(很多不出名npm都没有Cloudflare CDN)
    • 选择:更稳定,推荐优选。
  • unpkg:专为npm生态设计的公共CDN服务,可直接通过URL自动托管并分发npm包中的静态资源(如JS/CSS),底层依赖Cloudflare网络实现全球加速,适合快速开发调试。
    • 缺点:底层依托Cloudflare网络实现,未来被墙的概率更大。
    • 选择:自动托管npm包,可以无缝替代jsdelivr CDN,在 Cloudflare CDN 没资源情况下作为备选替代。

对已有项目的 jsdelivr CDN 进行批量替换

查看已有项目的 jsdelivr CDN 使用情况并记录

查看已有项目的 jsdelivr CDN 使用情况并记录(记录是为了便于追踪,在出错时进行恢复,毕竟搞错了,该网页就大概率要挂了):

grep 'cdn.jsdelivr.net/npm' /var/www/html -R | tee /tmp/"`date +%Y-%m-%d-%H-%m-%S`.log"
替换规律总结
首先尝试 cdnjs.cloudflare.com
  1. 域名和路径头替换

    • https://cdn.jsdelivr.net/npm/ -> https://cdnjs.cloudflare.com/ajax/libs/
  2. 包名和版本号路径化

    • @ 符号替换为 /
    • 原始格式package@version/...
    • 目标格式package/version/...
    • 例如:bootstrap@4.5.3 -> bootstrap/4.5.3
  3. 移除 /dist/ 目录

    • cdnjs 的路径中通常不包含 /dist/ 目录,需要将其删除。
    • 例如:/dist/js/bootstrap.min.js -> /js/bootstrap.min.js
    • 例如:/dist/css/bootstrap.min.css -> /css/bootstrap.min.css
  4. 版本号标准化(特殊情况)

    • 例如对于 tsparticles 系列包,原版本 2 并不支持,故将所有版本统一指定为了可用的具体版本 2.12.0

总结公式

https://cdn.jsdelivr.net/npm/{package}@{version}/path/to/file -> https://cdnjs.cloudflare.com/ajax/libs/{package}/{version}/path/to/file

兜底使用 unpkg.com
  1. 域名和路径头替换

    • https://cdn.jsdelivr.net/npm/ -> https://unpkg.com/
  2. 保留完整路径

    • unpkg 的路径结构与 npm 包原始结构完全一致,因此包名后的所有路径(包括 /dist/, /build/ 等目录)都原样保留,无需更改。

总结公式

https://cdn.jsdelivr.net/npm/{package}@{version}/path/to/file -> https://unpkg.com/{package}@{version}/path/to/file

执行替换

先确定替换后的 cloudflare CDN 地址是否存在!! 如果不存在则使用 unpkg 进行替换。

命令如下:

find . -type f -exec sed -i 's|https://cdn\.jsdelivr\.net/npm/font-awesome@4\.7\.0/css/font-awesome\.min\.css|https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css|g' {} +find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/hi-base32@0.5.1/build/base32.min.js|https://unpkg.com/hi-base32@0.5.1/build/base32.min.js|g' {} +
使用脚本统一完成替换

不推荐:无法确定被替换后的目标的有效性,且匹配路径不太通用。。(剩余的查找后可以再手动处理)

# 替换为 cdnjs.cloudflare.com
find . -type f -exec sed -i 's|https://cdn\.jsdelivr\.net/npm/\([^@]*\)@\([^/]*\)/dist/|https://cdnjs.cloudflare.com/ajax/libs/\1/\2/|g' {} +

推荐:可完美替代,就是未来的稳定性不如 cloudflare

# 替换为 unpkg.com
find . -type f -exec sed -i 's|https://cdn\.jsdelivr\.net/npm/|https://unpkg.com/|g' {} +

附记

处理记录参考(适用于 阿里云服务器 系列文章中的之前项目统一处理):

find . -type f -exec sed -i 's|https://cdn\.jsdelivr\.net/npm/font-awesome@4\.7\.0/css/font-awesome\.min\.css|https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js|https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.5.3/js/bootstrap.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js|https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css|https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.5.3/css/bootstrap.min.css|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles@2/tsparticles.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles/2.12.0/tsparticles.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-path-polygon@2/tsparticles.path.polygon.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-path-polygon/2.12.0/tsparticles.path.polygon.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/js/bootstrap.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css|https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-preset-fireworks@2/tsparticles.preset.fireworks.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-preset-fireworks/2.12.0/tsparticles.preset.fireworks.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-preset-fire@2/tsparticles.preset.fire.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-preset-fire/2.12.0/tsparticles.preset.fire.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-preset-fireworks@2/tsparticles.preset.fireworks.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-preset-fireworks/2.12.0/tsparticles.preset.fireworks.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-slim@2/tsparticles.slim.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-slim/2.12.0/tsparticles.slim.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-preset-fountain@2/tsparticles.preset.fountain.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-preset-fountain/2.12.0/tsparticles.preset.fountain.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/tsparticles-preset-confetti@2/tsparticles.preset.confetti.bundle.min.js|https://cdnjs.cloudflare.com/ajax/libs/tsparticles-preset-confetti/2.12.0/tsparticles.preset.confetti.bundle.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/vanilla-jsoneditor/standalone.js|https://unpkg.com/vanilla-jsoneditor@3.8.0/standalone.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/js-crc@0.3.1/build/crc.min.js|https://unpkg.com/js-crc@0.3.1/build/crc.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/crypto-js.min.js|https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/diff/dist/diff.min.js|https://unpkg.com/diff@8.0.2/dist/diff.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js|https://unpkg.com/diff2html@3.4.52/bundles/js/diff2html-ui.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css|https://unpkg.com/diff2html/bundles/css/diff2html.min.css|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js|https://unpkg.com/jszip@3.10.1/dist/jszip.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/pako@2.1.0/dist/pako.min.js|https://cdnjs.cloudflare.com/ajax/libs/pako/2.1.0/pako.min.js|g' {} +
find . -type f -exec sed -i 's|https://cdn.jsdelivr.net/npm/hi-base32@0.5.1/build/base32.min.js|https://unpkg.com/hi-base32@0.5.1/build/base32.min.js|g' {} +sed -i 's|https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css|https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css|g' ../php/public-share/index.php
sed -i 's|https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css|https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css|g' ../php/public-share/admin.php.dist
http://www.xdnf.cn/news/19088.html

相关文章:

  • GTSAM中gtsam::LinearContainerFactor因子详解
  • Acrobat Pro DC 2025安装包下载及详细安装教程,PDF编辑器永久免费中文版(稳定版安装包)
  • Android 短信验证码输入框实现
  • 嵌入式Linux驱动开发:定时器驱动
  • 北斗传输采集数据的自定义通信协议
  • 香港电讯创新解决方案,开启企业数字化转型新篇章
  • CollageIt:简单易用的照片拼贴工具
  • Spring boot 启用第二数据源
  • 【Day 40】Shell脚本-条件判断
  • linux中.tar 解压命令
  • 【系列05】端侧AI:构建与部署高效的本地化AI模型 第4章:模型量化(Quantization)
  • 嵌入式Linux驱动开发 - DTS LED驱动
  • 管家婆辉煌ERP中如何查询畅销商品
  • java8浮点型算平均值
  • 37 HTB Remote 机器 - 容易
  • 字典解密助手ArchiveHelperWpfv1.0.12详细使用说明书
  • Apisix工作流程
  • 界面钝化新策略:华南理工实现泡沫铜/Bi-In相变材料热循环性能显著增强
  • 直流电机驱动与TB6612
  • Excel数组学习笔记
  • 【开题答辩全过程】以 基于JSP的养生网站系统为例,包含答辩的问题和答案
  • 本地部署商业服务器 Glassfish 并实现外部访问
  • Rust 安装与运行指南
  • Jetson进行旋转目标检测推理实现大疆无人机飞行控制
  • Git 9 ,.git/index.lock 文件冲突问题( .git/index.lock‘: File exists. )
  • 卷积神经网络为什么要填充(Padding)
  • 基于无人机的风电叶片全自动智能巡检:高精度停角估计与细节优先曝光调控技术
  • 在做题中学习(89):合并区间
  • 如何去除edge浏览器的灰色边框
  • idea2023.3遇到了Lombok失效问题,注释optional和annotationProcessorPaths即可恢复正常