[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site":3,"post-shang-xian-na-tian-yu-ming-zheng-shu":59,"related-shang-xian-na-tian-yu-ming-zheng-shu":77},{"name":4,"url":5,"description":6,"bio":7,"avatar":8,"skills":9,"tools":16,"social":34,"hero":47,"heatmap":52,"icp":55,"police":56,"policeIcon":57,"shortName":58},"时过境迁技术笔记","https:\u002F\u002Fhsgjq.top","一个记录前端与 Node 实践的个人博客，内容围绕 Vue、Nuxt、NestJS 与工程化展开，附源码级的原理笔记。","一名热爱技术的全栈开发者，专注 TypeScript 与 Web 工程化，习惯把踩过的坑和思考记录在这里。","\u002Fuploads\u002Fc485c101-179e-48db-96d1-238693784c38.jpg",[10,11,12,13,14,15],"TypeScript","Vue 3","Nuxt","NestJS","Node.js","工程化",[17,23,28],{"items":18,"title":22},[19,20,21],"Cursor","Git","Chrome DevTools","开发工具",{"items":24,"title":27},[25,26],"Vite","npm","构建工具",{"items":29,"title":33},[30,31,32],"Docker","CI\u002FCD(GitHub Actions)","Vercel","部署运维",[35,39,43],{"href":36,"icon":37,"label":38},"https:\u002F\u002Fgithub.com\u002Fhsgjq","github","GitHub",{"href":40,"icon":41,"label":42},"2971861643@qq.com","mail","邮箱",{"href":44,"icon":45,"label":46},"\u002Frss.xml","rss","RSS",{"lines":48,"subtitle":51},[49,50],"人生若只如初见，","何事秋风悲画扇。","《木兰花·拟古决绝词柬友》",{"enabled":53,"platform":37,"username":54},true,"hsgjq","桂ICP备2024046985号","桂公网安备45011002000103号","\u002Fuploads\u002F72c67ef3-bc86-4b64-b0df-0aba71065050.png","时过境迁",{"slug":60,"title":61,"excerpt":62,"date":63,"updatedAt":64,"tags":65,"content":67,"series":66,"seriesIndex":68,"seriesNav":69,"prev":71,"next":74},"shang-xian-na-tian-yu-ming-zheng-shu","上线那天：域名、证书，和一条我打错的 IP","把 69 打成 96，于是照着\"安全组没放行\"这条错线索查了一整晚。分层排查的前提是先确认敲的是哪扇门。","2026-10-01","2026-10-19",[66],"随笔","站点上线那天，容器全绿、内部 curl 全通，但公网访问 80 端口超时。\n我的判断链是：端口超时 → 抓包看有没有 SYN 到达 → 一个都没有 → 结论：实例绑的安全组不是我看到的那个。为此我在控制台翻了很久，还去查了这台实例到底关联了哪条规则。\n整套推论都建立在一个错误前提上：我在打错的 IP 上。真实地址是 203.0.113.69，我一直敲的是 203.0.113.96，69 和 96 顺序记反了——那个错的地址来自我自己抄错的一行 scp 输出。那台机器是别的东西，22 端口有响应，所以我连 ssh  banner 都拿到了，反而更确信\"网络是通的、只有 80 被拦\"。\n安全组从头到尾都正常。\n这件事我记两条。\n分层排查的方法没错，端口超时先看包到没到、再对照一个确定没监听的端口看是不是秒拒。但方法对不代表结论对，前提得先钉住：动手之前先在那台机器上 curl -s ifconfig.me，跟控制台里的地址对一遍。我那天省掉的是这五秒钟，花掉的是两个小时。\n第二条是关于\"看起来支持我假设的证据\"。我拿到了错误机器的 ssh banner，那一刻应该起疑：如果这是我要找的服务器，为什么 22 端口响应而 80 超时，而 22 是我从没改过的。异常组合本身就是提示，我当时只顾着往下推。\n后面就顺了：域名解析到正确地址，宿主机 nginx 反代到 127.0.0.1:8081，certbot 签证书，http 跳 https。上线后我做的第一件事是把站点地址填进后台——因为 sitemap、RSS、og:image 的绝对地址都读它，不填分享卡片就没图。",2,[70],{"slug":60,"title":61,"seriesIndex":68},{"slug":72,"title":73},"jian-li-de-xie-gang-hui-bian-cheng","键里的斜杠会变成冒号：清缓存清了个空",{"slug":75,"title":76},"cong-da-bao-shang-chuan-dao-push-ji","从打包上传到 push 即上线：把 CD 接通",[78,88,94,97,101],{"slug":79,"title":80,"excerpt":81,"date":82,"tags":83},"gang-deng-lu-jiu-guo-qi-yi-ci","一个 401，查出四个前端机制：缓存回放、隐藏页的 rAF、百分比圆角、缓动过冲","响应头里的 token 被 304 原样回放，把刚签发的新 token 顶掉，表现成刚登录就过期。顺带记三个前端细节：隐藏标签页里 rAF 不执行、扁盒子的 50% 圆角是胶囊、缓动曲线的过冲只有 0.0008。","2026-10-13",[84,85,86,87],"CSS","JavaScript","Vue","浏览器",{"slug":89,"title":90,"excerpt":91,"date":92,"tags":93},"dian-xiang-mu-ye-mian-jiu-si-yi","点「项目」页面就死：一次客户端无限重定向","为了保留旧地址大小写加的一条跳转规则，被注册成了客户端路由；路由匹配不区分大小写，于是它自己跳自己。","2026-10-02",[12,87],{"slug":75,"title":76,"excerpt":95,"date":92,"tags":96},"私有仓库的镜像包默认也是私有的，健康检查的探测地址在宿主机有 nginx 时会打错地方。两处都是配好之后才验出来的。",[30,15],{"slug":72,"title":73,"excerpt":98,"date":99,"tags":100},"按源码里的分组名去匹配存储键，结果一条都没删掉，接口还回 200。返回一个可被证伪的数字，这类问题当场就能发现。","2026-09-30",[12,15],{"slug":102,"title":103,"excerpt":104,"date":105,"tags":106},"hou-tai-bao-cun-wen-zhang-qian-tai","后台保存文章，前台一小时没变","SSR 缓存要有主动失效这条通道。密钥两侧必须同值、这个接口不能对公网开、回执要能被打脸（计数）。","2026-09-27",[12]]