










我的博客一直托管在 Cloudflare Pages 上,借着 “赛博菩萨” 的免费额度,过得还算滋润。之前写过一篇用 HanAnalytics 做网站统计的文章(那篇在这儿),那个方案说白了是给我自己看的——想看数据还得登录后台一层层点开,访客是无感的。
但作为一个有点强迫症的站长,我总觉得少了点东西:来访的你,能不能在页面上直接看到这篇文章被读过多少次?全站又一共被访问了多少次?这种 “热腾腾” 的访问量数字,才是博客的烟火气嘛。
于是趁着周末有空,我给小站接上了一套站内访问量统计,顺手还把积压已久的依赖漏洞修了一波。下面聊聊思路和踩坑。
你可能会说:装个 Google Analytics、或者我之前用的 HanAnalytics 不就行了?
确实能统计,但它们有两个让我不太舒服的点:
而我这博客本就跑在 Cloudflare Pages 上,它自带 Pages Functions(边缘无服务器函数)和 KV(键值存储),全都在免费额度内。把访问量存在自己的 KV 里、用 Pages Functions 做接口,数据完全自控、零额外服务——这不就是 “赛博菩萨” 的正确打开方式吗?
思路很朴素:
functions/api/views.ts 里写一个 Serverless 函数,接收路径参数;为了避免重复计数,我是这么设计的:
+1,存到 KV 的固定 key(比如 __site__);location.pathname 自增一次,存成各自独立的 key。这样一来,站点总数是所有页面的真实访问量,文章数各自独立,互不打架。
Waiting for api.github.com...
本站用了 Swup 做无刷新页面切换,所以计数器不能只在首屏跑一次——切到另一篇文章时也得更新。我写了个小组件 ViewCounter:
page:view 事件,页面切换后再拉一次。于是文章页头部会显示 “阅读量 N”,页脚常驻 “全站访问量 N”。数字加载前先显示 —,拿到接口返回再填上,体验还算顺滑。
NOTE按我的习惯,这里统计的是 每次加载都
+1(包括刷新)。简单直观,虽然刷新会虚高一点点,但对一个个人博客来说无伤大雅。
借着折腾的机会,我顺手做了一次依赖大保健。一跑 pnpm audit,好家伙——168 个漏洞,3 个 critical、79 个 high,吓得我手里的枸杞茶都洒了。
按 package.json 里的版本范围把直接依赖更新到最新兼容版,再用 pnpm.overrides 强制修掉几个麻烦的传递依赖:
serialize-javascript(构建链里的 RCE)brace-expansion(glob/minimatch 链的 DoS)sharp(libvips 相关)一番操作下来,168 → 17。剩下的 17 个,全部来自 astro 自身——官方公告里写着修复版本是 astro >= 7.0.4,也就是说得做大版本破坏性升级才能清零。
我去翻了翻上游 saicaca/fuwari,发现官方主线也还停留在 astro 5.x,同样带着这 17 个漏洞;他们连 Dependabot 都设成了 “忽略所有大版本更新”,显然也是在等一个合适的时机再大改。既然上游都没急,我这小破站也就先停在这里,等哪天有空再跟着上游的 Tailwind v4 迁移一起把 astro 升上去。
代码推上 GitHub 后,Cloudflare Pages 会自动构建。但要让计数器真正跑起来,还有一个必做动作:
在 Pages 项目 设置 → Functions → KV namespace bindings 里,把新建的 KV 命名空间绑定上去,变量名必须叫 VIEWS(和代码里的 env.VIEWS 对应),然后重新部署一次。
没绑定的话,/api/views 会因为找不到 KV 而报错,计数器就会一直停在 —。
一套站内访问量统计,加上一次依赖大保健,小站又健康了一点。现在你能在每篇文章底下看到它被读过多少次,也能在页脚看到全站的热度——如果你愿意,多点几下刷新,帮我把数字刷好看点(不是)。
下次再聊,可能是 astro 7 的迁移实录了。在那之前,欢迎常来逛逛,你的每一次访问,KV 都记着呢。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。