为什么用纯静态?

心理测试的核心逻辑是前端交互——用户答题、即时出结果,整个过程不需要后端参与。纯静态方案有几个核心优势:

  • 零服务器成本:不需要 Node.js/Python 运行时,Nginx 直接 serve 静态文件
  • 极致性能:HTML+JS+CSS,无数据库查询,首屏秒开
  • 部署简单:打包上传解压,一条命令搞定
  • 高并发无忧:Nginx 静态文件并发能力远超动态程序

技术栈一览

前端原生 HTML + CSS + ES5 JavaScript,零框架依赖
服务器Nginx 1.24,HTTP/2 + gzip + 静态资源7天缓存
SSLLet's Encrypt 免费证书 + crontab 自动续期
部署tar 打包 + scp 上传,阿里云 Alibaba Cloud Linux
CDNqrcodejs 通过 jsDelivr CDN 引入

核心架构:一个引擎跑所有测试

整个网站 7 款测试共用一个 JS 测试引擎(test.js),支持三种测试类型:

  • dimension:多维度计分。MBTI 的 EI/SN/TF/JP 四维,恋爱测试的主动/被动+理性/感性
  • score:累计分数分段。抑郁自测 0-30 分四档,EQ 情商 0-30 分四档
  • multidim:多维度取最高分。职业性格从6个方向中选出最匹配的

新增一个测试只需在 tests.js 中配置题目、选项和结果数据,引擎自动处理渲染、计分、结果展示、二维码生成和分享。这种模式让测试扩展成本几乎为零。

页面组织方式

每个重点测试拥有独立 HTML 页面(如 mbti-test.html),通过 window.__TEST_ID__ 注入测试 ID。这带来几个好处:

  • 每个页面有独立的 title、meta description、结构化数据(JSON-LD),SEO 表现好
  • URL 简洁直观(/mbti-test.html),用户容易记忆和分享
  • 搜索引擎把每个测试当作独立页面索引

首页(index.html)通过 home.js 读取 tests.js 数据自动生成卡片网格,支持按类别筛选(人格/情感/职业/情绪/趣味)。

分享系统设计

考虑到大部分流量来自微信,分享功能做了针对性优化:

  • 微信/QQ 内置浏览器:检测 UA,展示"点击右上角···分享"的引导提示
  • 外部浏览器:优先使用 Web Share API,降级到剪贴板复制
  • 结果页 QR 码:130x130 小型二维码,扫码直达当前测试
  • OG 标签:每个页面配置了完整的 Open Graph 标签,微信分享卡片正常显示

踩过的三个坑

1. 中文弯引号导致全站白屏

EQ 测试描述中有一对中文弯引号(u201c来事u201d),被 JavaScript 解析器当成了字符串终止符,导致 window.TESTS 对象解析失败,所有页面白屏崩溃。排查了一个多小时才发现这一行代码的问题。教训:尽量避免在 JS 字符串中使用中文弯引号,或使用单引号包裹。

2. Nginx 403 拦截 Let's Encrypt 验证

安全规则 location ~ /. { deny all; } 拦截了所有点号开头的目录,包括 .well-known/acme-challenge/,导致证书申请失败。解决方案是在该规则前显式放行 location ^~ /.well-known/acme-challenge/

3. 移动端导航碎片化

早期每个页面各自维护导航链接,新增测试时遗漏了部分页面的更新。后来统一了底栏模板(首页/MBTI/职业/自测),但桌面端顶部导航仍需逐页维护——下一步计划用 SSI 或 JS 组件化解决。

效果与总结

上线后所有测试页均被百度和 Google 收录,移动端体验流畅。服务器单核 1G 内存,Nginx 跑满 7 个独立页面毫无压力,CPU 常年在 5% 以下。

纯静态方案适合内容型、工具型的小项目。如果不需要用户系统和动态数据,大胆用纯静态——简单即是最好的架构。

项目地址:https://ceshi.xiaowu.live