- 你是否由于在博客中使用到的免费cdn不稳定而烦恼?现在只需要在
urls.txt
放入url,并运行import_to_db_with_urls_txt.py
,之后再在博客中插入一行freecdn-js提供的js代码,则能够同时加载每个备用cdn连接,哪个先加载完就用哪个,并停止未加载完的cdn。 - 如果你使用
md
编写博客,也能提取.md
文件中的图片等url
并生成所需文件。目前脚本适配了![img](url)
、{%link%}
、{%image%}
、headimg
四个tag
;同时能够自定义需要匹配的tag
。
十分建议您先查看源码中的几个.txt
文件,看看此脚本是否适合你。
urllib3: 1.25.11
nodejs: 16.10.0
freecdn: 0.3.1
freecdn-js能提高网站稳定性,如果其中一个cdn链接不可用则启用另一个链接。博客图床使用到的cdn.jsdelivr.net不太稳定需要备用链接,所以用到了freecdn-js。但是freecdn-js对本身就在服务器端的文件不太友好(因为需要sha256
),例如我把github作为图床而上传的图片(图片不在本地),故写了一个python
脚本处理hash和生成freecdn-js所需要的配置文件。
需要使用安装freecdn-js。本脚本为python
脚本(因为不会写js),需要安装python
。若报错或许需要1.25.11版本的urllib3
。
经过验证,nodejs16.10.0
能运行freecdn-js,如果有安装旧版本nodejs的需要请使用nvm工具安装。
只需要把放在github的图片的url(以.xxx结尾,如.png、.css、.js)放在urls.txt
,每行放一个url,并在同一个文件夹内运行import_to_db_with_urls_txt.py
,即可生成custom.conf
(可以用freecdn manifest --merge $path_to_custom.conf
合并到freecdn-manifest.txt
),custom.conf
由几个内置的cdn模板生成。
url
的格式为http(s)://cdn/user/repo@your_branch/xxx
。其中cdn
可以是cdn.jsdelivr.net/gh/
,cdn.jsdelivr.net/npm/
这种免费cdn。url
的格式也可以为http(s)://raw.githubusercontent.com/user/repo/your_branch/xxx
。url
也可以不带有your_branch
,或许不能生成raw.githubusercontent.com
的cdn链接,但是能生成类cdn.jsdelivr.net/gh/
的cdn链接。可以看到下面.conf
的示例中的https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/app.js
只生成了4个cdn链接。
注:若要成功生成raw.githubusercontent.com
请确保原始url中在@your_branch
之前不存在@
urls.txt
示例
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo (2).ln5ua8psy9s.webp https://raw.githubusercontent.com/xingpingcn/picx-images-hosting/master/20230420/image.7grs1emx5ok0.png https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/app.js
注:脚本未支持其他url格式和生成其他图床url。
输出的最终.conf
会类似这样[示例]
点击查看示例
@global
open_timeout=0
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://jsd.cdn.zzko.cn/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.us/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.ren/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://raw.githubusercontent.com/xingpingcn/picx-images-hosting/master/20230525/logo%20(2).ln5ua8psy9s.webp
hash=53vmPtDi0FDFXfMGWxx4vfPICcg1nY8rLgmQh7wjZow=
https://raw.githubusercontent.com/xingpingcn/picx-images-hosting/master/20230420/image.7grs1emx5ok0.png
https://jsd.cdn.zzko.cn/gh/xingpingcn/picx-images-hosting@master/20230420/image.7grs1emx5ok0.png
https://cdn.jsdelivr.us/gh/xingpingcn/picx-images-hosting@master/20230420/image.7grs1emx5ok0.png
https://cdn.jsdelivr.ren/gh/xingpingcn/picx-images-hosting@master/20230420/image.7grs1emx5ok0.png
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230420/image.7grs1emx5ok0.png
https://raw.githubusercontent.com/xingpingcn/picx-images-hosting/master/20230420/image.7grs1emx5ok0.png
hash=D5Po8oLWNGQ5bk13Tr54ewGI6lcRU22JKIiCnwmKP0w=
https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/app.js
https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/app.js
https://cdn.jsdelivr.us/gh/xingpingcn/website.comments/app.js
https://cdn.jsdelivr.ren/gh/xingpingcn/website.comments/app.js
https://cdn.jsdelivr.net/gh/xingpingcn/website.comments/app.js
hash=xWPhZXLUcZFkPltRZW5UXuzEnLlNlkcIx55vlu5SB7M=
// 如果`is_import_html_to_conf` = `True`
/index.html
https://jsd.cdn.zzko.cn/gh/xingpingcn/xingpingcn.github.io@main/index.html
https://cdn.jsdelivr.us/gh/xingpingcn/xingpingcn.github.io@main/index.html
https://cdn.jsdelivr.ren/gh/xingpingcn/xingpingcn.github.io@main/index.html
https://cdn.jsdelivr.net/gh/xingpingcn/xingpingcn.github.io@main/index.html
https://raw.githubusercontent.com/xingpingcn/xingpingcn.github.io/main/index.html
hash=98HPGpSw/VfpGXiGFurKmHAC76gR5n2R2KNTWrisOTg=
mime=text/html
注:脚本会自动urlencode,将不是url元字符的字符转义以兼容freecdn-js。
或者你也用hexo博客(如果你也使用hexo博客,需要把对应的.py
文件放在博客根目录),那么可以使用import_to_db_with_hexo_blog.py
根据.md
(博客写作使用markdown)文件的内容直接生成pic.conf
(作用和custom.conf
一样,可以用--merge
合并到freecdn-manifest.txt
),无需手动把url添加到urls.txt
。.md
放在source\_posts
,或根据需要自行修改。.py
文件中的正则表达需要根据自己的需求更改。如果你也使用hexo-volantis可以试着直接运行。
脚本适配了四个tag
,为:
![img](url)
{%link%}
{%image%}
headimg
P.S. 如果你像我一样把文件(图片和某些js)放在github(我使用picx.xpoet.cn作为管理工具,上传图片的同时能够自动生成cdn链接),能十分方便生成cdn链接。
-
在
config.py
文件可以设置是否使用代理(v2ray代理,默认开启),需要自行设置。 -
is_import_html_to_conf
为True
时会把html文件也导入到pic.conf
。
P.S. 如果你使用windows可能有些坑,请看这篇文章
-
is_refresh_tag
为True
时,并运行generate_external_manifest_file.py
,这样可以刷新博客的releasetag
从而达到即时更新cdn缓存的目的。 -
config.py
中可以设置是否启用npm空间,只要填写npm空间名字就可以,详见教程。需要添加Token。
注:若在没有更新repo资源的时候重复刷新tag可能会生成多个draft
release;使用该.py文件需要上传两次博客,见和hexo配合使用的第二个示例
Github账户中添加Token:
- Github任意页面中,依次点击:右上角头像 -> Settings -> Developer Settings -> Personal access tokens
- 点击Generate new token
- Notes中随便输入个名字,Select scopes中,确保repo及其子项目全部选中,然后点击Generate Token
- 把产生的token,一个40位的16进制字符串记住。重要:此token只显示这一次,如果没记住只能删除重建
P.S. 官方进行了限制,需要用邮箱申请权限才能生效,比较麻烦(可以设置
config.py
中的is_refresh_tag
为True
,并运行generate_external_manifest_file.py
,这样可以刷新博客的releasetag
从而达到即时更新cdn缓存的目的)
在上传hexo博客后使用refresh_cdn_cache.py
进行刷新。通过访问purge.jsdelivr.net/resource
来刷新cdn.jsdelivr.net/resource
缓存。
外部manifest
(manifest-full.txt)详见EtherDream/freecdn
-
generate_external_manifest_file.py
用于生成freecdn-manifest.txt
,此.txt
储存用于加速manifest-full.txt
的cdn链接。需要在config.py
文件中填写user
、repo
等信息。 -
generate_external_manifest_file.py
中的is_refresh_tag
为True
(config.py中设置)时能刷新博客的releasetag
从而达到即时更新cdn缓存的目的(仅刷新freecdn-manifest.txt
中加速manifest-full.txt
的cdn)。需要填写user
、token
等信息。
P.S. cdn有缓存,如果freecdn失效请通过访问cdn的
freecdn-manifest.txt
或manifest-full.txt
来检验是否和在repo
中对应原文件一致。
生成的freecdn-manifest.txt
示例如下
点击查看示例
@include
/manifest-full.txt
@global
open_timeout=0
/manifest-full.txt
// `is_refresh_tag`为 `True` 时候@main变为@{tag_name}
https://jsd.cdn.zzko.cn/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.us/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.ren/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.net/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://raw.githubusercontent.com/xingpingcn/xingpingcn.github.io/main/manifest-full.txt
hash=izgWMFIdMtd29Zy7kWt3rWohTm7WQsZ9003qUATHdFo=
脚本会先判断urls.txt
(或.md
文件)中的url是否在数据库中(freecdn
使用sqlite3
,位置在~/.freecdn/custom.db
,详见freecdn db;同时python
也内置对应的库;不建议使用freecdn自带的db
命令写入和读取数据库,运行速度非常低)中,如果已经存在则直接写入到新的.conf
,从而节省流量和时间。
如果url不在数据库中,则判断本地是否存储了urls.txt
或.md
(import_to_db_with_hexo_blog.py
无需urls.txt
,脚本内自动处理)中的文件,如果没有则下载文件。如果有则计算hash
并写入.conf
(或pic.conf
)。
下载文件储存在同目录的dir_for_custom_conf
文件夹中,可以在config.py
文件修改位置。
内置了几个类cdn.jsdelivr.net
的cdn。其中jsd.cdn.zzko.cn的GitHub地址是这里
generate_external_manifest_file.py
中的is_refresh_tag
为 True
时(在config.py
中设置),会查询当前的branch是否有release tag
,如果没有则创建一个新的tag
(github API: create-a-release),这个tag
由当前head_commit的sha_id
的前10位组成。如果有则删除,然后创建一个新的tag
,freecdn-manifest.txt中的url替换成以下样式:
https://cdn.jsdelivr.us/gh/xingpingcn/xingpingcn.github.io@{tag}/manifest-full.txt
我的博客用的hexo,因而可以使用以下命令行生成对应文件。
cd f:/blog
hexo clean && hexo g
python ./import_to_db_with_urls_txt.py
python ./import_to_db_with_hexo_blog.py #如果是hexo博客
cd f:/blog/public
freecdn find --save
freecdn manifest --merge ../custom.conf
freecdn manifest --merge ../pic.conf #如果是hexo博客
freecdn js --make
gulp && hexo d
如果你也使用hexo,同时也希望通过cdn
加速freecdn-manifest.txt
,使用以下命令行。
f:
cd f:/blog #博客根目录
hexo clean && hexo g
python ./import_to_db_with_urls_txt.py
python ./import_to_db_with_hexo_blog.py #如果是hexo博客
cd f:/blog/public
freecdn find --save
freecdn manifest --merge ../custom.conf
freecdn manifest --merge ../pic.conf -o manifest-full.txt #用于生成外置的freecdn-manifest.txt
freecdn js --make --cdn "https://jsd.cdn.zzko.cn/gh/user/repo@main/freecdn-internal/ver/freecdn-main.min.js unpkg jsdelivr elemecdn " #此命令为配置cdn链接用于加速.min.js文件,详细请查看freecdn项目的GitHub
gulp && hexo d
python ../generate_external_manifest_file.py #会在.deploy_git生成文件
cd f:/blog/.deploy_git
git add --all #如果“is_refresh_tag”为 “True”需要上传两次
git commit -m "update"
git push origin main #如果需要添加origin地址,请自行添加
python ../refresh_cdn_cache.py
可以的话记得备份~/.freecdn/custom.db
。