[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site":3,"post-rss-he-sitemap-shi-zen-me-bei-pa":59,"related-rss-he-sitemap-shi-zen-me-bei-pa":85},{"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":66,"series":67,"seriesIndex":68,"seriesNav":69,"prev":79,"next":82},"rss-he-sitemap-shi-zen-me-bei-pa","RSS 和 sitemap 是怎么被爬虫看到的","生成时机、地址、robots 里要不要写。sitemap 带 lastmod 之后，改动被抓取的速度明显不一样。","2026-04-28","2026-10-17",[12],"两个都是 XML，作用完全不同，我一开始以为是一回事。\n\nsitemap 是给搜索引擎的地址清单：\"我这儿有哪些地址，最后什么时候改的\"。它不要求实时，但要全，且列出的地址必须能访问。\n\n```xml\n\u003Curl>\n  \u003Cloc>https:\u002F\u002Fexample.com\u002Fposts\u002Fhello\u003C\u002Floc>\n  \u003Clastmod>2026-04-27\u003C\u002Flastmod>\n\u003C\u002Furl>\n```\n\nlastmod 有用。改动后重新提交，被抓取的速度比没有快，因为爬虫能判断这条值不值得再来一次。要注意 lastmod 应该是内容真的改过的时间，不是构建时间——如果每次部署所有条目的 lastmod 都变，它就失去了信息量，爬虫会开始不信这个字段。\n\nsitemap 本身要能被 robots.txt 指到：\n\n```\nSitemap: https:\u002F\u002Fexample.com\u002Fsitemap.xml\n```\n\nrobots.txt 里挡什么要仔细。我挡的是 \u002Fapi\u002F 和 \u002Fadmin\u002F，这两个确实不该进索引。有一处我差点挡错：\u002Fuploads\u002F。图片路径在 robots 里被 Disallow 的话，抓取方拿不到分享卡片和搜索结果里的图，等于自己削弱展示效果。\n\nRSS 是给订阅者的内容流，人要看的。所以它要包含正文全文，而不只是摘要——订阅的人不想再点一次链接。\n\n```xml\n\u003Cchannel>\n  \u003Ctitle>...\u003C\u002Ftitle>\n  \u003Clink>https:\u002F\u002Fexample.com\u003C\u002Flink>\n  \u003Cdescription>...\u003C\u002Fdescription>\n  \u003Citem>\n    \u003Ctitle>...\u003C\u002Ftitle>\n    \u003Clink>https:\u002F\u002Fexample.com\u002Fposts\u002Fhello\u003C\u002Flink>\n    \u003Cguid isPermaLink=\"true\">https:\u002F\u002Fexample.com\u002Fposts\u002Fhello\u003C\u002Fguid>\n    \u003CpubDate>Fri, 24 Apr 2026 09:00:00 GMT\u003C\u002FpubDate>\n    \u003Cdescription>\u003C![CDATA[ ... 正文 HTML ... ]]>\u003C\u002Fdescription>\n  \u003C\u002Fitem>\n\u003C\u002Fchannel>\n```\n\n四个细节我都错过至少一次。\n\npubDate 的格式是 RFC 822，不是 ISO。直接把 new Date().toISOString() 塞进去，订阅器会报错或者当成没日期，条目顺序乱掉。要用 toUTCString()。\n\nguid 用永久链接，别用自增 id。换域名之后订阅者会以为所有文章都变了，全部重推一遍。\n\nCDATA 里的正文要转义。文章里出现 ]]> 会把 CDATA 提前结束，我的处理是把它拆成 \"]]\" + \">\"。这种边角情况一年碰不到一次，碰到了就是订阅端解析失败。\n\n条目数量要有限制。全量输出意味着 RSS 文件会随文章数无限增长，而我第一版就是全量——一百篇之后那个 XML 有 2MB。改成最近 30 篇，加一个 \u002Frss.xml 的缓存。\n\n还有一处是做完才发现的：这两个地址要在 HTML 里声明，别人才发现得了。\n\n```html\n\u003Clink rel=\"alternate\" type=\"application\u002Frss+xml\" href=\"\u002Frss.xml\" title=\"站点名\">\n```\n\n我做完这步才有第一个订阅者。之前 RSS 是\"存在但没人知道\"，跟没做一样。","Nuxt 与服务端渲染",6,[70,71,75],{"slug":60,"title":61,"seriesIndex":68},{"slug":72,"title":73,"seriesIndex":74},"301-302-307-wo-yi-kai-shi-fen","301、302、307 我一开始分不清",7,{"slug":76,"title":77,"seriesIndex":78},"hou-tai-bao-cun-wen-zhang-qian-tai","后台保存文章，前台一小时没变",8,{"slug":80,"title":81},"biao-ge-cha-cao-li-de-row-shi","表格插槽里的 row 是宽类型：TS7053",{"slug":83,"title":84},"re-li-tu-cong-github-zhua-shu-ju","热力图从 GitHub 抓数据，私有仓库不算",[86,93,99,103,107],{"slug":87,"title":88,"excerpt":89,"date":90,"tags":91},"dian-xiang-mu-ye-mian-jiu-si-yi","点「项目」页面就死：一次客户端无限重定向","为了保留旧地址大小写加的一条跳转规则，被注册成了客户端路由；路由匹配不区分大小写，于是它自己跳自己。","2026-10-02",[12,92],"浏览器",{"slug":94,"title":95,"excerpt":96,"date":97,"tags":98},"jian-li-de-xie-gang-hui-bian-cheng","键里的斜杠会变成冒号：清缓存清了个空","按源码里的分组名去匹配存储键，结果一条都没删掉，接口还回 200。返回一个可被证伪的数字，这类问题当场就能发现。","2026-09-30",[12,15],{"slug":76,"title":77,"excerpt":100,"date":101,"tags":102},"SSR 缓存要有主动失效这条通道。密钥两侧必须同值、这个接口不能对公网开、回执要能被打脸（计数）。","2026-09-27",[12],{"slug":72,"title":73,"excerpt":104,"date":105,"tags":106},"永久和临时不只是名字区别，搜索端权重转移不一样。框架给的默认值不一定是你要的那个，得显式写。","2026-09-18",[12],{"slug":108,"title":109,"excerpt":110,"date":111,"tags":112},"gang-deng-lu-jiu-guo-qi-yi-ci","一个 401，查出四个前端机制：缓存回放、隐藏页的 rAF、百分比圆角、缓动过冲","响应头里的 token 被 304 原样回放，把刚签发的新 token 顶掉，表现成刚登录就过期。顺带记三个前端细节：隐藏标签页里 rAF 不执行、扁盒子的 50% 圆角是胶囊、缓动曲线的过冲只有 0.0008。","2026-10-13",[113,114,115,92],"CSS","JavaScript","Vue"]