换主题,顺手挖了四个坑
一直觉得这个博客有点花里胡哨。用的是别人的 Aurora 主题,SPA 架构——首页 HTML 只有 1,539 字节,一个空壳,真正的页面靠 453,646 字节的 JS 在浏览器里拼出来。
所以这次的想法很简单:自己写个主题,干干净净的。
主题两天就写完了。真正的活是在后面。
一、删掉的东西还在,因为服务器在兜底
新主题上线后首页 9.9KB,正文直接躺在 HTML 里,全站 0 个 JS。按理说这就清爽了。
然后我随手请求了一下 /lodash.min.js——这是 Aurora 时代引用的文件,主题删了,文件也不在服务器上。结果:
1 | |
/js/md5.min.js、/dist/gitalk.min.js 也一样,全是 200。
那一刻我意识到:旧站那些”加载不出来但不报错”的怪现象,原因不在主题,在服务器。 页面上引用的三个脚本早就 404 了,是 nginx 把所有找不到的路径统一甩回 index.html,返回 200,浏览器拿到一坨空壳当脚本执行,什么也没发生,静悄悄地失败。
这就是 SPA 时代的标配配置。前端接管路由之后,服务器不知道哪些路径是真页面、哪些不存在,只能全都交出去——反正前端会渲染。可一旦换回服务端生成的静态站,这个兜底就从”必要”变成了纯粹的负担。
二、所有错误地址都返回 200
顺着上一条查下去,就是软 404(soft 404)。
打开 /etc/nginx/sites-available/ckun.xyz,第 17 行:
1 | |
再往下翻,第 38 行:
1 | |
这行一直在,只是从来没生效过。 因为 try_files 的第三个参数兜住了所有失败情况,nginx 根本走不到 404 分支——它认为自己成功返回了首页。
改动就一个字符级别的事:
1 | |
效果:
| 请求 | 改前 | 改后 |
|---|---|---|
/ |
200 | 200 |
/tiantian/ |
200 | 200 |
/definitely-not-exist-xyz/ |
200 + 首页 | 404 + 404 页 |
/post/不存在.html |
200 + 首页 | 404 + 404 页 |
为什么值得修:搜索引擎遇到这种配置,会把无数垃圾 URL 当成有效页面收录进去,稀释站点权重。用户输错地址看不到提示,只看到首页,还会以为是自己点错了。
改之前 cp -a 备份、diff -q 确认备份一致,改完 nginx -t 过了再 systemctl reload(不是 restart)。这些动作一个都不能省——这是生产机上唯一对外的那台。
三、证书从来不会自动续期
修完 404,顺手检查了 www 子域,发现 https://www.ckun.xyz 直接报证书不匹配:
1 | |
证书是单域名的。nginx 里 server_name ckun.xyz www.ckun.xyz; 两个都收了,DNS 也指向同一台机器,但证书只签了主域。一条命令扩进去就行:
1 | |
然后是这次最值得说的一条:这台机器上所有证书都不会自动续期。
我当时想确认续期有没有配好,结果三处全空:
| 检查项 | 结果 |
|---|---|
systemctl list-timers | grep certbot |
空 |
/etc/cron.d/ 里 certbot |
无 |
snap list | grep certbot |
无 |
root 的 crontab |
无 |
查根因:
1 | |
certbot 不是 apt 装的,所以包里自带的 systemd timer 根本没跟着装上。机器上 12 张证书——主域加上 aria2、ariarpc 这些子域——全靠人手续。哪天忘了,某天早上所有 HTTPS 会同时失效,而且是在一个你完全没预料到的时刻。
补了个 cron 兜底:
1 | |
一天两次检查(certbot 只在到期前 30 天才真去申请),续完自动 reload 让 nginx 加载新证书。
这类问题有个共同点:它不在你正在做的事的路径上。 你不查 www 就发现不了单域名证书,不修证书就不会去看续期配置。每一次都是”顺手多看一眼”才挖出来的。
四、”图太大”的根因是截图里的空白
写小程序介绍页时,用户反馈”图太大了,一排多放几个”。
第一反应是调 CSS,把显示宽度从 290px 降到 200px,组内从 250px 降到 165px。改完还是觉得占地方。
真正的原因在图片本身:手机截图是 819×1920 的整屏,但表单页内容到”保存”按钮就结束了——下面七八百像素全是空背景。显示宽度怎么调,这块空白都按比例跟着。
处理办法是先裁再缩:
- 缩到 140px 宽,从底部往上逐行扫,找第一行满足
max(行) - min(行) > 18的位置,那就是内容底 - 裁掉下方多余部分,只留 34px 余白
- 转 WebP(620px 宽、q80)
结果:
| 图 | 裁前高 | 裁后高 | 减少 |
|---|---|---|---|
| 记录血压 | 1920 | 1368 | 29% |
| 记录血糖 | 1920 | 1222 | 36% |
| 记录尿酸 | 1920 | 1198 | 38% |
9 张图从 887KB 降到 317KB。二维码例外——保持原尺寸不压缩,码糊了就扫不出来。
顺带一个细节:裁完三张图高度不一致,display: flex 的默认 align-items 会让它们错位,得显式设 flex-start 顶对齐。
五、几个零碎的坑
Hexo 会把 scripts/ 下所有文件当成插件脚本加载。 我往 scripts/ 放了个 validate_posts.py,结果每次构建都报:
1 | |
它拿 JS 的解析器去读 Python 文件了。挪到 tools/ 就安静了。这个错误不阻断构建,所以我用了好几天都没发现——只是被 | tail -2 挡住了。
CSS 变量写错不会报错,只会静默失效。 我写了 color: var(--text),而主题里的变量叫 --fg。没有警告,没有回退色,就是这一条样式悄悄不生效。后来是通读变量表才发现的。
DNS 被 fake-ip 劫持时,直连域名会连到保留网段。 想 SSH 上服务器,先 getent hosts ckun.xyz 得到 198.18.0.138——这是 198.18.0.0/15,专门做 benchmark 测试的保留段,代理的 fake-ip 占用了它。SSH 连域名必然失败,得用 DoH 查真实 IP:
1 | |
收尾
这次一共改了:主题重写、布局从 720 加宽到 1100、标签配色、分页 bug、一个介绍页配 11 张图、nginx 的软 404、证书扩容、续期 cron。
可如果只看”想简单点”这个出发点,主题本身大概占三成工作量。剩下七成是主题之外那些一直存在、但没人碰过的东西——SPA 时代的兜底规则、装歪了的 certbot、塞在配置 JSON 里的 secret、以及一张张没人裁剪的截图。
它们不是新问题,只是没人在你修别的东西时顺手看它们一眼。