之的文章 Vercel 部署完成后自动执行 Github Action 讲了如何在 Vercel 部署完成后刷新缓存。
但它是整个域下面刷新,某些不需要刷新的部分也被无辜的刷掉了,需要重新回源
例如本站的头像缓存 /avatar
下面子域名的缓存,都被刷掉了
既然 Hexo 是静态生成的,那所有的路径都是编译过程中可获取的,说干就干
如何获取路径
一开始,我想的是写一个 Hexo 的插件,输出所有的 url 列表,转念一想,输出的 sitemap 不就是现成的 url 列表吗?
从 xml 提取所有的链接
1 2 3
| const reg = /(https):\/\/cuojue.org[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g; let url_array = datastr.match(reg);
|
提取的只有 文章 分类 归档 标签 的路径,因为我的静态资源都是托管在其他 CDN 上的,不需要处理
只有首页地址和搜索用的 search.xml 没有,所以要加入它们
1 2 3 4
| url_array.push( "https://cuojue.org/static/xml/search.xml", "https://cuojue.org/" );
|
开始实现梦想
用 axios 构造一个 Post 函数调用 CloudFlare 的 API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function Post(s) { axios .post( `https://api.cloudflare.com/client/v4/zones/${process.env.CLOUDFLARE_ZONE}/purge_cache`, { files: JSON.stringify(s), }, { headers: { Authorization: `Bearer ${process.env.CLOUDFLARE_TOKEN}`, "content-type": "application/json", }, } ) .then((res) => { console.log(`statusCode: ${res.status} success: ${res.data.success} `); }) .catch((error) => { console.error(error); }); }
|
试了一下,出错了。原来是 CloudFlare 的 API 请求有限制,每次最多只能提交 30 个 URL
给 URL 分组,每组 30 个
1 2 3 4
| let _url_array = []; for (var i = 0; i < url_array.length; i += 30) { _result.push(url_array.slice(i, i + 30)); }
|
试一下,提交成功,刷新成功
1 2 3 4 5 6 7
| Run node ./purgecache.js statusCode: 200 success: true statusCode: 200 success: true statusCode: 200 success: true statusCode: 200 success: true statusCode: 200 success: true statusCode: 200 success: true
|
梦想实现啦
成品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| const fs = require("fs"); const axios = require("axios"); fs.readFile("./public/sitemap.xml", "utf8", function (err, datastr) { const reg = /(https):\/\/cuojue.org[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g; let url_array = datastr.match(reg); url_array.push( "https://cuojue.org/static/xml/search.xml", "https://cuojue.org/" ); for (var i = 0; i < url_array.length; i += 30) { Post(url_array.slice(i, i + 30)); } });
function Post(s) { axios .post( `https://api.cloudflare.com/client/v4/zones/${process.env.CLOUDFLARE_ZONE}/purge_cache`, { files: JSON.stringify(s), }, { headers: { Authorization: `Bearer ${process.env.CLOUDFLARE_TOKEN}`, "content-type": "application/json", }, } ) .then((res) => { console.log(`statusCode: ${res.status} success: ${res.data.success} `); }) .catch((error) => { console.error(error); }); }
|
后续,把 Github action 的编译顺序放到了 Vercel 后面,Vercel 编译成功后 Github action 再编译,然后再刷新 CDN