正在准备人机验证...
请稍后,正在请求blog-turnstile接口

人机验证折腾记

折腾了整整两天,终于给我的博客加上了一道像样的人机验证。这篇把全过程记下来,也给想在 GitHub Pages 上加验证的朋友一条现成的路。

为什么要加

我的博客是 Hugo + Stack 主题,托管在 GitHub Pages 上,纯静态、没有后端。访客进来先看到一段加载动画,动画结束后就可以直接访问——总觉得少了点仪式感,又怕被脚本刷,就想加一道人机验证,顺便让加载流程变得更有"设计感"。

第一版:自制滑块

最开始想用滑块验证:加载完成后弹出一个面板,把滑块拖到最右边就放行。代码都写好了,效果也确实能跑,但仔细一想——纯前端的滑块,说白了就是自己画了个好看的门,访客拖一下、脚本根本不理你。而且我自己用着都嫌麻烦,果断放弃。

第二版:各种"山寨"方案

不要滑块,那换成什么?试了一圈:

  • 点击按钮式:点一下"完成验证",变绿打勾——太假了,谁看不出来这是摆设?
  • 算术题式:弹个"3 + 5 = ?"——更假,而且打扰人。
  • 点选图标式:弹张图让你点某个物体——倒是像回事,但图库太小,刷两次就撞见同一张,露馅。

试完一圈得出一个结论:自制验证码,做得越像真的越费劲,本质上还是挡不住脚本。要么上真货,要么就别上。

最终版:Cloudflare Turnstile

后来查了一圈,发现 GitHub Pages 这种纯静态站其实有一个正牌选择——Cloudflare Turnstile。它在"托管模式"(Managed)下整个验证过程都跑在 Cloudflare 的节点上,不需要你自己的服务器,前端只插一个组件就行,免费。这是唯一能真正接进纯静态博客的第三方人机验证。

接入后的完整流程变成了:

1
2
3
资源加载齐 → 四根柱子淡出 → 显示「正在准备人机验证...」
→ 等 0.5 秒 → 弹出 Turnstile → 验证通过 → 「请稍后...」
→ 遮罩渐隐 → 进入站点

核心代码就一小段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit" async defer></script>
<div id="captchaBox"></div>
<script>
  turnstile.render('captchaBox', {
    sitekey: '你的 Site Key',
    callback: function (token) {
      hideLoading();  // 验证通过才移除加载遮罩,放行访问
    }
  });
</script>

Site Key 在 Cloudflare 控制台的 Turnstile 页面创建小组件后就能拿到,免费的额度个人博客完全够用。

踩坑:刷新一次弹一次

上线后立刻发现一个烦人的问题:每刷新一次页面,就要重新验证一次。我自己写博客调样式的时候,刷一下就卡一道验证,心态爆炸。

解决办法很简单:验证通过后,把状态写进 sessionStorage。同一标签页里再刷新,直接跳过验证、正常放行;只有关掉标签页重新打开才需要再验证一次。

1
2
3
4
5
6
if (!sessionStorage.getItem('turnstile-passed')) {
  // 弹验证,通过后写入标记
  turnstile.render(...)
} else {
  hideLoading();  // 已验证过,直接跳过
}

收尾

验证通过后我还在遮罩里加了一句「请稍后…」,停顿约 0.8 秒再淡出,节奏刚刚好;侧栏的时钟也改成了等验证结束、遮罩消失后才开始走动,整个加载流程现在是自洽的。

小结

给同样折腾 GitHub Pages 的朋友一句话总结:没有后端的静态站,人机验证只有 Cloudflare Turnstile 的托管模式是正路,别在自制滑块、自制字母验证码上浪费时间——做得再像也是摆设。验证码挡得住手动刷子和垃圾骚扰,挡不住真懂技术的人,个人博客图个安心和个性就足够了。

折腾完这道坎,博客又完善了一块。下次想折腾啥,继续。

根据 CC BY-NC-SA 4.0 协议许可
共 9 篇文章 · 约 1.2 万字 · 运行 38 天
Build using Hugo