<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="https://blog.zsx815.top/usr/plugins/Rss/rss-gradient.xsl"?>
<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ZSXの小站</title>
        <link>https://blog.zsx815.top/</link>
        <atom:link href="https://blog.zsx815.top/feed" rel="self" type="application/rss+xml" />
        <description>钟神秀的博客，在这里记录我的生活日常、踩坑教程和资源分享。</description>
        <language>zh-CN</language>
        <lastBuildDate>Mon, 25 May 26 07:59:16 +0800</lastBuildDate>
        <lastBuildDateFormatted>2026年05月25日 07:59</lastBuildDateFormatted>
        <generator>Typecho RSS Plugin</generator>
                <item>
            <title>欢迎使用 Typecho</title>
            <link>https://blog.zsx815.top/archives/1/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/1/</guid>
            <pubDate>Tue, 06 Jan 26 20:34:00 +0800</pubDate>
            <pubDateFormatted>2026年01月06日20:34</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; 一些语法格式记录。</p><h2>注释</h2><!-- NOTE: 蓝色 --><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">ℹ️ 提示</strong><br>
  <span style="color: #ff6600;">补充信息</span>
</div><!-- WARNING: 黄色 --><div style="border-left: 4px solid #d1242f; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">⚠️ 警告</strong><br>
  <span style="color: #ff6600;">警告内容</span>
</div><!-- IMPORTANT: 紫色 --><div style="border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #FA3107;">❗ 重要</strong><br>
  <span style="color: #FA3107;">关键信息</span>
</div><!-- TIP: 绿色 --><div style="border-left: 4px solid #1a7f37; background-color: #dafbe1; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">💡 建议</strong><br>
  <span style="color: #ff6600;">实用建议</span>
</div><!-- CAUTION: 红色 --><div style="border-left: 4px solid #cf222e; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">⛔ 注意</strong><br>
  <span style="color: #ff6600;">危险操作警示</span>
</div><pre><code>&lt;!-- NOTE: 蓝色 --&gt;
&lt;div style=&quot;border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;ℹ️ 提示&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;补充信息&lt;/span&gt;
&lt;/div&gt;

&lt;!-- WARNING: 黄色 --&gt;
&lt;div style=&quot;border-left: 4px solid #d1242f; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;⚠️ 警告&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;警告内容&lt;/span&gt;
&lt;/div&gt;

&lt;!-- IMPORTANT: 紫色 --&gt;
&lt;div style=&quot;border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #FA3107;&quot;&gt;❗ 重要&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #FA3107;&quot;&gt;关键信息&lt;/span&gt;
&lt;/div&gt;

&lt;!-- TIP: 绿色 --&gt;
&lt;div style=&quot;border-left: 4px solid #1a7f37; background-color: #dafbe1; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;💡 建议&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;实用建议&lt;/span&gt;
&lt;/div&gt;

&lt;!-- CAUTION: 红色 --&gt;
&lt;div style=&quot;border-left: 4px solid #cf222e; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;⛔ 注意&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;危险操作警示&lt;/span&gt;
&lt;/div&gt;</code></pre>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; 一些语法格式记录。</p><h2>注释</h2><!-- NOTE: 蓝色 --><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">ℹ️ 提示</strong><br>
  <span style="color: #ff6600;">补充信息</span>
</div><!-- WARNING: 黄色 --><div style="border-left: 4px solid #d1242f; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">⚠️ 警告</strong><br>
  <span style="color: #ff6600;">警告内容</span>
</div><!-- IMPORTANT: 紫色 --><div style="border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #FA3107;">❗ 重要</strong><br>
  <span style="color: #FA3107;">关键信息</span>
</div><!-- TIP: 绿色 --><div style="border-left: 4px solid #1a7f37; background-color: #dafbe1; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">💡 建议</strong><br>
  <span style="color: #ff6600;">实用建议</span>
</div><!-- CAUTION: 红色 --><div style="border-left: 4px solid #cf222e; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">⛔ 注意</strong><br>
  <span style="color: #ff6600;">危险操作警示</span>
</div><pre><code>&lt;!-- NOTE: 蓝色 --&gt;
&lt;div style=&quot;border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;ℹ️ 提示&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;补充信息&lt;/span&gt;
&lt;/div&gt;

&lt;!-- WARNING: 黄色 --&gt;
&lt;div style=&quot;border-left: 4px solid #d1242f; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;⚠️ 警告&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;警告内容&lt;/span&gt;
&lt;/div&gt;

&lt;!-- IMPORTANT: 紫色 --&gt;
&lt;div style=&quot;border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #FA3107;&quot;&gt;❗ 重要&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #FA3107;&quot;&gt;关键信息&lt;/span&gt;
&lt;/div&gt;

&lt;!-- TIP: 绿色 --&gt;
&lt;div style=&quot;border-left: 4px solid #1a7f37; background-color: #dafbe1; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;💡 建议&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;实用建议&lt;/span&gt;
&lt;/div&gt;

&lt;!-- CAUTION: 红色 --&gt;
&lt;div style=&quot;border-left: 4px solid #cf222e; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;&quot;&gt;
  &lt;strong style=&quot;color: #ff6600;&quot;&gt;⛔ 注意&lt;/strong&gt;&lt;br&gt;
  &lt;span style=&quot;color: #ff6600;&quot;&gt;危险操作警示&lt;/span&gt;
&lt;/div&gt;</code></pre>]]></content:encoded>
        </item>
                <item>
            <title>2025年终总结</title>
            <link>https://blog.zsx815.top/archives/20/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/20/</guid>
            <pubDate>Wed, 31 Dec 25 16:00:00 +0800</pubDate>
            <pubDateFormatted>2025年12月31日16:00</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown--><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;"><br>  <strong style="color: #ff6600;">ℹ️ 提示</strong><br><br>  <span style="color: #ff6600;">一年马上要结束了，终于到我写年末总结了！我的年末总结大体还是总结我今年做了什么和明年的展望吧。</span><br></div></p><p><center></p><pre style="font-family: 'KaiTi', serif; font-size: 20px;">
归去来兮辞
陶渊明

往者不可谏，
来者犹可追。
</pre><p></center></p><h2>总结</h2><blockquote>今年算是没什么起色，依旧彷徨不定的一年吧。</blockquote><h3>2025.1</h3><p>年初考试，被早早结束甚至连复习作业都没有的电机与电气控制成功背刺，差两分过关。然后就是寒假学车，速成5天去考试，这次一次过，成功拿证！然后算是恶补准备开学补考，然后算是去实践了一段时间。之后就是年底过年，没什么好说的，近些年年味是越来越少，最多也就是去舅舅或者外婆家吃饭了，然后就和普通放假没区别。</p><hr><h3>2025.2</h3><p>到了2月份，陪妈妈出去玩了几天，我不是个喜欢外出的人，而且社恐，不过陪妈妈出去玩还是乐意的。然后在11号下午逛Github时看到了 <a href="https://www.zhilu.site">纸鹿</a> 大佬的<a href="https://github.com/L33Z22L11/blog-v3">博客项目</a>，很好看，于是使用！然后开始我正式学习修改博客的旅程。接下来几天就算是练手和尝试不同的博客，然后开始随便写写。后来时不时分享来自电报的项目在我的<a href="https://t.me/kemiaofx_me">频道</a>上时不时分享我找到的资源。</p><p>很快就开学了，开学正常准备补考，期间还看到4级裸考过关了。然后就是补考过关，然后在26号开始想写写日记，在obs和思源上，基本上一直在坚持，距今基本写了10个月，虽然文笔不怎么样，但一直在坚持。</p><hr><h3>2025.3</h3><p>3月份开始我就在不断地尝试各种博客和逛友链，上课等等循环，仔细想想，好久不玩游戏了。期间说实话没什么好写的，同质化严重。</p><hr><h3>2025.4</h3><p>4月份又写了些文章，然后忙于学业，同时对博客也一直不是很满意，尝试了很多，同时晚上活动添加一：看LOL比赛。其实也不算看，我有个不算习惯的习惯，干什么事耳朵总想听些东西。</p><hr><h3>2025.5</h3><p>年后第一次回家就在劳动节，5天回去转了转，然后就回来实训，准备期末等等，期间发现了不少好的博客主题，不在一一列举。然后在<a href="https://github.com/kemiaofxjun">账号</a>等继续测试，选中了好看的<a href="https://github.com/everfu/hexo-theme-solitude">solitude主题</a><sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup>，以及后台<a href="https://github.com/Qexo/Qexo">Qexo</a><sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup>。然后在<a href="https://shengdaoyun.cn">圣道云</a>开始了typecho和WordPress博客的搭建。由于我的需求不大，最后选择了typecho。</p><hr><h3>2025.6</h3><p>6月份开始，电脑出了点问题，反复进BIOS，初步推断是硬盘的问题，但是当时期末有PLC的课，实在不好去修，于是先将就着，然后那段时间就不改项目和写日记了。顺便裸考了一次六级，有一说一，感觉和四级差不多难度🤔。然后考完了期末，放假。</p><p>回了家去给电脑清个灰，加了点内存，然后那个问题就不在出现了。</p><hr><h3>2025.7</h3><p>暑假第一个月其实就是在实践和休息里面度过，陪老妈转了几天，然后我就肾结石了。</p><div style="border-left: 4px solid #d1242f; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">⚠️ 警告</strong><br>
  <span style="color: #ff6600;">少喝饮料多运动！</span>
</div><p>睡醒痛的我死去活来，感人人要没了，后来去医院检查，差点动手术，后面吃药自然排出了。</p><p>月底的时候搞了台服务器，然后玩了几天Halo，动态的博客还是不大适应，一般般吧，后面就放弃了，然后部署了<a href="https://github.com/lin-snow/Ech0">Ech0</a>、<a href="https://github.com/kingwrcy/moments">Moments</a>等服务，挺有意思的。</p><hr><h3>2025.8</h3><p>8月份其实没什么，着重来说就是新开了个号，然后就是继续玩各种项目和实践。20号一看，六级裸考过关了。</p><hr><h3>2025.9</h3><p>开学后继续改博客，然后上课，看比赛然后就是搞了些许项目。后面电脑的问题又出来了，但是被我倒腾了一段时间就好了。</p><hr><h3>2025.10</h3><p>国庆在家瘫了7天，然后继续改博客，写博客，回来后就是上课，解决了宽禁带半导体的2万多字的论文和排版，恶心坏我了。在月底的鸭科夫时又出现了那个问题，初步确定是系统盘的问题，拿去售后换了个盘，修了下一些成年旧事。</p><hr><h3>2025.11</h3><p>这个月搞好后重新搞环境等等，上课什么的，没什么好说的。月底开始实训，是关于水净化系统的编程，前三天画图，后面那B系统已经绝版，全世界估计就那一间实验室还在用的老古董，能不能用全看天，哪天能用全看天，没什么好说的，因此就是没什么急迫感。</p><hr><h3>2025.12</h3><p>这个月就是继续完成实训，上课，再战六级，同样裸考，随便玩玩，反正过了。然后月底再次重搞blog-v3，每次打开项目还是有新的想法还是不错的。</p><hr><h2>总结</h2><p>今年还是那咸鱼样，摆烂惯了，总体来说比去年这时候肯定是进步的，还是希望明年更好吧。</p><hr><h2>展望</h2><p>不算什么展望吧，希望明年会的更多，解决更多的问题，过得越来越好吧。</p><div class="footnotes"><hr><ol><li id="fn-1"> 后面还会重新搞一下。 <a href="#fnref-1" class="footnote-backref">&#8617;</a></li></ol></div>]]></description>
            <content:encoded><![CDATA[<p><!--markdown--><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;"><br>  <strong style="color: #ff6600;">ℹ️ 提示</strong><br><br>  <span style="color: #ff6600;">一年马上要结束了，终于到我写年末总结了！我的年末总结大体还是总结我今年做了什么和明年的展望吧。</span><br></div></p><p><center></p><pre style="font-family: 'KaiTi', serif; font-size: 20px;">
归去来兮辞
陶渊明

往者不可谏，
来者犹可追。
</pre><p></center></p><h2>总结</h2><blockquote>今年算是没什么起色，依旧彷徨不定的一年吧。</blockquote><h3>2025.1</h3><p>年初考试，被早早结束甚至连复习作业都没有的电机与电气控制成功背刺，差两分过关。然后就是寒假学车，速成5天去考试，这次一次过，成功拿证！然后算是恶补准备开学补考，然后算是去实践了一段时间。之后就是年底过年，没什么好说的，近些年年味是越来越少，最多也就是去舅舅或者外婆家吃饭了，然后就和普通放假没区别。</p><hr><h3>2025.2</h3><p>到了2月份，陪妈妈出去玩了几天，我不是个喜欢外出的人，而且社恐，不过陪妈妈出去玩还是乐意的。然后在11号下午逛Github时看到了 <a href="https://www.zhilu.site">纸鹿</a> 大佬的<a href="https://github.com/L33Z22L11/blog-v3">博客项目</a>，很好看，于是使用！然后开始我正式学习修改博客的旅程。接下来几天就算是练手和尝试不同的博客，然后开始随便写写。后来时不时分享来自电报的项目在我的<a href="https://t.me/kemiaofx_me">频道</a>上时不时分享我找到的资源。</p><p>很快就开学了，开学正常准备补考，期间还看到4级裸考过关了。然后就是补考过关，然后在26号开始想写写日记，在obs和思源上，基本上一直在坚持，距今基本写了10个月，虽然文笔不怎么样，但一直在坚持。</p><hr><h3>2025.3</h3><p>3月份开始我就在不断地尝试各种博客和逛友链，上课等等循环，仔细想想，好久不玩游戏了。期间说实话没什么好写的，同质化严重。</p><hr><h3>2025.4</h3><p>4月份又写了些文章，然后忙于学业，同时对博客也一直不是很满意，尝试了很多，同时晚上活动添加一：看LOL比赛。其实也不算看，我有个不算习惯的习惯，干什么事耳朵总想听些东西。</p><hr><h3>2025.5</h3><p>年后第一次回家就在劳动节，5天回去转了转，然后就回来实训，准备期末等等，期间发现了不少好的博客主题，不在一一列举。然后在<a href="https://github.com/kemiaofxjun">账号</a>等继续测试，选中了好看的<a href="https://github.com/everfu/hexo-theme-solitude">solitude主题</a><sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup>，以及后台<a href="https://github.com/Qexo/Qexo">Qexo</a><sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup>。然后在<a href="https://shengdaoyun.cn">圣道云</a>开始了typecho和WordPress博客的搭建。由于我的需求不大，最后选择了typecho。</p><hr><h3>2025.6</h3><p>6月份开始，电脑出了点问题，反复进BIOS，初步推断是硬盘的问题，但是当时期末有PLC的课，实在不好去修，于是先将就着，然后那段时间就不改项目和写日记了。顺便裸考了一次六级，有一说一，感觉和四级差不多难度🤔。然后考完了期末，放假。</p><p>回了家去给电脑清个灰，加了点内存，然后那个问题就不在出现了。</p><hr><h3>2025.7</h3><p>暑假第一个月其实就是在实践和休息里面度过，陪老妈转了几天，然后我就肾结石了。</p><div style="border-left: 4px solid #d1242f; background-color: #ffebe9; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">⚠️ 警告</strong><br>
  <span style="color: #ff6600;">少喝饮料多运动！</span>
</div><p>睡醒痛的我死去活来，感人人要没了，后来去医院检查，差点动手术，后面吃药自然排出了。</p><p>月底的时候搞了台服务器，然后玩了几天Halo，动态的博客还是不大适应，一般般吧，后面就放弃了，然后部署了<a href="https://github.com/lin-snow/Ech0">Ech0</a>、<a href="https://github.com/kingwrcy/moments">Moments</a>等服务，挺有意思的。</p><hr><h3>2025.8</h3><p>8月份其实没什么，着重来说就是新开了个号，然后就是继续玩各种项目和实践。20号一看，六级裸考过关了。</p><hr><h3>2025.9</h3><p>开学后继续改博客，然后上课，看比赛然后就是搞了些许项目。后面电脑的问题又出来了，但是被我倒腾了一段时间就好了。</p><hr><h3>2025.10</h3><p>国庆在家瘫了7天，然后继续改博客，写博客，回来后就是上课，解决了宽禁带半导体的2万多字的论文和排版，恶心坏我了。在月底的鸭科夫时又出现了那个问题，初步确定是系统盘的问题，拿去售后换了个盘，修了下一些成年旧事。</p><hr><h3>2025.11</h3><p>这个月搞好后重新搞环境等等，上课什么的，没什么好说的。月底开始实训，是关于水净化系统的编程，前三天画图，后面那B系统已经绝版，全世界估计就那一间实验室还在用的老古董，能不能用全看天，哪天能用全看天，没什么好说的，因此就是没什么急迫感。</p><hr><h3>2025.12</h3><p>这个月就是继续完成实训，上课，再战六级，同样裸考，随便玩玩，反正过了。然后月底再次重搞blog-v3，每次打开项目还是有新的想法还是不错的。</p><hr><h2>总结</h2><p>今年还是那咸鱼样，摆烂惯了，总体来说比去年这时候肯定是进步的，还是希望明年更好吧。</p><hr><h2>展望</h2><p>不算什么展望吧，希望明年会的更多，解决更多的问题，过得越来越好吧。</p><div class="footnotes"><hr><ol><li id="fn-1"> 后面还会重新搞一下。 <a href="#fnref-1" class="footnote-backref">&#8617;</a></li></ol></div>]]></content:encoded>
        </item>
                <item>
            <title>给博客加一个外链安全中转页（/go）</title>
            <link>https://blog.zsx815.top/archives/17/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/17/</guid>
            <pubDate>Wed, 10 Dec 25 12:00:00 +0800</pubDate>
            <pubDateFormatted>2025年12月10日12:00</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; [!NOTE]</p><blockquote><p>这篇文章来自<strong>AI</strong>整理，来自我的<a href="https://blog.zsxcoder.top">博客</a>。</p><p>想做一个类似 <a href="https://github.com/willow-god/hexo-safego"><code>hexo-safego</code></a> 的外链安全检测 / 中转效果，于是在自己的 Nuxt 博客里加了一个 <code>/go</code> 页面，用来统一接住外链，给用户一个“即将离开本站”的提醒和手动确认。</p></blockquote><p>这篇文章记录一下整个实现过程：从需求拆解，到 <code>go.vue</code> 的实现，再到 Markdown 外链、友链卡片接入中转页，以及中途踩到的几个小坑。</p><h2>背景 & 需求</h2><p>需求最初很简单：</p><ul><li>站内所有 <strong>外链</strong>（包括 Markdown 正文里的链接、友链页里的链接），点击时不要直接打开目标网站；</li><li><p>先跳到一个中转页 <code>/go?url=...</code>：</p><ul><li>提示“即将离开本站”；</li><li>显示目标链接和域名；</li><li>提供「继续访问」和「返回上一页」两个按钮；</li><li>支持几秒钟的倒计时，自动跳转；</li></ul></li><li>内部链接（例如 <code>/posts/...</code>、<code>/about</code>）保持原样，不走 <code>/go</code>。</li></ul><p>最后确定的范围是：</p><ul><li>Markdown 渲染组件 <code>ProseA.vue</code>（文章正文中的链接）；</li><li>友链页使用的 <code>FriendLinkCard.vue</code>（<code>link.vue</code> 页面中的友链卡片）。</li></ul><h2>实现 <code>/go</code> 页面</h2><p>首先在 <code>app/pages/go.vue</code> 新增一个页面，对应路由 <code>/go</code>。这个页面做几件事：</p><ol><li>从 query 参数里拿到原始链接 <code>url</code>；</li><li>做一层解码和合法性判断；</li><li>展示信息 + 倒计时；</li><li>处理手动「继续访问」和「返回上一页」。</li></ol><h3>解析 URL 与合法性判断</h3><pre><code class="lang-ts">&lt;script setup lang=&quot;ts&quot;&gt;
const route = useRoute()
const router = useRouter()

// 原始 query 参数
const rawUrl = computed(() =&gt; (route.query.url as string) || &#039;&#039;)

// 解码后的 URL：优先 decode，失败就回退到原始字符串，保证按钮始终有值可用
const decodedUrl = computed(() =&gt; {
  if (!rawUrl.value)
    return &#039;&#039;
  try {
    return decodeURIComponent(rawUrl.value)
  }
  catch {
    // 如果解码失败，回退使用原始字符串，保证按钮依然可用
    return rawUrl.value
  }
})

// 检查是否是一个合法的 http/https 外链
const isValidExternal = computed(() =&gt; {
  if (!decodedUrl.value)
    return false
  try {
    const u = new URL(decodedUrl.value)
    return u.protocol === &#039;http:&#039; || u.protocol === &#039;https:&#039;
  }
  catch {
    return false
  }
})

// 提取域名用于展示
const domain = computed(() =&gt; {
  if (!isValidExternal.value)
    return &#039;&#039;
  try {
    return new URL(decodedUrl.value).hostname
  }
  catch {
    return &#039;&#039;
  }
})</code></pre><p>这里有一个小细节：</p><ul><li>一开始如果 decodeURIComponent 失败，直接返回空字符串会导致后面一系列逻辑都认为“无效链接”，按钮会被禁用，看起来像“点不了”；</li><li><p>后来改为失败回退到 rawUrl ，只要 query 里有东西，最终就有一个可用字符串。</p><h3>倒计时和自动跳转</h3><pre><code class="lang-ts">const countdownSeconds = 5
const countdown = ref(countdownSeconds)
let countdownTimer: number | null = null

onMounted(() =&gt; {
if (!isValidExternal.value)
  return

countdown.value = countdownSeconds

countdownTimer = window.setInterval(() =&gt; {
  if (countdown.value &lt;= 1) {
    clearCountdown()
    proceed()
  }
  else {
    countdown.value -= 1
  }
}, 1000)
})

onUnmounted(() =&gt; {
clearCountdown()
})

function clearCountdown() {
if (countdownTimer != null) {
  clearInterval(countdownTimer)
  countdownTimer = null
}
}</code></pre><p>设计思路：</p></li><li>只要判断为合法外链，就从设定的秒数开始倒计时；</li><li>每秒减 1，减到 1 时自动调用 proceed() ；</li><li><p>页面销毁（路由离开）时清理定时器，避免内存泄漏或误触发。</p><h3>手动跳转和返回逻辑</h3><pre><code class="lang-ts">function proceed() {
const target = decodedUrl.value || rawUrl.value
if (!target)
  return

clearCountdown()
window.location.href = target
}

function goBack() {
clearCountdown()

// 1. 如果是通过 window.open 打开的新标签页，优先尝试关闭自己
if (window.opener &amp;&amp; window.opener !== window) {
  window.close()
  return
}

// 2. 有历史记录就正常返回
if (history.length &gt; 1) {
  history.back()
  return
}

// 3. 没有历史时，尝试根据同源 referrer 返回
if (document.referrer) {
  try {
    const ref = new URL(document.referrer)
    if (ref.origin === window.location.origin) {
      router.push(ref.pathname + ref.search + ref.hash)
      return
    }
  }
  catch {
    // ignore
  }
}

// 4. 兜底：回首页
router.push(&#039;/&#039;)
}
&lt;/script&gt;</code></pre><p>这里对「返回上一页」做了比较细的兼容：</p></li><li><strong>友链卡片那种新标签页场景</strong>：通过 window.open('/go?url=...', '_blank') 打开的 /go 页面，其实没有历史记录，这时 history.back() 是无效的，于是我们优先检测 window.opener ，直接 window.close() ，让原来的标签页停留在友链页不动；</li><li><strong>同标签页场景</strong>：有历史记录就走 history.back() ，行为和用户点浏览器后退按钮一致；</li><li><p><strong>没有历史、没有同源 referrer 的极端场景</strong>：最后才兜底跳首页。</p><h3>模板和样式</h3><p>模板部分主要就是展示提示、链接、按钮和倒计时：</p><pre><code class="lang-vue">&lt;template&gt;
&lt;div class=&quot;go-page&quot;&gt;
  &lt;div class=&quot;go-card&quot;&gt;
    &lt;h1 class=&quot;go-title&quot;&gt;即将离开本站&lt;/h1&gt;
    &lt;p class=&quot;go-desc&quot;&gt;
      你将要访问的外部链接：
    &lt;/p&gt;
    &lt;p v-if=&quot;isValidExternal&quot; class=&quot;go-url&quot;&gt;{{ decodedUrl }}&lt;/p&gt;
    &lt;p v-else class=&quot;go-url invalid&quot;&gt;链接无效或缺失&lt;/p&gt;

    &lt;p v-if=&quot;isValidExternal&quot; class=&quot;go-domain&quot;&gt;
      目标站点：&lt;strong&gt;{{ domain }}&lt;/strong&gt;
    &lt;/p&gt;

    &lt;div class=&quot;go-actions&quot;&gt;
      &lt;button type=&quot;button&quot; class=&quot;btn secondary&quot; @click=&quot;goBack&quot;&gt;
        返回上一页
      &lt;/button&gt;
      &lt;button
        type=&quot;button&quot;
        class=&quot;btn primary&quot;
        @click=&quot;proceed&quot;
      &gt;
        继续访问&lt;span v-if=&quot;domain&quot;&gt; {{ domain }}&lt;/span&gt;
      &lt;/button&gt;
    &lt;/div&gt;

    &lt;p v-if=&quot;isValidExternal&quot; class=&quot;go-countdown&quot;&gt;
      {{ countdown }} 秒后将自动跳转，如不希望跳转，请点击「返回上一页」
    &lt;/p&gt;

    &lt;p class=&quot;go-tip&quot;&gt;
      外部网站内容与本博客无关，请注意辨别信息和账号安全。
    &lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;</code></pre><p>样式部分使用了博客现有的变量（ <code>var(--c-text)</code>、 <code>var(--ld-bg-card)</code> 等），整体就是一个居中的卡片，这里不赘述。</p></li></ul><p><strong>接入 Markdown 外链：改造 <code>ProseA.vue</code></strong><br>博客的 Markdown 链接渲染组件是 <code>app/components/content/ProseA.vue</code> ，原来大致是：</p><ul><li>根据 <code>href</code> 判断是否外链；</li><li>用 <code>UtilLink</code> 渲染；</li><li>用 <code>v-tip</code> 显示域名或完整地址。</li></ul><p>为了让 Markdown 外链走 <code>/go</code> ，改动非常小，只需要在这里统一改造 <code>href</code> 即可：</p><pre><code class="lang-ts">const props = defineProps&lt;{
  href: string
  icon?: string
}&gt;()

const icon = computed(() =&gt; props.icon || getDomainIcon(props.href))
const isExternal = computed(() =&gt; isExtLink(props.href))

// 外链统一改成指向 /go?url=encodeURIComponent(href)
const resolvedHref = computed(() =&gt; (
  isExternal.value ? `/go?url=${encodeURIComponent(props.href)}` : props.href
))

const tip = computed(() =&gt; ({
  content: isExternal.value ? getDomain(props.href) : decodeURIComponent(props.href),
  inlinePositioning: true,
}))</code></pre><p>模板：</p><pre><code class="lang-Vue">&lt;template&gt;
  &lt;UtilLink v-tip=&quot;tip&quot; class=&quot;z-link&quot; :to=&quot;resolvedHref&quot;&gt;
    &lt;Icon v-if=&quot;icon&quot; class=&quot;domain-icon&quot; :name=&quot;icon&quot; /&gt;
    &lt;slot /&gt;
  &lt;/UtilLink&gt;
&lt;/template&gt;</code></pre><p>这样一来：</p><ul><li>Markdown 里写的 <code>https://xxx</code> 外链 → 页面中变成指向 <code>/go?url=...</code> 的链接；</li><li>内部链接（ <code>/about</code> 、 <code>/posts/...</code> ）仍然直接跳内部路由，不走 <code>/go</code> 。</li></ul><p><strong>接入友链卡片</strong>：改造 <code>FriendLinkCard.vue</code><br><br>友链页 <code>link.vue</code> 使用的是 <code>app/components/partial/FriendLinkCard.vue</code> 这张卡片。原来的跳转逻辑是直接打开站点：</p><pre><code class="lang-ts">function navigateToSite() {
  if (props.siteUrl) {
    window.open(props.siteUrl, &#039;_blank&#039;)
  }
}</code></pre><p>改造后统一走 <code>/go</code> ：</p><pre><code class="lang-ts">function navigateToSite() {
  if (!props.siteUrl)
    return

  const target = `/go?url=${encodeURIComponent(props.siteUrl)}`
  window.open(target, &#039;_blank&#039;)
}</code></pre><p>效果：</p><ul><li>友链页面点“前往网站”时，不再直接打开友链，而是新开一个 <code>/go</code> 标签页；</li><li><code>/go</code> 负责显示提示、倒计时和跳转；</li><li><p>返回时能够区分“新开标签页”这个场景，优先关闭自己，不干扰原来的 <code>link.vue</code> 页面滚动位置。</p><h3>一些踩坑 & 调整</h3><p>在实现过程中踩了几个小坑，顺手记一下。</p></li></ul><p><strong>1. 链接合法性校验过于严格导致按钮点不了</strong>  <br>一开始「继续访问」按钮的禁用逻辑是：</p><pre><code class="lang-vue">&lt;button
  :disabled=&quot;!isValidExternal&quot;
  @click=&quot;proceed&quot;
&gt;
  继续访问
&lt;/button&gt;</code></pre><p>而 <code>isValidExternal</code> 是通过 <code>new URL(decodedUrl)</code> + 协议判断实现的。这样做的初衷是安全：</p><p>URL 缺失、编码错误、协议不是 http/https → 认为不安全，按钮禁用。<br>但实际使用时：</p><p>我们对外链统一做了 <code>encodeURIComponent</code> ；<br>中间一旦出现编码/解码上的处理差异， <code>isValidExternal</code> 就可能是 <code>false</code> ；<br>结果就是：<strong>页面能显示链接，倒计时能自动跳转，但按钮一直是禁用状态，用户手动点不了</strong>。<br>后面改成：</p><ul><li><code>isValidExternal</code> 只用于显示信息（例如显示域名、显示“链接无效或缺失”）；</li><li><p>按钮本身不再绑定禁用条件，始终可点，真正的兜底放在<code>proceed()</code>里：</p><pre><code class="lang-ts">function proceed() {
const target = decodedUrl.value || rawUrl.value
if (!target)
  return

clearCountdown()
window.location.href = target
}</code></pre><p>这样既保留了一定的安全感知，又不至于影响正常访问。</p></li></ul><p><strong>2. 返回上一页导致滚动位置混乱</strong>  <br>友链卡片是通过 <code>window.open</code> 新开 <code>/go</code> 标签页的，但 <code>/go</code> 一开始是这么写的：</p><pre><code class="lang-ts">function goBack() {
  if (history.length &gt; 1)
    history.back()
  else
    router.push(&#039;/&#039;)
}</code></pre><p>新标签页基本没有历史，所以会直接 <code>router.push(&#039;/&#039;)</code> 跳首页。视觉体验就是：</p><ul><li>你明明是从 <code>link.vue</code> 底部的友链区域点过来的；</li><li>点了「返回上一页」却去了首页，原来的页面滚动位置也被重置，看起来像是“底部组件跑到顶部”。</li></ul><p>重写后的 <code>goBack</code> 逻辑就解决了这个体验问题：</p><ul><li>新标签页优先 <code>window.close()</code> ；</li><li>同标签页用 <code>history.back()</code> ；</li><li>实在没有历史才兜底根据 <code>document.referrer</code> / 首页处理。</li></ul><h3>总结</h3><p>通过这次改造，博客里所有指定范围的外链都统一走了 <code>/go</code> 中转页，达到了类似 hexo-safego 的效果：</p><ul><li>用户在点击外链前会看到明确的提示；</li><li>可以手动选择继续访问或返回；</li><li>也支持倒计时自动跳转；</li><li>Markdown 正文和友链页都接入了这套逻辑。</li></ul><p>整体实现成本并不高，但能明显提升外链安全感知和交互体验。如果以后需要更严格的策略（例如只允许白名单域名、记录访问日志等），也可以在 <code>/go</code> 这个集中入口上继续扩展。</p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; [!NOTE]</p><blockquote><p>这篇文章来自<strong>AI</strong>整理，来自我的<a href="https://blog.zsxcoder.top">博客</a>。</p><p>想做一个类似 <a href="https://github.com/willow-god/hexo-safego"><code>hexo-safego</code></a> 的外链安全检测 / 中转效果，于是在自己的 Nuxt 博客里加了一个 <code>/go</code> 页面，用来统一接住外链，给用户一个“即将离开本站”的提醒和手动确认。</p></blockquote><p>这篇文章记录一下整个实现过程：从需求拆解，到 <code>go.vue</code> 的实现，再到 Markdown 外链、友链卡片接入中转页，以及中途踩到的几个小坑。</p><h2>背景 & 需求</h2><p>需求最初很简单：</p><ul><li>站内所有 <strong>外链</strong>（包括 Markdown 正文里的链接、友链页里的链接），点击时不要直接打开目标网站；</li><li><p>先跳到一个中转页 <code>/go?url=...</code>：</p><ul><li>提示“即将离开本站”；</li><li>显示目标链接和域名；</li><li>提供「继续访问」和「返回上一页」两个按钮；</li><li>支持几秒钟的倒计时，自动跳转；</li></ul></li><li>内部链接（例如 <code>/posts/...</code>、<code>/about</code>）保持原样，不走 <code>/go</code>。</li></ul><p>最后确定的范围是：</p><ul><li>Markdown 渲染组件 <code>ProseA.vue</code>（文章正文中的链接）；</li><li>友链页使用的 <code>FriendLinkCard.vue</code>（<code>link.vue</code> 页面中的友链卡片）。</li></ul><h2>实现 <code>/go</code> 页面</h2><p>首先在 <code>app/pages/go.vue</code> 新增一个页面，对应路由 <code>/go</code>。这个页面做几件事：</p><ol><li>从 query 参数里拿到原始链接 <code>url</code>；</li><li>做一层解码和合法性判断；</li><li>展示信息 + 倒计时；</li><li>处理手动「继续访问」和「返回上一页」。</li></ol><h3>解析 URL 与合法性判断</h3><pre><code class="lang-ts">&lt;script setup lang=&quot;ts&quot;&gt;
const route = useRoute()
const router = useRouter()

// 原始 query 参数
const rawUrl = computed(() =&gt; (route.query.url as string) || &#039;&#039;)

// 解码后的 URL：优先 decode，失败就回退到原始字符串，保证按钮始终有值可用
const decodedUrl = computed(() =&gt; {
  if (!rawUrl.value)
    return &#039;&#039;
  try {
    return decodeURIComponent(rawUrl.value)
  }
  catch {
    // 如果解码失败，回退使用原始字符串，保证按钮依然可用
    return rawUrl.value
  }
})

// 检查是否是一个合法的 http/https 外链
const isValidExternal = computed(() =&gt; {
  if (!decodedUrl.value)
    return false
  try {
    const u = new URL(decodedUrl.value)
    return u.protocol === &#039;http:&#039; || u.protocol === &#039;https:&#039;
  }
  catch {
    return false
  }
})

// 提取域名用于展示
const domain = computed(() =&gt; {
  if (!isValidExternal.value)
    return &#039;&#039;
  try {
    return new URL(decodedUrl.value).hostname
  }
  catch {
    return &#039;&#039;
  }
})</code></pre><p>这里有一个小细节：</p><ul><li>一开始如果 decodeURIComponent 失败，直接返回空字符串会导致后面一系列逻辑都认为“无效链接”，按钮会被禁用，看起来像“点不了”；</li><li><p>后来改为失败回退到 rawUrl ，只要 query 里有东西，最终就有一个可用字符串。</p><h3>倒计时和自动跳转</h3><pre><code class="lang-ts">const countdownSeconds = 5
const countdown = ref(countdownSeconds)
let countdownTimer: number | null = null

onMounted(() =&gt; {
if (!isValidExternal.value)
  return

countdown.value = countdownSeconds

countdownTimer = window.setInterval(() =&gt; {
  if (countdown.value &lt;= 1) {
    clearCountdown()
    proceed()
  }
  else {
    countdown.value -= 1
  }
}, 1000)
})

onUnmounted(() =&gt; {
clearCountdown()
})

function clearCountdown() {
if (countdownTimer != null) {
  clearInterval(countdownTimer)
  countdownTimer = null
}
}</code></pre><p>设计思路：</p></li><li>只要判断为合法外链，就从设定的秒数开始倒计时；</li><li>每秒减 1，减到 1 时自动调用 proceed() ；</li><li><p>页面销毁（路由离开）时清理定时器，避免内存泄漏或误触发。</p><h3>手动跳转和返回逻辑</h3><pre><code class="lang-ts">function proceed() {
const target = decodedUrl.value || rawUrl.value
if (!target)
  return

clearCountdown()
window.location.href = target
}

function goBack() {
clearCountdown()

// 1. 如果是通过 window.open 打开的新标签页，优先尝试关闭自己
if (window.opener &amp;&amp; window.opener !== window) {
  window.close()
  return
}

// 2. 有历史记录就正常返回
if (history.length &gt; 1) {
  history.back()
  return
}

// 3. 没有历史时，尝试根据同源 referrer 返回
if (document.referrer) {
  try {
    const ref = new URL(document.referrer)
    if (ref.origin === window.location.origin) {
      router.push(ref.pathname + ref.search + ref.hash)
      return
    }
  }
  catch {
    // ignore
  }
}

// 4. 兜底：回首页
router.push(&#039;/&#039;)
}
&lt;/script&gt;</code></pre><p>这里对「返回上一页」做了比较细的兼容：</p></li><li><strong>友链卡片那种新标签页场景</strong>：通过 window.open('/go?url=...', '_blank') 打开的 /go 页面，其实没有历史记录，这时 history.back() 是无效的，于是我们优先检测 window.opener ，直接 window.close() ，让原来的标签页停留在友链页不动；</li><li><strong>同标签页场景</strong>：有历史记录就走 history.back() ，行为和用户点浏览器后退按钮一致；</li><li><p><strong>没有历史、没有同源 referrer 的极端场景</strong>：最后才兜底跳首页。</p><h3>模板和样式</h3><p>模板部分主要就是展示提示、链接、按钮和倒计时：</p><pre><code class="lang-vue">&lt;template&gt;
&lt;div class=&quot;go-page&quot;&gt;
  &lt;div class=&quot;go-card&quot;&gt;
    &lt;h1 class=&quot;go-title&quot;&gt;即将离开本站&lt;/h1&gt;
    &lt;p class=&quot;go-desc&quot;&gt;
      你将要访问的外部链接：
    &lt;/p&gt;
    &lt;p v-if=&quot;isValidExternal&quot; class=&quot;go-url&quot;&gt;{{ decodedUrl }}&lt;/p&gt;
    &lt;p v-else class=&quot;go-url invalid&quot;&gt;链接无效或缺失&lt;/p&gt;

    &lt;p v-if=&quot;isValidExternal&quot; class=&quot;go-domain&quot;&gt;
      目标站点：&lt;strong&gt;{{ domain }}&lt;/strong&gt;
    &lt;/p&gt;

    &lt;div class=&quot;go-actions&quot;&gt;
      &lt;button type=&quot;button&quot; class=&quot;btn secondary&quot; @click=&quot;goBack&quot;&gt;
        返回上一页
      &lt;/button&gt;
      &lt;button
        type=&quot;button&quot;
        class=&quot;btn primary&quot;
        @click=&quot;proceed&quot;
      &gt;
        继续访问&lt;span v-if=&quot;domain&quot;&gt; {{ domain }}&lt;/span&gt;
      &lt;/button&gt;
    &lt;/div&gt;

    &lt;p v-if=&quot;isValidExternal&quot; class=&quot;go-countdown&quot;&gt;
      {{ countdown }} 秒后将自动跳转，如不希望跳转，请点击「返回上一页」
    &lt;/p&gt;

    &lt;p class=&quot;go-tip&quot;&gt;
      外部网站内容与本博客无关，请注意辨别信息和账号安全。
    &lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;</code></pre><p>样式部分使用了博客现有的变量（ <code>var(--c-text)</code>、 <code>var(--ld-bg-card)</code> 等），整体就是一个居中的卡片，这里不赘述。</p></li></ul><p><strong>接入 Markdown 外链：改造 <code>ProseA.vue</code></strong><br>博客的 Markdown 链接渲染组件是 <code>app/components/content/ProseA.vue</code> ，原来大致是：</p><ul><li>根据 <code>href</code> 判断是否外链；</li><li>用 <code>UtilLink</code> 渲染；</li><li>用 <code>v-tip</code> 显示域名或完整地址。</li></ul><p>为了让 Markdown 外链走 <code>/go</code> ，改动非常小，只需要在这里统一改造 <code>href</code> 即可：</p><pre><code class="lang-ts">const props = defineProps&lt;{
  href: string
  icon?: string
}&gt;()

const icon = computed(() =&gt; props.icon || getDomainIcon(props.href))
const isExternal = computed(() =&gt; isExtLink(props.href))

// 外链统一改成指向 /go?url=encodeURIComponent(href)
const resolvedHref = computed(() =&gt; (
  isExternal.value ? `/go?url=${encodeURIComponent(props.href)}` : props.href
))

const tip = computed(() =&gt; ({
  content: isExternal.value ? getDomain(props.href) : decodeURIComponent(props.href),
  inlinePositioning: true,
}))</code></pre><p>模板：</p><pre><code class="lang-Vue">&lt;template&gt;
  &lt;UtilLink v-tip=&quot;tip&quot; class=&quot;z-link&quot; :to=&quot;resolvedHref&quot;&gt;
    &lt;Icon v-if=&quot;icon&quot; class=&quot;domain-icon&quot; :name=&quot;icon&quot; /&gt;
    &lt;slot /&gt;
  &lt;/UtilLink&gt;
&lt;/template&gt;</code></pre><p>这样一来：</p><ul><li>Markdown 里写的 <code>https://xxx</code> 外链 → 页面中变成指向 <code>/go?url=...</code> 的链接；</li><li>内部链接（ <code>/about</code> 、 <code>/posts/...</code> ）仍然直接跳内部路由，不走 <code>/go</code> 。</li></ul><p><strong>接入友链卡片</strong>：改造 <code>FriendLinkCard.vue</code><br><br>友链页 <code>link.vue</code> 使用的是 <code>app/components/partial/FriendLinkCard.vue</code> 这张卡片。原来的跳转逻辑是直接打开站点：</p><pre><code class="lang-ts">function navigateToSite() {
  if (props.siteUrl) {
    window.open(props.siteUrl, &#039;_blank&#039;)
  }
}</code></pre><p>改造后统一走 <code>/go</code> ：</p><pre><code class="lang-ts">function navigateToSite() {
  if (!props.siteUrl)
    return

  const target = `/go?url=${encodeURIComponent(props.siteUrl)}`
  window.open(target, &#039;_blank&#039;)
}</code></pre><p>效果：</p><ul><li>友链页面点“前往网站”时，不再直接打开友链，而是新开一个 <code>/go</code> 标签页；</li><li><code>/go</code> 负责显示提示、倒计时和跳转；</li><li><p>返回时能够区分“新开标签页”这个场景，优先关闭自己，不干扰原来的 <code>link.vue</code> 页面滚动位置。</p><h3>一些踩坑 & 调整</h3><p>在实现过程中踩了几个小坑，顺手记一下。</p></li></ul><p><strong>1. 链接合法性校验过于严格导致按钮点不了</strong>  <br>一开始「继续访问」按钮的禁用逻辑是：</p><pre><code class="lang-vue">&lt;button
  :disabled=&quot;!isValidExternal&quot;
  @click=&quot;proceed&quot;
&gt;
  继续访问
&lt;/button&gt;</code></pre><p>而 <code>isValidExternal</code> 是通过 <code>new URL(decodedUrl)</code> + 协议判断实现的。这样做的初衷是安全：</p><p>URL 缺失、编码错误、协议不是 http/https → 认为不安全，按钮禁用。<br>但实际使用时：</p><p>我们对外链统一做了 <code>encodeURIComponent</code> ；<br>中间一旦出现编码/解码上的处理差异， <code>isValidExternal</code> 就可能是 <code>false</code> ；<br>结果就是：<strong>页面能显示链接，倒计时能自动跳转，但按钮一直是禁用状态，用户手动点不了</strong>。<br>后面改成：</p><ul><li><code>isValidExternal</code> 只用于显示信息（例如显示域名、显示“链接无效或缺失”）；</li><li><p>按钮本身不再绑定禁用条件，始终可点，真正的兜底放在<code>proceed()</code>里：</p><pre><code class="lang-ts">function proceed() {
const target = decodedUrl.value || rawUrl.value
if (!target)
  return

clearCountdown()
window.location.href = target
}</code></pre><p>这样既保留了一定的安全感知，又不至于影响正常访问。</p></li></ul><p><strong>2. 返回上一页导致滚动位置混乱</strong>  <br>友链卡片是通过 <code>window.open</code> 新开 <code>/go</code> 标签页的，但 <code>/go</code> 一开始是这么写的：</p><pre><code class="lang-ts">function goBack() {
  if (history.length &gt; 1)
    history.back()
  else
    router.push(&#039;/&#039;)
}</code></pre><p>新标签页基本没有历史，所以会直接 <code>router.push(&#039;/&#039;)</code> 跳首页。视觉体验就是：</p><ul><li>你明明是从 <code>link.vue</code> 底部的友链区域点过来的；</li><li>点了「返回上一页」却去了首页，原来的页面滚动位置也被重置，看起来像是“底部组件跑到顶部”。</li></ul><p>重写后的 <code>goBack</code> 逻辑就解决了这个体验问题：</p><ul><li>新标签页优先 <code>window.close()</code> ；</li><li>同标签页用 <code>history.back()</code> ；</li><li>实在没有历史才兜底根据 <code>document.referrer</code> / 首页处理。</li></ul><h3>总结</h3><p>通过这次改造，博客里所有指定范围的外链都统一走了 <code>/go</code> 中转页，达到了类似 hexo-safego 的效果：</p><ul><li>用户在点击外链前会看到明确的提示；</li><li>可以手动选择继续访问或返回；</li><li>也支持倒计时自动跳转；</li><li>Markdown 正文和友链页都接入了这套逻辑。</li></ul><p>整体实现成本并不高，但能明显提升外链安全感知和交互体验。如果以后需要更严格的策略（例如只允许白名单域名、记录访问日志等），也可以在 <code>/go</code> 这个集中入口上继续扩展。</p>]]></content:encoded>
        </item>
                <item>
            <title>Hexo备忘</title>
            <link>https://blog.zsx815.top/archives/16/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/16/</guid>
            <pubDate>Sat, 16 Aug 25 22:11:00 +0800</pubDate>
            <pubDateFormatted>2025年08月16日22:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown--># Hexo 备忘</p><h2>我的配置</h2><ol><li><strong>Hexo 版本</strong>: hexo-cli: 4.3.2, hexo: 7.3.0(当前最新)</li><li><strong>Node.js 版本</strong>: 22.16.0</li><li><strong>Git 版本</strong>: 2.47.0.sindows.2</li><li><strong>PNPM 版本</strong>: 10.12.4</li><li><strong>Windows 版本</strong>: 11</li></ol><h2>安装 Node.js</h2><ol><li>在 <a href="https://nodejs.org/en/download/">官网</a> 安装 LTS 版本，电脑一般来说内存足够直接在 C 盘即可，当然，换路径也可以，我反正正常下载换路径，没什么问题。</li><li>安装完成后，检查是否安装成功。在键盘按下 <kbd> win </kbd> + <kbd> R </kbd> 键，输入 <code>CMD</code>，然后回车，打开 CMD 窗口，执行 <code>node -v</code> 命令，看到版本信息，则说明安装成功。</li></ol><h2>安装 Git</h2><p>在 <a href="https://git-scm.com/download/win">官网</a> 安装最新版本的 <code>64-bit Git for Windows Setup</code> 安装包。  </p><p>安装完成后，在命令行输入 <code>git --version</code>，如果显示版本号，则说明安装成功。</p><h3>常用命令</h3><pre><code class="lang-bash">git config -l  //查看所有配置
git config --system --list //查看系统配置
git config --global --list //查看用户（全局）配置</code></pre><h3>配置 Git 用户名和邮箱</h3><pre><code class="lang-bash">git config --global user.name &quot;你的用户名&quot;
git config --global user.email &quot;你的邮箱&quot;</code></pre><h2>安装 包管理器</h2><p>安装 npm 为一切的基石，一般来说，你安装了 node，也相当于你安装了 npm，通过一下命令来验证：</p><pre><code class="lang-bash">npm -v
node -v</code></pre><p><strong>修改 npm 源</strong>。npm 下载各种模块，默认是从国外服务器下载，速度较慢，建议配置成淘宝镜像。打开 CMD 窗口，运行如下命令:</p><pre><code class="lang-bash">npm config set registry https://registry.npm.taobao.org</code></pre><h3>安装 pnpm</h3><p>pnpm 是一个快速、节省磁盘空间的包管理器，类似于 npm 和 yarn。安装 pnpm 可以通过以下命令：</p><pre><code class="lang-bash">npm install -g pnpm</code></pre><p>为什么选择 pnpm？因为它的安装速度快，依赖管理更高效，且相对于 npm，我使用 npm 容易失败且慢，pnpm 给我的体验更好。</p><h2>安装 Hexo</h2><ol><li>在 Git BASH 输入如下命令安装 Hexo：</li></ol><pre><code class="lang-bash">pnpm install -g hexo-cli</code></pre><ol start="2"><li>安装完后输入 <code>hexo -v</code> 验证是否安装成功。</li></ol><hr><h2><a id="github-config"></a>Github配置</h2><blockquote>上述操作是前提，接下来是配置 Github。</blockquote><p>注册 github 就不说了，很基础的东西，连我个代码小白都懂就不多说了。</p><h3>创建仓库</h3><ol><li>登录 GitHub，点击右上角的 <code>+</code> 号，选择 <code>New repository</code>。</li><li>填写仓库名称，建议使用 <code>&lt;username&gt;.github.io</code> 格式（例如：<code>yourusername.github.io</code>），这样可以直接作为个人主页。</li></ol><p>这里我不准备直接使用常规的 <code>hexo deploy</code> 命令来部署到 GitHub Pages，因为当你的文章一多，生成时间就会繁琐，这里的建议是使用 <code>Github Actions</code> 来自动部署。</p><blockquote>这一部分的教程是源于 <a href="https://akilar.top/posts/f752c86d/">店长的文章</a>，但是有点老旧了，于是我做了点更改（这里的图片来源于 <a href="https://blog.anheyu.com/posts/asdx.html">安知鱼</a>）：</blockquote><ol><li>首先要创建一个放置源码的私有仓库，以下称之为 <code>hexo-source</code>，</li><li>然后要生成一个 Github 密钥：</li></ol><blockquote>访问 Github-&gt; 头像（右上角）-&gt; Settings-&gt; Developer Settings-&gt; Personal access tokens-&gt; generate new token, 创建的 Token 名称随意，但必须勾选 repo 项 和 workflows 项。</blockquote><p>点击 <a href="https://github.com/settings/tokens">链接</a> 前往生成</p><p><img src="https://img.314926.xyz/images/2025/08/17/jiaoxue1.webp" alt="" title=""><br><img src="https://img.314926.xyz/images/2025/08/17/jiaoxue2.webp" alt="" title=""></p><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">ℹ️ 提示</strong><br>
<span style="color: #ff6600;">!!! token 只会显示这一次，之后将无法查看，所以务必保证你已经记录下了 Token。之后如果忘记了就只能重新生成重新配置了。</span>
</div><ol start="3"><li><p>在 <code>hexo-source</code> 仓库中的设置里点击设置 -&gt; action -&gt; General -&gt; 工作流程权限</p><ul><li>勾选 <code>Read and write permissions</code>，并且勾选 <code>Allow &lt;span style=&quot;background:#FF0000;&quot;&gt;&lt;/span&gt;all actions and reusable workflows</code>。</li></ul></li><li>在设置里 -&gt; Secrets and variables -&gt; Actions -&gt; New repository secret 添加</li><li><code>GITHUBTOKEN</code>：放置你刚才生成的 Token。</li></ol><hr><h2>上述是前置条件，接下来要先部署 hexo，你才好继续下一步。</h2><h2>初始化 Hexo</h2><ol><li>在本地新建一个文件夹，例如 <code>hexo-solitude</code>。</li><li>这里我是用的是 vscode 打开该文件夹，然后在终端输入以下命令来初始化 Hexo：</li></ol><pre><code class="lang-bash">hexo init (项目名称)</code></pre><p>我一般都不填，直接在文件下下就可以开始，如果你添加了项目名称，那么下一步就是：</p><pre><code class="lang-bash">cd (项目名称)</code></pre><ol start="3"><li>安装依赖包：</li></ol><pre><code class="lang-bash">pnpm install</code></pre><p>然后就是选择你想要的主题，这里我使用的是<a href="https://solitude.js.org/cn/getting-started/installation">Solitude</a>，具体的配置不细讲，我只讲一部分：</p><p>首先就是基本的安装，这里还是选择<code>git clone</code>没有别的原因，主要还是会改点源码，不想改的直接pnpm下载即可：</p><pre><code>// git安装
git clone -b dev https://github.com/everfu/hexo-theme-solitude.git themes/solitude

// pnpm 安装
pnpm i hexo-theme-solitude</code></pre><p>然后在<code>_config.yml</code>里修改成：</p><pre><code class="lang-yml">theme: solitude</code></pre><h2>配置</h2><p>下列代码是我的备忘：</p><pre><code class="lang-yml"># Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title: 喵落阁
subtitle: &#039;克喵的博客&#039;
description: &#039;愿你看清一切真相后，依旧热爱你的家人和朋友。&#039;
keywords: 克喵,kemiao,博客
author: 克喵爱吃卤面
language: zh-CN
timezone: &#039;Asia/Shanghai&#039;

# URL
## Set your site url here. For example, if you use GitHub Page, set url as &#039;https://username.github.io/project&#039;
url: # 填网站地址
permalink: posts/:abbrlink.html
permalink_defaults:
pretty_urls:
  trailing_index: true # Set to false to remove trailing &#039;index.html&#039; from permalinks
  trailing_html: true # Set to false to remove trailing &#039;.html&#039; from permalinks

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
  enable: true # Open external links in new tab
  field: site # Apply to the whole site
  exclude: &#039;&#039;
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
syntax_highlighter: highlight.js
highlight:
  line_number: false
  auto_detect: false
  tab_replace: &#039;&#039;
  wrap: true
  hljs: false
prismjs:
  preprocess: true
  line_number: true
  tab_replace: &#039;&#039;

# Home page setting
# path: Root path for your blogs index page. (default = &#039;&#039;)
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
  path: &#039;&#039;
  per_page: 10
  order_by: -date

# Category &amp; Tag
default_category: uncategorized
category_map:
tag_map:

# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports &#039;mtime&#039;, &#039;date&#039;, &#039;empty&#039;
updated_option: &#039;mtime&#039;

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Include / Exclude file(s)
## include:/exclude: options only apply to the &#039;source/&#039; folder
include: []
exclude: []
ignore: []

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: solitude

# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
  type: git
  repo: git@github.com-xx:kemiaofxjun/kemiaofxjun.github.io.git
  branch: main

# RSS Feed 配置
feed:
  type: atom          # 生成 atom.xml
  path: atom.xml      # 输出文件名
  limit: 20           # 最多显示文章数 (0=全部)
  hub:                # PubSubHubbub 中心 (可选)
  content: true       # 是否包含全文内容 (true=是, false=仅摘要)
  content_limit: 140  # 摘要长度（当 content=false 时生效）
  content_limit_delim: &#039; &#039;  # 截断分隔符
  order_by: -date     # 按日期倒序排列
  autodiscovery: true # 在 HTML 头部添加自动发现标签

# 数学公式渲染配置
markdown:
  preset: &#039;default&#039; # 使用的 MD 语法，默认使用的 GFM
  render:
    html: true # 渲染 html
    xhtmlOut: false
    langPrefix: &#039;language-&#039; # 在代码块的类名中添加前缀（指定语言时）。
    breaks: true
    linkify: true # 如果你写了一个链接而不是 [name](link) 方式，会自动识别为链接并渲染。
    typographer: true # 将替换常见的印刷元素。
    quotes: &#039;“”‘’&#039; # 替换文章张的 &quot;&quot; &#039;&#039; 号
  enable_rules:
  disable_rules:
  plugins: # 使用插件
  anchors:
    level: 2 # 渲染标题的级别（h1,h2,h3）
    collisionSuffix: &#039;&#039;
    permalink: true
    permalinkClass: &#039;headerlink&#039;
    permalinkSide: &#039;left&#039;
    permalinkSymbol: &#039;&#039;
    case: 0
    separator: &#039;-&#039;
  images: # 图片的一些编译
    lazyload: true # 是否需要渲染 lazyload
    prepend_root: false
    post_asset: false
  inline: false

swpp:
  # 是否启用插件
  enable: true
  # 是否在发布前自动执行脚本
  auto_exec: true
  gen_dom: true

# 文章链接转数字或字母：https://github.com/rozbo/hexo-abbrlink
abbrlink:
    alg: crc16   #算法： crc16(default) and crc32
    rep: hex     #进制： dec(default) and hex: dec #输出进制：十进制和十六进制，默认为10进制。丨dec为十进制，hex

# https://github.com/hexojs/hexo-generator-sitemap
sitemap:
  path: sitemap.xml
  rel: false
  tags: true
  categories: true

algolia:
  appId: &quot;&quot;
  apiKey: &quot;&quot;
  adminApiKey: &quot;&quot;
  chunkSize: 5000
  indexName: &quot;index-name&quot;
  fields:
    - content:strip:truncate,0,500
    - excerpt:strip
    - gallery
    - permalink
    - photos
    - slug
    - tags
    - title

# hexo-safego安全跳转插件
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
  # 基本功能设置
  general:
    enable: true                # 启用插件
    enable_base64_encode: true  # 使用 Base64 编码
    enable_target_blank: true   # 从新窗口打开跳转页面

  # 安全设置
  security:
    url_param_name: &#039;u&#039;         # URL 参数名
    html_file_name: &#039;go.html&#039;   # 重定向页面的文件名
    ignore_attrs:               # 忽略处理的 HTML 结构
      - &#039;data-fancybox&#039;

  # 容器与页面设置
  scope:
    apply_containers:           # 应用的容器选择器
      - &#039;#article-container&#039;
    apply_pages:                # 应用的页面路径
      - &quot;/posts/&quot;
      - &quot;/devices/&quot;
    exclude_pages:              # 排除的页面路径

  # 域名白名单
  whitelist:
    domain_whitelist:           # 允许的白名单域名，通过字符串匹配实现
      - &quot;kemeow.top&quot;
      - &quot;kemiaosw.top&quot;
      - &quot;050815.xyz&quot;
      - &quot;314926.xyz&quot;
      - &quot;051531.xyz&quot;

  # 页面外观设置
  appearance:
    avatar: https://img.314926.xyz/images/2025/08/13/no-background-kemiaofxjun.webp   # 跳转页面头像路径
    title: &quot;喵洛阁&quot;            # 跳转页面标题
    subtitle: &quot;安全中心&quot;         # 跳转页面副标题
    darkmode: auto              # 是否启用深色模式
    countdowntime: 4            # 跳转页面倒计时秒数，如果设置为负数则为不自动跳转

  # 调试设置
  debug:
    enable: false               # 启用调试模式

# 追番插件
# https://github.com/HCLonely/hexo-bilibili-bangumi
bangumi: # 追番设置
  enable: true
  source: bili
  path: 
  vmid: 3546643173477234
  title: &quot;追番列表&quot;
  quote: &quot;生命不息，追番不止！&quot;
  show: 1
  lazyload: false
  loading:
  showMyComment: true
  pagination: false
  extra_options:
    top_img: false
    lazyload:
      enable: false
</code></pre><p>博客的其他修改基本就是来自教程和一些博主的网站。</p><hr><h2>插件</h2><ol><li><strong>基础依赖</strong> <code>hexo-renderer-pug</code></li></ol><pre><code class="lang-bash">pnpm i hexo-renderer-pug</code></pre><hr><ol start="2"><li><strong>字数统计</strong> <code>hexo-wordcount</code></li></ol><pre><code class="lang-bash">pnpm i hexo-wordcount</code></pre><p>配置里修改：</p><pre><code class="lang-yml"># --------------------------- start ---------------------------
# Word count
# 字数统计
# warning: Please install the hexo-wordcount plugin first.
# 警告: 请先安装 hexo-wordcount 插件。
wordcount: false
# --------------------------- end ---------------------------</code></pre><hr><ol start="3"><li><strong>数学公式</strong> 卸载 <code>hexo-render-marked</code></li></ol><pre><code class="lang-bash">npm un hexo-renderer-marked</code></pre><p>安装 <code>hexo-renderer-markdown-it</code> <code>katex</code> <code>@renbaoshuo/markdown-it-katex</code></p><pre><code class="lang-bash">pnpm i hexo-renderer-markdown-it katex @renbaoshuo/markdown-it-katex</code></pre><p>配置里修改</p><pre><code class="lang-yml"># --------------------------- start ---------------------------
# Katex
# Latex formula support
# Latex 公式支持
katex:
  enable: false
  # Whether to load on each page
  # 是否在每个页面加载
  per_page: false
  # Whether to enable copy formula
  # 是否启用复制公式
  copytex: false
# --------------------------- end ---------------------------</code></pre><p>添加以下内容到 <code>_config.yml</code></p><pre><code class="lang-yml">markdown:
  preset: &#039;default&#039;
  render:
    html: true
    xhtmlOut: false
    langPrefix: &#039;language-&#039;
    breaks: true
    linkify: true
    typographer: true
    quotes: &#039;“”‘’&#039;
  enable_rules:
  disable_rules:
  plugins:
    - &#039;@renbaoshuo/markdown-it-katex&#039;
  anchors:
    level: 2
    collisionSuffix: &#039;&#039;
    permalink: false
    permalinkClass: &#039;header-anchor&#039;
    permalinkSide: &#039;left&#039;
    permalinkSymbol: &#039;¶&#039;
    case: 0
    separator: &#039;-&#039;
  images:
    lazyload: false
    prepend_root: false
    post_asset: false
  inline: false  # https://markdown-it.github.io/markdown-it/#MarkdownIt.renderInline</code></pre><p>开启配置项</p><pre><code class="lang-yml"># --------------------------- start ---------------------------
# Katex
# Latex formula support
# Latex 公式支持
katex:
  enable: true
  # Whether to load on each page
  # 是否在每个页面加载
  per_page: true
  # Whether to enable copy formula
  # 是否启用复制公式
  copytex: false
# --------------------------- end ---------------------------
</code></pre><hr><ol start="4"><li><strong>PWA</strong> 安装 hexo-swpp 和 swpp-backends 插件</li></ol><p>在博客根目录执行</p><pre><code class="lang-bash">pnpm i hexo-swpp 

pnpm i swpp-backends</code></pre><p>开启配置</p><pre><code class="lang-yml"># 大约在773行
# --------------------------- start ---------------------------
# PWA
# Progressive Web App
pwa:
  enable: true
  manifest: /manifest.json # manifest.json
  theme_color: &quot;#006a73&quot; # Theme color
  mask_icon: /img/pwa/favicon.png # Mask icon
  apple_touch_icon: /img/pwa/favicon.png # Apple touch icon
  bookmark_icon: /img/pwa/favicon.png # Bookmark icon
  favicon_32_32: /img/pwa/favicon_32.png # 32x32 icon
  favicon_16_16: /img/pwa/favicon_16.png # 16x16 icon
# --------------------------- end ---------------------------
</code></pre><p>在<code>_config.yml</code>里添加swpp配置</p><pre><code class="lang-yml">swpp:
  # 是否启用插件
  enable: true
  # 是否在发布前自动执行脚本
  auto_exec: true
  gen_dom: true</code></pre><p>在 <code>source</code> 目录中创建 <code>manifest.json</code> 文件</p><pre><code class="lang-json">{
    &quot;name&quot;: &quot;网站名称&quot;,
    &quot;short_name&quot;: &quot;网站名称缩写&quot;,
    &quot;theme_color&quot;: &quot;#006a73&quot;,
    &quot;background_color&quot;: &quot;#006a73&quot;,
    &quot;display&quot;: &quot;fullscreen&quot;,
    &quot;scope&quot;: &quot;/&quot;,
    &quot;start_url&quot;: &quot;/&quot;,
    &quot;id&quot;: &quot;/&quot;,
    &quot;icons&quot;: [
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_16.png&quot;,
        &quot;sizes&quot;: &quot;16x16&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;any&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_16.png&quot;,
        &quot;sizes&quot;: &quot;16x16&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;maskable&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_32.png&quot;,
        &quot;sizes&quot;: &quot;32x32&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;any&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_32.png&quot;,
        &quot;sizes&quot;: &quot;32x32&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;maskable&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon.png&quot;,
        &quot;sizes&quot;: &quot;180x180&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;any&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon.png&quot;,
        &quot;sizes&quot;: &quot;180x180&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;maskable&quot;
      }
    ],
    &quot;splash_pages&quot;: null
}
</code></pre><p>在博客根目录创建一个 <code>sw-rules.js</code> 文件</p><pre><code class="lang-js">module.exports.config = {
  /** @type {?ServiceWorkerConfig|boolean} */
  serviceWorker: {
    escape: 1,
    cacheName: &#039;SolitudeCache&#039;,
    debug: false,
  },
  register: {
    onsuccess: undefined,
    onerror: () =&gt;
      console.error(
        &#039;Service Worker 注册失败！可能是由于您的浏览器不支持该功能！&#039;
      ),
    builder: (root, framework, pluginConfig) =&gt; {
      const { onerror, onsuccess } = pluginConfig.register;
      return `
            &lt;script&gt;
                (() =&gt; {
                    const sw = navigator.serviceWorker;
                    const error = ${onerror &amp;&amp; onerror.toString()};
                    if (!sw?.register(&#039;${new URL(root).pathname}sw.js&#039;)
                        ${onsuccess ? `?.then(${onsuccess.toString()})` : &quot;&quot;}
                        ?.catch(error)
                    ) error()
                })()
            &lt;/script&gt;`;
    },
  },
  /** @type {?DomConfig|boolean} */
  dom: {
    /** @type {?VoidFunction} */
    onsuccess: () =&gt; {
      caches
        .match(&#039;https://id.v3/&#039;)
        .then((res) =&gt; {
          if (res)
            res.json().then((json) =&gt; {
              utils &amp;&amp;
                utils.snackbarShow(
                  `已刷新缓存，更新为${json.escape + &#039;.&#039; + json.global + &#039;.&#039; + json.local
                  }版本最新内容`,
                  false,
                  2500
                );
            });
          else console.info(&#039;未找到缓存&#039;);
        })
        .catch((error) =&gt; console.error(&#039;缓存匹配出错&#039;, error));
    },
  },
  /** @type {?VersionJsonConfig|boolean} */
  json: {
    /** @type {number} */
    maxHtml: 15,
    /** @type {number} */
    charLimit: 1024,
    /** @type {string[]} */
    merge: [],
    exclude: {
      /** @type {RegExp[]} */
      localhost: [],
      /** @type {RegExp[]} */
      other: [],
    },
  },
  /** @type {?ExternalMonitorConfig|boolean} */
  external: {
    /** @type {number} */
    timeout: 5000,
    /** 拉取文件时地并发限制 */
    concurrencyLimit: 100,
    /** @type {({head: string, tail: string}|function(string):string[])[]} */
    js: [],
    /** @type {RegExp[]} */
    stable: [
      /^https:\/\/npm\.elemecdn\.com\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
      /^https:\/\/cdn\.cbd\.int\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
      /^https:\/\/cdn\.jsdelivr\.net\/npm\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
    ],
    replacer: (srcUrl) =&gt; {
      if (srcUrl.startsWith(&#039;https://cdn.jsdelivr.net/npm/&#039;)) {
        const pathname = new URL(srcUrl).pathname;
        return [
          srcUrl,
          `https://cdn.cbd.int/${pathname}`,
          `https://npm.elemecdn.com/${pathname}`,
          `https://fastly.jsdelivr.net/npm/${pathname}`,
        ];
      } else {
        return srcUrl;
      }
    },
  },
};

module.exports.cacheRules = {
  simple: {
    clean: true,
    search: false,
    match: (url, $eject) =&gt;
      url.host === $eject.domain &amp;&amp; [&#039;/404.html&#039;].includes(url.pathname),
  },
  cdn: {
    clean: true,
    match: (url) =&gt;
      [
        &#039;cdn.cbd.int&#039;,
        &#039;lf26-cdn-tos.bytecdntp.com&#039;,
        &#039;lf6-cdn-tos.bytecdntp.com&#039;,
        &#039;lf3-cdn-tos.bytecdntp.com&#039;,
        &#039;lf9-cdn-tos.bytecdntp.com&#039;,
        &#039;cdn.staticfile.org&#039;,
        &#039;npm.elemecdn.com&#039;,
      ].includes(url.host) &amp;&amp;
      url.pathname.match(/\.(js|css|woff2|woff|ttf|cur)$/),
  },
};

module.exports.getSpareUrls = (srcUrl) =&gt; {
  if (srcUrl.startsWith(&#039;https://npm.elemecdn.com&#039;)) {
    return {
      timeout: 3000,
      list: [
        srcUrl,
        `https://fastly.jsdelivr.net/${new URL(srcUrl).pathname}`,
      ],
    };
  }
};

module.exports.ejectValues = (hexo, rules) =&gt; {
  return {
    domain: {
      prefix: &#039;const&#039;,
      value: new URL(hexo.config.url).host,
    },
  };
};

module.exports.skipRequest = (request) =&gt; request.url.startsWith(&quot;https://i0.hdslb.com&quot;) ||
  request.url.startsWith(&#039;https://meting.qjqq.cn&#039;) ||
  request.url.startsWith(&#039;https://api.i-meto.com&#039;);</code></pre><hr><ol start="5"><li><strong><a href="https://github.com/hexojs/hexo-deployer-git">hexo-deploy-git</a></strong> 提交到git的插件</li></ol><pre><code class="lang-bash">pnpm i hexo-deploy-git --save</code></pre><hr><ol start="6"><li><strong><a href="https://github.com/hexojs/hexo-generator-feed">hexo-generator-feed</a></strong> hexo的rss插件</li></ol><pre><code class="lang-bash">pnpm i hexo-generator-feed --save</code></pre><hr><ol start="7"><li><strong><a href="https://github.com/ohroy/hexo-abbrlink">hexo 的短链接</a></strong>: <code>hexo-abbrlink</code></li></ol><pre><code class="lang-bash">pnpm i hexo-abbrlink --save</code></pre><p>在<code>_config.yml</code>里修改：</p><pre><code class="lang-yml">permalink: posts/:abbrlink/ 
# or
permalink: posts/:abbrlink.html</code></pre><p>添加:</p><pre><code class="lang-yml"># abbrlink config
abbrlink:
  alg: crc32      # Algorithm used to calc abbrlink. Support crc16(default) and crc32
  rep: hex        # Representation of abbrlink in URLs. Support dec(default) and hex
  drafts: false   # Whether to generate abbrlink for drafts. (false in default)
  force: false    # Enable force mode. In this mode, the plugin will ignore the cache, and calc the abbrlink for every post even it already had an abbrlink. (false in default)
  writeback: true # Whether to write changes to front-matters back to the actual markdown files. (true in default)</code></pre><hr><ol start="8"><li><strong><a href="https://github.com/hexojs/hexo-generator-sitemap">博客的sitemap</a></strong> : <code>hexo-generator-sitemap</code></li></ol><pre><code class="lang-bash">pnpm i hexo-generator-sitemap --save</code></pre><p>在<code>_config.yml</code>里添加配置：</p><pre><code class="lang-yml">sitemap:
  path: 
    - sitemap.xml
    - sitemap.txt
  template: ./sitemap_template.xml
  template_txt: ./sitemap_template.txt
  rel: false
  tags: true
  categories: true</code></pre><hr><ol start="9"><li><a href="https://www.mebi.me/hexo-with-algolia"><strong>使用algolia搜索</strong></a> : <code>hexo-algoliasearch</code></li></ol><ul><li>注册algolia：</li></ul><p>注册地址：<a href="https://dashboard.algolia.com/users/sign_up">dashboard.algolia.com/users/sign_up</a></p><ul><li>创建应用：</li></ul><p>注册成功后创建应用：<a href="https://dashboard.algolia.com/account/plan/create?from=dashboard">dashboard.algolia.com/account/plan/create?from=dashboard</a></p><ul><li>search -&gt; configure -&gt; index添加index_name即可</li></ul><p>在博客执行命令：</p><pre><code class="lang-bash">pnpm i hexo-algoliasearch --save</code></pre><p><code>_config.yml</code>里添加</p><pre><code class="lang-yml">algolia:
  appId: &quot;Z7A3XW4R2I&quot;
  apiKey: &quot;12db1ad54372045549ef465881c17e743&quot;
  adminApiKey: &quot;40321c7c207e7f73b63a19aa24c4761b&quot;
  chunkSize: 5000
  indexName: &quot;my-hexo-blog&quot;
  fields:
    - content:strip:truncate,0,500
    - excerpt:strip
    - gallery
    - permalink
    - photos
    - slug
    - tags
    - title</code></pre><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">ℹ️ 提示</strong><br>
<span style="color: #ff6600;">**!!!配置完成后记得运行 `hexo clean`**</span>
</div><p>在<code>hexo g </code>后实行下列代码：</p><pre><code class="lang-bash">hexo algolia</code></pre><hr><ol start="10"><li><strong><a href="https://blog.liushen.fun/posts/1dfd1f41/">hexo-safego</a></strong>安全跳转插件</li></ol><p>使用该插件之前，需要先安装 <code>cheerio</code>，<code>cheerio</code> 是一个轻量级的库，用于在服务器端快速、灵活地实现 jQuery 核心功能。在 <code>hexo-safego</code> 插件中，<code>cheerio</code> 被用来解析和操作生成的静态 HTML 内容，类似于在浏览器中使用 jQuery 处理 DOM 元素。这使得插件能够在生成静态页面时，处理和替换外部链接，增强博客的安全性，而不需要在客户端引入 jQuery。Hexo 一般都有这个插件，可以在 <code>node_modules</code> 查看，如果没有，请先执行：</p><pre><code class="lang-bash">pnpm i cheerio --save</code></pre><p>然后即可安装该插件：</p><pre><code class="lang-bash">pnpm i hexo-safego --save</code></pre><p>在<code>hexo</code>根目录的<code>_config.yml</code>文件中添加以下配置：</p><pre><code class="lang-yml"># hexo-safego安全跳转插件
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
  # 基本功能设置
  general:
    enable: true                # 启用插件
    enable_base64_encode: true  # 使用 Base64 编码
    enable_target_blank: true   # 打开新窗口
  # 安全设置
  security:
    url_param_name: &#039;u&#039;         # URL 参数名
    html_file_name: &#039;go.html&#039;   # 重定向页面的文件名
    ignore_attrs:               # 忽略处理的 HTML 属性
      - &#039;data-fancybox&#039;
  # 容器与页面设置
  scope:
    apply_containers:           # 应用的容器选择器
      - &#039;#article-container&#039;
    apply_pages:                # 应用的页面路径
      - &quot;/posts/&quot;
      - &quot;/devices/&quot;
    exclude_pages:              # 排除的页面路径
  # 域名白名单
  whitelist:
    domain_whitelist:           # 允许的白名单域名
      - &quot;qyliu.top&quot;
      - &quot;liushen.fun&quot;
  # 页面外观设置
  appearance:
    avatar: /info/avatar.ico    # 头像路径
    title: &quot;清羽飞扬&quot;            # 页面标题
    subtitle: &quot;安全中心&quot;         # 页面副标题
    darkmode: true              # 是否启用深色模式
    countdowntime: -1           # 倒计时秒数
  # 调试设置
  debug:
    enable: false               # 启用调试模式</code></pre><ol start="11"><li><strong>hexo的追番页面</strong>：<a href="https://github.com/HCLonely/hexo-bilibili-bangumi">hexo-bilibili-bangumi</a></li></ol><pre><code class="lang-bash">pnpm i hexo-bilibili-bangumi --save</code></pre><p>在<code>_config.yml</code>配置：</p><pre><code class="lang-yml">bangumi: # 追番设置
  enable: true           # 是否启用
  source: bili          # 数据源
  path: bangumis/index.html  # 页面路径
  vmid:                 # 用户ID
  title: &#039;追番列表&#039;      # 页面标题
  quote: &#039;生命不息，追番不止！&#039; # 页面引言
  show: 1              # 初始显示页面: 0=想看, 1=在看, 2=看过
  lazyload: true       # 是否启用图片懒加载
  metaColor:           # meta 信息字体颜色
  color:               # 简介字体颜色
  webp: true          # 是否使用 webp 格式图片
  progress: true      # 是否显示进度条

cinema: # 追剧设置
  enable: true           # 是否启用
  source: bili

game: # 游戏设置，仅支持source: bgmv0
  enable: true           # 是否启用
  source: bgmv0
</code></pre><p>还在更新中。。。</p><hr><h2>Github action配置</h2><p>承接<a href="#github-config">段落</a>的继续吧，未来会在<del>出</del>水一期。</p><p>接下来就是创建一个私有仓库，根据大佬的文章，是为了保护<strong>Token</strong>，见仁见智。</p><p>这个私有仓库的建立是存储Hexo博客代码，如果你要使用<a href="https://github.com/Qexo/Qexo">Qexo</a></p><p>，这也是必不可少的！</p><p><img src="https://img.314926.xyz/images/2025/08/19/hexo-beiwang1.webp" alt="" title=""></p><p>创建完成后，需要把博客的源码 push 到这里。首先获取远程仓库地址，此处虽然 SSH 和 HTTPS 均可。SSH 在绑定过 ssh key 的设备上无需再输入密码，HTTPS 则需要输入密码，但是 SSH 偶尔会遇到端口占用的情况。请自主选择。</p><p><img src="https://img.314926.xyz/images/2025/08/19/hexo-beiwang2.webp" alt="" title=""></p><div style="border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #FA3107;">❗ 重要</strong><br>
<span style="color: #ff6600;">这里之所以是私有仓库，是因为在接下来的配置中会用到 `Token`，如果 `Token` 被盗用，别人可以肆意操作你的 github 仓库内容，为了避免这一风险，才选择的博客源码闭源。</span>
</div><h3>配置 Github Action</h3><ol><li>在<code>[Blogroot]</code>新建<code>.github</code>文件夹,注意开头是有个<code>.</code>的。然后在<code>.github</code> 内新建 <code>workflows</code> 文件夹，再在 <code>workflows</code> 文件夹内新建 <code>autodeploy.yml</code>,在<code>[Blogroot]/.github/workflows/autodeploy.yml</code> 里面输入</li></ol><pre><code class="lang-yml"># 当有改动推送到 main 分支时，启动 Action
name: 自动部署

on:
  push:
    branches:
      - main # 自选分支

  release:
    types:
      - published

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 检查分支
        uses: actions/checkout@v4
        with:
          ref: main # 自选分支

      - name: 安装 Node
        uses: actions/setup-node@v4
        with:
          node-version: &quot;22.x&quot; # node版本

      - name: 安装 Hexo
        run: |
          export TZ=&#039;Asia/Shanghai&#039;
          npm install hexo-cli -g
          npm install yamljs --save

      - name: 缓存 Hexo
        uses: actions/cache@v4
        id: cache
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(&#039;**/package-lock.json&#039;) }}

      - name: 安装依赖
        if: steps.cache.outputs.cache-hit != &#039;true&#039;
        run: |
          npm install --save
          npm install hexo-algoliasearch --save
          npm install hexo-bilibili-bangumi --save

      - name: 生成静态文件
        run: |
          node ./link.js
          hexo clean
          hexo generate
          hexo bangumi -u
          hexo algolia

      - name: 部署
        run: |
          cd ./public
          git init -b main
          git config --global user.name &#039;${{ secrets.GITHUBUSERNAME }}&#039;
          git config --global user.email &#039;${{ secrets.GITHUBEMAIL }}&#039;
          git add .
          git commit -m &quot;${{ github.event.head_commit.message }} $(date +&quot;%Z %Y-%m-%d %A %H:%M:%S&quot;) Updated by GitHub Actions&quot;
          git push --force --quiet &quot;https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git&quot; main</code></pre><p>上述代码是来自<a href="https://akilar.top/posts/f752c86d/">店长</a>的修改自用，为什么不用<a href="https://blog.anheyu.com/posts/asdx.html">安知鱼</a>的？</p><ul><li>首先把Token直接放在仓库的文件里还是不太好。</li><li>像我这种在本地搞的，推不到仓库里，因为这里的token不能直接上传，所以改成环境变量来引入，但是依旧有各种问题，相反使用了店长的代码后，就大差不差，询问AI后就得到目前的代码，也就可以正式上传了。（无拉踩的意思）</li><li>之后需要自己到仓库的 Settings-&gt;Secrets-&gt;actions 下添加环境变量，变量名参考脚本中出现的，依次添加。</li></ul><p><img src="https://img.314926.xyz/images/2025/08/19/hexo-beiwang3.webp" alt="" title=""></p><h3>重新设置远程仓库和分支</h3><p><details><br><summary>🍼第一次使用git管理博客源码</summary></p><ol><li>删除或者先把<code>[Blogroot]/themes/solitude/.git</code>移动到非博客文件夹目录下,原因是主题文件夹下的<code>.git</code>文件夹的存在会导致其被识别成子项目，从而无法被上传到源码仓库。</li><li><p>在博客根目录<code>[Blogroot]</code>路径下运行指令:</p><pre><code class="lang-bash">git init #初始化
git remote add origin git@github.com:[GithubUsername]/[SourceRepo].git #[SourceRepo]为存放源码的github私有仓库
git checkout -b master # 切换到master分支，
#2020年10月后github新建仓库默认分支改为main，注意更改
# 如果不是，后面的所有设置的分支记得保持一致</code></pre></li><li><p>添加屏蔽项</p><pre><code class="lang-bash">.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.deploy_git*/
.idea
themes/solitude/.git</code></pre><p>如果不是<code>solitude</code>主题，记得替换最后一行内容为你自己当前使用的主题。</p></li><li><p>之后再运行 git 提交指令，将博客源码提交到 github 上。</p><pre><code class="lang-bash">git add .
git commit -m &quot;github action update&quot;
git push origin master
#2020年10月后github新建仓库默认分支改为main，注意更改</code></pre></li><li>此时你的主题文件夹若已经被正常上传，并且你也添加了主题文件夹下的.git 文件夹的屏蔽项。那你可以考虑把第二步移走或删除的<code>.git</code>放回来，用作以后升级。（不禁怀疑真的有人会去用这个方式来升级吗）<br></details></li></ol><p><details><br><summary>🍾曾经做过git管理源码的操作</summary></p><ol><li>添加屏蔽项</li></ol><p>因为能够使用指令进行安装的内容不包括在需要提交的源码内，所有我们需要将这些内容添加到屏蔽项，表示不上传到 github 上。这样可以显著减少需要提交的文件量和加快提交速度。<br>打开<code>[Blogroot]/.gitignore</code>,输入以下内容：</p><pre><code class="lang-bash">.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.deploy_git*/
.idea
themes/solitude/.git</code></pre><p>如果不是<code>solitude</code>主题，记得替换最后一行内容为你自己当前使用的主题。</p><ol start="2"><li><p>提交源码到私有仓库<code>[SourceRepo]</code><br>在博客根目录<code>[Blogroot]</code>下启动终端，使用 git 指令重设仓库地址。这样在新建仓库，我们仍旧可以保留珍贵的 commit history，便于版本回滚。</p><pre><code class="lang-bash">git remote rm origin # 删除原有仓库链接
git remote add origin git@github.com:[GithubUsername]/[SourceRepo].git #[SourceRepo]为新的存放源码的github私有仓库
git checkout -b master # 切换到master分支，
#2020年10月后github新建仓库默认分支改为main，注意更改
# 如果不是，后面的所有设置的分支记得保持一致
git add .
git commit -m &quot;github action update&quot;
git push origin master
#2020年10月后github新建仓库默认分支改为main，注意更改</code></pre></li><li><p>可能遇到的 bug<br>因为 solitude 主题文件夹下的.git 文件夹的存在，那么主题文件夹会被识别子项目。从而无法被上传到源码仓库。若是遇到添加屏蔽项，但是还是无法正常上传主题文件夹的情况。请先将本地源码中的 themes 文件夹移动到别的目录下。然后 commit 一次。接着将 themes 文件夹移动回来，再 commit 一次。</p><div style="border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #FA3107;">❗ 重要</strong><br>
<span style="color: #ff6600;">要是还不行，那就删了 solitude 主题文件夹下的.git 文件夹，然后再重复上述的 commit 操作。
</span>
</div><p></details></p></li></ol><h1>挖坑</h1><p>大致写到这，未来或许会有<del>下一章</del>挖坑？但是目前通用的就到这，然后后续会写Qexo的简单使用方法、solitude的一些配置更改和我踩坑经历吧。</p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown--># Hexo 备忘</p><h2>我的配置</h2><ol><li><strong>Hexo 版本</strong>: hexo-cli: 4.3.2, hexo: 7.3.0(当前最新)</li><li><strong>Node.js 版本</strong>: 22.16.0</li><li><strong>Git 版本</strong>: 2.47.0.sindows.2</li><li><strong>PNPM 版本</strong>: 10.12.4</li><li><strong>Windows 版本</strong>: 11</li></ol><h2>安装 Node.js</h2><ol><li>在 <a href="https://nodejs.org/en/download/">官网</a> 安装 LTS 版本，电脑一般来说内存足够直接在 C 盘即可，当然，换路径也可以，我反正正常下载换路径，没什么问题。</li><li>安装完成后，检查是否安装成功。在键盘按下 <kbd> win </kbd> + <kbd> R </kbd> 键，输入 <code>CMD</code>，然后回车，打开 CMD 窗口，执行 <code>node -v</code> 命令，看到版本信息，则说明安装成功。</li></ol><h2>安装 Git</h2><p>在 <a href="https://git-scm.com/download/win">官网</a> 安装最新版本的 <code>64-bit Git for Windows Setup</code> 安装包。  </p><p>安装完成后，在命令行输入 <code>git --version</code>，如果显示版本号，则说明安装成功。</p><h3>常用命令</h3><pre><code class="lang-bash">git config -l  //查看所有配置
git config --system --list //查看系统配置
git config --global --list //查看用户（全局）配置</code></pre><h3>配置 Git 用户名和邮箱</h3><pre><code class="lang-bash">git config --global user.name &quot;你的用户名&quot;
git config --global user.email &quot;你的邮箱&quot;</code></pre><h2>安装 包管理器</h2><p>安装 npm 为一切的基石，一般来说，你安装了 node，也相当于你安装了 npm，通过一下命令来验证：</p><pre><code class="lang-bash">npm -v
node -v</code></pre><p><strong>修改 npm 源</strong>。npm 下载各种模块，默认是从国外服务器下载，速度较慢，建议配置成淘宝镜像。打开 CMD 窗口，运行如下命令:</p><pre><code class="lang-bash">npm config set registry https://registry.npm.taobao.org</code></pre><h3>安装 pnpm</h3><p>pnpm 是一个快速、节省磁盘空间的包管理器，类似于 npm 和 yarn。安装 pnpm 可以通过以下命令：</p><pre><code class="lang-bash">npm install -g pnpm</code></pre><p>为什么选择 pnpm？因为它的安装速度快，依赖管理更高效，且相对于 npm，我使用 npm 容易失败且慢，pnpm 给我的体验更好。</p><h2>安装 Hexo</h2><ol><li>在 Git BASH 输入如下命令安装 Hexo：</li></ol><pre><code class="lang-bash">pnpm install -g hexo-cli</code></pre><ol start="2"><li>安装完后输入 <code>hexo -v</code> 验证是否安装成功。</li></ol><hr><h2><a id="github-config"></a>Github配置</h2><blockquote>上述操作是前提，接下来是配置 Github。</blockquote><p>注册 github 就不说了，很基础的东西，连我个代码小白都懂就不多说了。</p><h3>创建仓库</h3><ol><li>登录 GitHub，点击右上角的 <code>+</code> 号，选择 <code>New repository</code>。</li><li>填写仓库名称，建议使用 <code>&lt;username&gt;.github.io</code> 格式（例如：<code>yourusername.github.io</code>），这样可以直接作为个人主页。</li></ol><p>这里我不准备直接使用常规的 <code>hexo deploy</code> 命令来部署到 GitHub Pages，因为当你的文章一多，生成时间就会繁琐，这里的建议是使用 <code>Github Actions</code> 来自动部署。</p><blockquote>这一部分的教程是源于 <a href="https://akilar.top/posts/f752c86d/">店长的文章</a>，但是有点老旧了，于是我做了点更改（这里的图片来源于 <a href="https://blog.anheyu.com/posts/asdx.html">安知鱼</a>）：</blockquote><ol><li>首先要创建一个放置源码的私有仓库，以下称之为 <code>hexo-source</code>，</li><li>然后要生成一个 Github 密钥：</li></ol><blockquote>访问 Github-&gt; 头像（右上角）-&gt; Settings-&gt; Developer Settings-&gt; Personal access tokens-&gt; generate new token, 创建的 Token 名称随意，但必须勾选 repo 项 和 workflows 项。</blockquote><p>点击 <a href="https://github.com/settings/tokens">链接</a> 前往生成</p><p><img src="https://img.314926.xyz/images/2025/08/17/jiaoxue1.webp" alt="" title=""><br><img src="https://img.314926.xyz/images/2025/08/17/jiaoxue2.webp" alt="" title=""></p><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">ℹ️ 提示</strong><br>
<span style="color: #ff6600;">!!! token 只会显示这一次，之后将无法查看，所以务必保证你已经记录下了 Token。之后如果忘记了就只能重新生成重新配置了。</span>
</div><ol start="3"><li><p>在 <code>hexo-source</code> 仓库中的设置里点击设置 -&gt; action -&gt; General -&gt; 工作流程权限</p><ul><li>勾选 <code>Read and write permissions</code>，并且勾选 <code>Allow &lt;span style=&quot;background:#FF0000;&quot;&gt;&lt;/span&gt;all actions and reusable workflows</code>。</li></ul></li><li>在设置里 -&gt; Secrets and variables -&gt; Actions -&gt; New repository secret 添加</li><li><code>GITHUBTOKEN</code>：放置你刚才生成的 Token。</li></ol><hr><h2>上述是前置条件，接下来要先部署 hexo，你才好继续下一步。</h2><h2>初始化 Hexo</h2><ol><li>在本地新建一个文件夹，例如 <code>hexo-solitude</code>。</li><li>这里我是用的是 vscode 打开该文件夹，然后在终端输入以下命令来初始化 Hexo：</li></ol><pre><code class="lang-bash">hexo init (项目名称)</code></pre><p>我一般都不填，直接在文件下下就可以开始，如果你添加了项目名称，那么下一步就是：</p><pre><code class="lang-bash">cd (项目名称)</code></pre><ol start="3"><li>安装依赖包：</li></ol><pre><code class="lang-bash">pnpm install</code></pre><p>然后就是选择你想要的主题，这里我使用的是<a href="https://solitude.js.org/cn/getting-started/installation">Solitude</a>，具体的配置不细讲，我只讲一部分：</p><p>首先就是基本的安装，这里还是选择<code>git clone</code>没有别的原因，主要还是会改点源码，不想改的直接pnpm下载即可：</p><pre><code>// git安装
git clone -b dev https://github.com/everfu/hexo-theme-solitude.git themes/solitude

// pnpm 安装
pnpm i hexo-theme-solitude</code></pre><p>然后在<code>_config.yml</code>里修改成：</p><pre><code class="lang-yml">theme: solitude</code></pre><h2>配置</h2><p>下列代码是我的备忘：</p><pre><code class="lang-yml"># Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title: 喵落阁
subtitle: &#039;克喵的博客&#039;
description: &#039;愿你看清一切真相后，依旧热爱你的家人和朋友。&#039;
keywords: 克喵,kemiao,博客
author: 克喵爱吃卤面
language: zh-CN
timezone: &#039;Asia/Shanghai&#039;

# URL
## Set your site url here. For example, if you use GitHub Page, set url as &#039;https://username.github.io/project&#039;
url: # 填网站地址
permalink: posts/:abbrlink.html
permalink_defaults:
pretty_urls:
  trailing_index: true # Set to false to remove trailing &#039;index.html&#039; from permalinks
  trailing_html: true # Set to false to remove trailing &#039;.html&#039; from permalinks

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
  enable: true # Open external links in new tab
  field: site # Apply to the whole site
  exclude: &#039;&#039;
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
syntax_highlighter: highlight.js
highlight:
  line_number: false
  auto_detect: false
  tab_replace: &#039;&#039;
  wrap: true
  hljs: false
prismjs:
  preprocess: true
  line_number: true
  tab_replace: &#039;&#039;

# Home page setting
# path: Root path for your blogs index page. (default = &#039;&#039;)
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
  path: &#039;&#039;
  per_page: 10
  order_by: -date

# Category &amp; Tag
default_category: uncategorized
category_map:
tag_map:

# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports &#039;mtime&#039;, &#039;date&#039;, &#039;empty&#039;
updated_option: &#039;mtime&#039;

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Include / Exclude file(s)
## include:/exclude: options only apply to the &#039;source/&#039; folder
include: []
exclude: []
ignore: []

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: solitude

# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
  type: git
  repo: git@github.com-xx:kemiaofxjun/kemiaofxjun.github.io.git
  branch: main

# RSS Feed 配置
feed:
  type: atom          # 生成 atom.xml
  path: atom.xml      # 输出文件名
  limit: 20           # 最多显示文章数 (0=全部)
  hub:                # PubSubHubbub 中心 (可选)
  content: true       # 是否包含全文内容 (true=是, false=仅摘要)
  content_limit: 140  # 摘要长度（当 content=false 时生效）
  content_limit_delim: &#039; &#039;  # 截断分隔符
  order_by: -date     # 按日期倒序排列
  autodiscovery: true # 在 HTML 头部添加自动发现标签

# 数学公式渲染配置
markdown:
  preset: &#039;default&#039; # 使用的 MD 语法，默认使用的 GFM
  render:
    html: true # 渲染 html
    xhtmlOut: false
    langPrefix: &#039;language-&#039; # 在代码块的类名中添加前缀（指定语言时）。
    breaks: true
    linkify: true # 如果你写了一个链接而不是 [name](link) 方式，会自动识别为链接并渲染。
    typographer: true # 将替换常见的印刷元素。
    quotes: &#039;“”‘’&#039; # 替换文章张的 &quot;&quot; &#039;&#039; 号
  enable_rules:
  disable_rules:
  plugins: # 使用插件
  anchors:
    level: 2 # 渲染标题的级别（h1,h2,h3）
    collisionSuffix: &#039;&#039;
    permalink: true
    permalinkClass: &#039;headerlink&#039;
    permalinkSide: &#039;left&#039;
    permalinkSymbol: &#039;&#039;
    case: 0
    separator: &#039;-&#039;
  images: # 图片的一些编译
    lazyload: true # 是否需要渲染 lazyload
    prepend_root: false
    post_asset: false
  inline: false

swpp:
  # 是否启用插件
  enable: true
  # 是否在发布前自动执行脚本
  auto_exec: true
  gen_dom: true

# 文章链接转数字或字母：https://github.com/rozbo/hexo-abbrlink
abbrlink:
    alg: crc16   #算法： crc16(default) and crc32
    rep: hex     #进制： dec(default) and hex: dec #输出进制：十进制和十六进制，默认为10进制。丨dec为十进制，hex

# https://github.com/hexojs/hexo-generator-sitemap
sitemap:
  path: sitemap.xml
  rel: false
  tags: true
  categories: true

algolia:
  appId: &quot;&quot;
  apiKey: &quot;&quot;
  adminApiKey: &quot;&quot;
  chunkSize: 5000
  indexName: &quot;index-name&quot;
  fields:
    - content:strip:truncate,0,500
    - excerpt:strip
    - gallery
    - permalink
    - photos
    - slug
    - tags
    - title

# hexo-safego安全跳转插件
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
  # 基本功能设置
  general:
    enable: true                # 启用插件
    enable_base64_encode: true  # 使用 Base64 编码
    enable_target_blank: true   # 从新窗口打开跳转页面

  # 安全设置
  security:
    url_param_name: &#039;u&#039;         # URL 参数名
    html_file_name: &#039;go.html&#039;   # 重定向页面的文件名
    ignore_attrs:               # 忽略处理的 HTML 结构
      - &#039;data-fancybox&#039;

  # 容器与页面设置
  scope:
    apply_containers:           # 应用的容器选择器
      - &#039;#article-container&#039;
    apply_pages:                # 应用的页面路径
      - &quot;/posts/&quot;
      - &quot;/devices/&quot;
    exclude_pages:              # 排除的页面路径

  # 域名白名单
  whitelist:
    domain_whitelist:           # 允许的白名单域名，通过字符串匹配实现
      - &quot;kemeow.top&quot;
      - &quot;kemiaosw.top&quot;
      - &quot;050815.xyz&quot;
      - &quot;314926.xyz&quot;
      - &quot;051531.xyz&quot;

  # 页面外观设置
  appearance:
    avatar: https://img.314926.xyz/images/2025/08/13/no-background-kemiaofxjun.webp   # 跳转页面头像路径
    title: &quot;喵洛阁&quot;            # 跳转页面标题
    subtitle: &quot;安全中心&quot;         # 跳转页面副标题
    darkmode: auto              # 是否启用深色模式
    countdowntime: 4            # 跳转页面倒计时秒数，如果设置为负数则为不自动跳转

  # 调试设置
  debug:
    enable: false               # 启用调试模式

# 追番插件
# https://github.com/HCLonely/hexo-bilibili-bangumi
bangumi: # 追番设置
  enable: true
  source: bili
  path: 
  vmid: 3546643173477234
  title: &quot;追番列表&quot;
  quote: &quot;生命不息，追番不止！&quot;
  show: 1
  lazyload: false
  loading:
  showMyComment: true
  pagination: false
  extra_options:
    top_img: false
    lazyload:
      enable: false
</code></pre><p>博客的其他修改基本就是来自教程和一些博主的网站。</p><hr><h2>插件</h2><ol><li><strong>基础依赖</strong> <code>hexo-renderer-pug</code></li></ol><pre><code class="lang-bash">pnpm i hexo-renderer-pug</code></pre><hr><ol start="2"><li><strong>字数统计</strong> <code>hexo-wordcount</code></li></ol><pre><code class="lang-bash">pnpm i hexo-wordcount</code></pre><p>配置里修改：</p><pre><code class="lang-yml"># --------------------------- start ---------------------------
# Word count
# 字数统计
# warning: Please install the hexo-wordcount plugin first.
# 警告: 请先安装 hexo-wordcount 插件。
wordcount: false
# --------------------------- end ---------------------------</code></pre><hr><ol start="3"><li><strong>数学公式</strong> 卸载 <code>hexo-render-marked</code></li></ol><pre><code class="lang-bash">npm un hexo-renderer-marked</code></pre><p>安装 <code>hexo-renderer-markdown-it</code> <code>katex</code> <code>@renbaoshuo/markdown-it-katex</code></p><pre><code class="lang-bash">pnpm i hexo-renderer-markdown-it katex @renbaoshuo/markdown-it-katex</code></pre><p>配置里修改</p><pre><code class="lang-yml"># --------------------------- start ---------------------------
# Katex
# Latex formula support
# Latex 公式支持
katex:
  enable: false
  # Whether to load on each page
  # 是否在每个页面加载
  per_page: false
  # Whether to enable copy formula
  # 是否启用复制公式
  copytex: false
# --------------------------- end ---------------------------</code></pre><p>添加以下内容到 <code>_config.yml</code></p><pre><code class="lang-yml">markdown:
  preset: &#039;default&#039;
  render:
    html: true
    xhtmlOut: false
    langPrefix: &#039;language-&#039;
    breaks: true
    linkify: true
    typographer: true
    quotes: &#039;“”‘’&#039;
  enable_rules:
  disable_rules:
  plugins:
    - &#039;@renbaoshuo/markdown-it-katex&#039;
  anchors:
    level: 2
    collisionSuffix: &#039;&#039;
    permalink: false
    permalinkClass: &#039;header-anchor&#039;
    permalinkSide: &#039;left&#039;
    permalinkSymbol: &#039;¶&#039;
    case: 0
    separator: &#039;-&#039;
  images:
    lazyload: false
    prepend_root: false
    post_asset: false
  inline: false  # https://markdown-it.github.io/markdown-it/#MarkdownIt.renderInline</code></pre><p>开启配置项</p><pre><code class="lang-yml"># --------------------------- start ---------------------------
# Katex
# Latex formula support
# Latex 公式支持
katex:
  enable: true
  # Whether to load on each page
  # 是否在每个页面加载
  per_page: true
  # Whether to enable copy formula
  # 是否启用复制公式
  copytex: false
# --------------------------- end ---------------------------
</code></pre><hr><ol start="4"><li><strong>PWA</strong> 安装 hexo-swpp 和 swpp-backends 插件</li></ol><p>在博客根目录执行</p><pre><code class="lang-bash">pnpm i hexo-swpp 

pnpm i swpp-backends</code></pre><p>开启配置</p><pre><code class="lang-yml"># 大约在773行
# --------------------------- start ---------------------------
# PWA
# Progressive Web App
pwa:
  enable: true
  manifest: /manifest.json # manifest.json
  theme_color: &quot;#006a73&quot; # Theme color
  mask_icon: /img/pwa/favicon.png # Mask icon
  apple_touch_icon: /img/pwa/favicon.png # Apple touch icon
  bookmark_icon: /img/pwa/favicon.png # Bookmark icon
  favicon_32_32: /img/pwa/favicon_32.png # 32x32 icon
  favicon_16_16: /img/pwa/favicon_16.png # 16x16 icon
# --------------------------- end ---------------------------
</code></pre><p>在<code>_config.yml</code>里添加swpp配置</p><pre><code class="lang-yml">swpp:
  # 是否启用插件
  enable: true
  # 是否在发布前自动执行脚本
  auto_exec: true
  gen_dom: true</code></pre><p>在 <code>source</code> 目录中创建 <code>manifest.json</code> 文件</p><pre><code class="lang-json">{
    &quot;name&quot;: &quot;网站名称&quot;,
    &quot;short_name&quot;: &quot;网站名称缩写&quot;,
    &quot;theme_color&quot;: &quot;#006a73&quot;,
    &quot;background_color&quot;: &quot;#006a73&quot;,
    &quot;display&quot;: &quot;fullscreen&quot;,
    &quot;scope&quot;: &quot;/&quot;,
    &quot;start_url&quot;: &quot;/&quot;,
    &quot;id&quot;: &quot;/&quot;,
    &quot;icons&quot;: [
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_16.png&quot;,
        &quot;sizes&quot;: &quot;16x16&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;any&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_16.png&quot;,
        &quot;sizes&quot;: &quot;16x16&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;maskable&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_32.png&quot;,
        &quot;sizes&quot;: &quot;32x32&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;any&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon_32.png&quot;,
        &quot;sizes&quot;: &quot;32x32&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;maskable&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon.png&quot;,
        &quot;sizes&quot;: &quot;180x180&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;any&quot;
      },
      {
        &quot;src&quot;: &quot;/img/pwa/favicon.png&quot;,
        &quot;sizes&quot;: &quot;180x180&quot;,
        &quot;type&quot;: &quot;image/png&quot;,
        &quot;purpose&quot;: &quot;maskable&quot;
      }
    ],
    &quot;splash_pages&quot;: null
}
</code></pre><p>在博客根目录创建一个 <code>sw-rules.js</code> 文件</p><pre><code class="lang-js">module.exports.config = {
  /** @type {?ServiceWorkerConfig|boolean} */
  serviceWorker: {
    escape: 1,
    cacheName: &#039;SolitudeCache&#039;,
    debug: false,
  },
  register: {
    onsuccess: undefined,
    onerror: () =&gt;
      console.error(
        &#039;Service Worker 注册失败！可能是由于您的浏览器不支持该功能！&#039;
      ),
    builder: (root, framework, pluginConfig) =&gt; {
      const { onerror, onsuccess } = pluginConfig.register;
      return `
            &lt;script&gt;
                (() =&gt; {
                    const sw = navigator.serviceWorker;
                    const error = ${onerror &amp;&amp; onerror.toString()};
                    if (!sw?.register(&#039;${new URL(root).pathname}sw.js&#039;)
                        ${onsuccess ? `?.then(${onsuccess.toString()})` : &quot;&quot;}
                        ?.catch(error)
                    ) error()
                })()
            &lt;/script&gt;`;
    },
  },
  /** @type {?DomConfig|boolean} */
  dom: {
    /** @type {?VoidFunction} */
    onsuccess: () =&gt; {
      caches
        .match(&#039;https://id.v3/&#039;)
        .then((res) =&gt; {
          if (res)
            res.json().then((json) =&gt; {
              utils &amp;&amp;
                utils.snackbarShow(
                  `已刷新缓存，更新为${json.escape + &#039;.&#039; + json.global + &#039;.&#039; + json.local
                  }版本最新内容`,
                  false,
                  2500
                );
            });
          else console.info(&#039;未找到缓存&#039;);
        })
        .catch((error) =&gt; console.error(&#039;缓存匹配出错&#039;, error));
    },
  },
  /** @type {?VersionJsonConfig|boolean} */
  json: {
    /** @type {number} */
    maxHtml: 15,
    /** @type {number} */
    charLimit: 1024,
    /** @type {string[]} */
    merge: [],
    exclude: {
      /** @type {RegExp[]} */
      localhost: [],
      /** @type {RegExp[]} */
      other: [],
    },
  },
  /** @type {?ExternalMonitorConfig|boolean} */
  external: {
    /** @type {number} */
    timeout: 5000,
    /** 拉取文件时地并发限制 */
    concurrencyLimit: 100,
    /** @type {({head: string, tail: string}|function(string):string[])[]} */
    js: [],
    /** @type {RegExp[]} */
    stable: [
      /^https:\/\/npm\.elemecdn\.com\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
      /^https:\/\/cdn\.cbd\.int\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
      /^https:\/\/cdn\.jsdelivr\.net\/npm\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
    ],
    replacer: (srcUrl) =&gt; {
      if (srcUrl.startsWith(&#039;https://cdn.jsdelivr.net/npm/&#039;)) {
        const pathname = new URL(srcUrl).pathname;
        return [
          srcUrl,
          `https://cdn.cbd.int/${pathname}`,
          `https://npm.elemecdn.com/${pathname}`,
          `https://fastly.jsdelivr.net/npm/${pathname}`,
        ];
      } else {
        return srcUrl;
      }
    },
  },
};

module.exports.cacheRules = {
  simple: {
    clean: true,
    search: false,
    match: (url, $eject) =&gt;
      url.host === $eject.domain &amp;&amp; [&#039;/404.html&#039;].includes(url.pathname),
  },
  cdn: {
    clean: true,
    match: (url) =&gt;
      [
        &#039;cdn.cbd.int&#039;,
        &#039;lf26-cdn-tos.bytecdntp.com&#039;,
        &#039;lf6-cdn-tos.bytecdntp.com&#039;,
        &#039;lf3-cdn-tos.bytecdntp.com&#039;,
        &#039;lf9-cdn-tos.bytecdntp.com&#039;,
        &#039;cdn.staticfile.org&#039;,
        &#039;npm.elemecdn.com&#039;,
      ].includes(url.host) &amp;&amp;
      url.pathname.match(/\.(js|css|woff2|woff|ttf|cur)$/),
  },
};

module.exports.getSpareUrls = (srcUrl) =&gt; {
  if (srcUrl.startsWith(&#039;https://npm.elemecdn.com&#039;)) {
    return {
      timeout: 3000,
      list: [
        srcUrl,
        `https://fastly.jsdelivr.net/${new URL(srcUrl).pathname}`,
      ],
    };
  }
};

module.exports.ejectValues = (hexo, rules) =&gt; {
  return {
    domain: {
      prefix: &#039;const&#039;,
      value: new URL(hexo.config.url).host,
    },
  };
};

module.exports.skipRequest = (request) =&gt; request.url.startsWith(&quot;https://i0.hdslb.com&quot;) ||
  request.url.startsWith(&#039;https://meting.qjqq.cn&#039;) ||
  request.url.startsWith(&#039;https://api.i-meto.com&#039;);</code></pre><hr><ol start="5"><li><strong><a href="https://github.com/hexojs/hexo-deployer-git">hexo-deploy-git</a></strong> 提交到git的插件</li></ol><pre><code class="lang-bash">pnpm i hexo-deploy-git --save</code></pre><hr><ol start="6"><li><strong><a href="https://github.com/hexojs/hexo-generator-feed">hexo-generator-feed</a></strong> hexo的rss插件</li></ol><pre><code class="lang-bash">pnpm i hexo-generator-feed --save</code></pre><hr><ol start="7"><li><strong><a href="https://github.com/ohroy/hexo-abbrlink">hexo 的短链接</a></strong>: <code>hexo-abbrlink</code></li></ol><pre><code class="lang-bash">pnpm i hexo-abbrlink --save</code></pre><p>在<code>_config.yml</code>里修改：</p><pre><code class="lang-yml">permalink: posts/:abbrlink/ 
# or
permalink: posts/:abbrlink.html</code></pre><p>添加:</p><pre><code class="lang-yml"># abbrlink config
abbrlink:
  alg: crc32      # Algorithm used to calc abbrlink. Support crc16(default) and crc32
  rep: hex        # Representation of abbrlink in URLs. Support dec(default) and hex
  drafts: false   # Whether to generate abbrlink for drafts. (false in default)
  force: false    # Enable force mode. In this mode, the plugin will ignore the cache, and calc the abbrlink for every post even it already had an abbrlink. (false in default)
  writeback: true # Whether to write changes to front-matters back to the actual markdown files. (true in default)</code></pre><hr><ol start="8"><li><strong><a href="https://github.com/hexojs/hexo-generator-sitemap">博客的sitemap</a></strong> : <code>hexo-generator-sitemap</code></li></ol><pre><code class="lang-bash">pnpm i hexo-generator-sitemap --save</code></pre><p>在<code>_config.yml</code>里添加配置：</p><pre><code class="lang-yml">sitemap:
  path: 
    - sitemap.xml
    - sitemap.txt
  template: ./sitemap_template.xml
  template_txt: ./sitemap_template.txt
  rel: false
  tags: true
  categories: true</code></pre><hr><ol start="9"><li><a href="https://www.mebi.me/hexo-with-algolia"><strong>使用algolia搜索</strong></a> : <code>hexo-algoliasearch</code></li></ol><ul><li>注册algolia：</li></ul><p>注册地址：<a href="https://dashboard.algolia.com/users/sign_up">dashboard.algolia.com/users/sign_up</a></p><ul><li>创建应用：</li></ul><p>注册成功后创建应用：<a href="https://dashboard.algolia.com/account/plan/create?from=dashboard">dashboard.algolia.com/account/plan/create?from=dashboard</a></p><ul><li>search -&gt; configure -&gt; index添加index_name即可</li></ul><p>在博客执行命令：</p><pre><code class="lang-bash">pnpm i hexo-algoliasearch --save</code></pre><p><code>_config.yml</code>里添加</p><pre><code class="lang-yml">algolia:
  appId: &quot;Z7A3XW4R2I&quot;
  apiKey: &quot;12db1ad54372045549ef465881c17e743&quot;
  adminApiKey: &quot;40321c7c207e7f73b63a19aa24c4761b&quot;
  chunkSize: 5000
  indexName: &quot;my-hexo-blog&quot;
  fields:
    - content:strip:truncate,0,500
    - excerpt:strip
    - gallery
    - permalink
    - photos
    - slug
    - tags
    - title</code></pre><div style="border-left: 4px solid #0969da; background-color: #ddf4ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #ff6600;">ℹ️ 提示</strong><br>
<span style="color: #ff6600;">**!!!配置完成后记得运行 `hexo clean`**</span>
</div><p>在<code>hexo g </code>后实行下列代码：</p><pre><code class="lang-bash">hexo algolia</code></pre><hr><ol start="10"><li><strong><a href="https://blog.liushen.fun/posts/1dfd1f41/">hexo-safego</a></strong>安全跳转插件</li></ol><p>使用该插件之前，需要先安装 <code>cheerio</code>，<code>cheerio</code> 是一个轻量级的库，用于在服务器端快速、灵活地实现 jQuery 核心功能。在 <code>hexo-safego</code> 插件中，<code>cheerio</code> 被用来解析和操作生成的静态 HTML 内容，类似于在浏览器中使用 jQuery 处理 DOM 元素。这使得插件能够在生成静态页面时，处理和替换外部链接，增强博客的安全性，而不需要在客户端引入 jQuery。Hexo 一般都有这个插件，可以在 <code>node_modules</code> 查看，如果没有，请先执行：</p><pre><code class="lang-bash">pnpm i cheerio --save</code></pre><p>然后即可安装该插件：</p><pre><code class="lang-bash">pnpm i hexo-safego --save</code></pre><p>在<code>hexo</code>根目录的<code>_config.yml</code>文件中添加以下配置：</p><pre><code class="lang-yml"># hexo-safego安全跳转插件
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
  # 基本功能设置
  general:
    enable: true                # 启用插件
    enable_base64_encode: true  # 使用 Base64 编码
    enable_target_blank: true   # 打开新窗口
  # 安全设置
  security:
    url_param_name: &#039;u&#039;         # URL 参数名
    html_file_name: &#039;go.html&#039;   # 重定向页面的文件名
    ignore_attrs:               # 忽略处理的 HTML 属性
      - &#039;data-fancybox&#039;
  # 容器与页面设置
  scope:
    apply_containers:           # 应用的容器选择器
      - &#039;#article-container&#039;
    apply_pages:                # 应用的页面路径
      - &quot;/posts/&quot;
      - &quot;/devices/&quot;
    exclude_pages:              # 排除的页面路径
  # 域名白名单
  whitelist:
    domain_whitelist:           # 允许的白名单域名
      - &quot;qyliu.top&quot;
      - &quot;liushen.fun&quot;
  # 页面外观设置
  appearance:
    avatar: /info/avatar.ico    # 头像路径
    title: &quot;清羽飞扬&quot;            # 页面标题
    subtitle: &quot;安全中心&quot;         # 页面副标题
    darkmode: true              # 是否启用深色模式
    countdowntime: -1           # 倒计时秒数
  # 调试设置
  debug:
    enable: false               # 启用调试模式</code></pre><ol start="11"><li><strong>hexo的追番页面</strong>：<a href="https://github.com/HCLonely/hexo-bilibili-bangumi">hexo-bilibili-bangumi</a></li></ol><pre><code class="lang-bash">pnpm i hexo-bilibili-bangumi --save</code></pre><p>在<code>_config.yml</code>配置：</p><pre><code class="lang-yml">bangumi: # 追番设置
  enable: true           # 是否启用
  source: bili          # 数据源
  path: bangumis/index.html  # 页面路径
  vmid:                 # 用户ID
  title: &#039;追番列表&#039;      # 页面标题
  quote: &#039;生命不息，追番不止！&#039; # 页面引言
  show: 1              # 初始显示页面: 0=想看, 1=在看, 2=看过
  lazyload: true       # 是否启用图片懒加载
  metaColor:           # meta 信息字体颜色
  color:               # 简介字体颜色
  webp: true          # 是否使用 webp 格式图片
  progress: true      # 是否显示进度条

cinema: # 追剧设置
  enable: true           # 是否启用
  source: bili

game: # 游戏设置，仅支持source: bgmv0
  enable: true           # 是否启用
  source: bgmv0
</code></pre><p>还在更新中。。。</p><hr><h2>Github action配置</h2><p>承接<a href="#github-config">段落</a>的继续吧，未来会在<del>出</del>水一期。</p><p>接下来就是创建一个私有仓库，根据大佬的文章，是为了保护<strong>Token</strong>，见仁见智。</p><p>这个私有仓库的建立是存储Hexo博客代码，如果你要使用<a href="https://github.com/Qexo/Qexo">Qexo</a></p><p>，这也是必不可少的！</p><p><img src="https://img.314926.xyz/images/2025/08/19/hexo-beiwang1.webp" alt="" title=""></p><p>创建完成后，需要把博客的源码 push 到这里。首先获取远程仓库地址，此处虽然 SSH 和 HTTPS 均可。SSH 在绑定过 ssh key 的设备上无需再输入密码，HTTPS 则需要输入密码，但是 SSH 偶尔会遇到端口占用的情况。请自主选择。</p><p><img src="https://img.314926.xyz/images/2025/08/19/hexo-beiwang2.webp" alt="" title=""></p><div style="border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #FA3107;">❗ 重要</strong><br>
<span style="color: #ff6600;">这里之所以是私有仓库，是因为在接下来的配置中会用到 `Token`，如果 `Token` 被盗用，别人可以肆意操作你的 github 仓库内容，为了避免这一风险，才选择的博客源码闭源。</span>
</div><h3>配置 Github Action</h3><ol><li>在<code>[Blogroot]</code>新建<code>.github</code>文件夹,注意开头是有个<code>.</code>的。然后在<code>.github</code> 内新建 <code>workflows</code> 文件夹，再在 <code>workflows</code> 文件夹内新建 <code>autodeploy.yml</code>,在<code>[Blogroot]/.github/workflows/autodeploy.yml</code> 里面输入</li></ol><pre><code class="lang-yml"># 当有改动推送到 main 分支时，启动 Action
name: 自动部署

on:
  push:
    branches:
      - main # 自选分支

  release:
    types:
      - published

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 检查分支
        uses: actions/checkout@v4
        with:
          ref: main # 自选分支

      - name: 安装 Node
        uses: actions/setup-node@v4
        with:
          node-version: &quot;22.x&quot; # node版本

      - name: 安装 Hexo
        run: |
          export TZ=&#039;Asia/Shanghai&#039;
          npm install hexo-cli -g
          npm install yamljs --save

      - name: 缓存 Hexo
        uses: actions/cache@v4
        id: cache
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(&#039;**/package-lock.json&#039;) }}

      - name: 安装依赖
        if: steps.cache.outputs.cache-hit != &#039;true&#039;
        run: |
          npm install --save
          npm install hexo-algoliasearch --save
          npm install hexo-bilibili-bangumi --save

      - name: 生成静态文件
        run: |
          node ./link.js
          hexo clean
          hexo generate
          hexo bangumi -u
          hexo algolia

      - name: 部署
        run: |
          cd ./public
          git init -b main
          git config --global user.name &#039;${{ secrets.GITHUBUSERNAME }}&#039;
          git config --global user.email &#039;${{ secrets.GITHUBEMAIL }}&#039;
          git add .
          git commit -m &quot;${{ github.event.head_commit.message }} $(date +&quot;%Z %Y-%m-%d %A %H:%M:%S&quot;) Updated by GitHub Actions&quot;
          git push --force --quiet &quot;https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git&quot; main</code></pre><p>上述代码是来自<a href="https://akilar.top/posts/f752c86d/">店长</a>的修改自用，为什么不用<a href="https://blog.anheyu.com/posts/asdx.html">安知鱼</a>的？</p><ul><li>首先把Token直接放在仓库的文件里还是不太好。</li><li>像我这种在本地搞的，推不到仓库里，因为这里的token不能直接上传，所以改成环境变量来引入，但是依旧有各种问题，相反使用了店长的代码后，就大差不差，询问AI后就得到目前的代码，也就可以正式上传了。（无拉踩的意思）</li><li>之后需要自己到仓库的 Settings-&gt;Secrets-&gt;actions 下添加环境变量，变量名参考脚本中出现的，依次添加。</li></ul><p><img src="https://img.314926.xyz/images/2025/08/19/hexo-beiwang3.webp" alt="" title=""></p><h3>重新设置远程仓库和分支</h3><p><details><br><summary>🍼第一次使用git管理博客源码</summary></p><ol><li>删除或者先把<code>[Blogroot]/themes/solitude/.git</code>移动到非博客文件夹目录下,原因是主题文件夹下的<code>.git</code>文件夹的存在会导致其被识别成子项目，从而无法被上传到源码仓库。</li><li><p>在博客根目录<code>[Blogroot]</code>路径下运行指令:</p><pre><code class="lang-bash">git init #初始化
git remote add origin git@github.com:[GithubUsername]/[SourceRepo].git #[SourceRepo]为存放源码的github私有仓库
git checkout -b master # 切换到master分支，
#2020年10月后github新建仓库默认分支改为main，注意更改
# 如果不是，后面的所有设置的分支记得保持一致</code></pre></li><li><p>添加屏蔽项</p><pre><code class="lang-bash">.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.deploy_git*/
.idea
themes/solitude/.git</code></pre><p>如果不是<code>solitude</code>主题，记得替换最后一行内容为你自己当前使用的主题。</p></li><li><p>之后再运行 git 提交指令，将博客源码提交到 github 上。</p><pre><code class="lang-bash">git add .
git commit -m &quot;github action update&quot;
git push origin master
#2020年10月后github新建仓库默认分支改为main，注意更改</code></pre></li><li>此时你的主题文件夹若已经被正常上传，并且你也添加了主题文件夹下的.git 文件夹的屏蔽项。那你可以考虑把第二步移走或删除的<code>.git</code>放回来，用作以后升级。（不禁怀疑真的有人会去用这个方式来升级吗）<br></details></li></ol><p><details><br><summary>🍾曾经做过git管理源码的操作</summary></p><ol><li>添加屏蔽项</li></ol><p>因为能够使用指令进行安装的内容不包括在需要提交的源码内，所有我们需要将这些内容添加到屏蔽项，表示不上传到 github 上。这样可以显著减少需要提交的文件量和加快提交速度。<br>打开<code>[Blogroot]/.gitignore</code>,输入以下内容：</p><pre><code class="lang-bash">.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.deploy_git*/
.idea
themes/solitude/.git</code></pre><p>如果不是<code>solitude</code>主题，记得替换最后一行内容为你自己当前使用的主题。</p><ol start="2"><li><p>提交源码到私有仓库<code>[SourceRepo]</code><br>在博客根目录<code>[Blogroot]</code>下启动终端，使用 git 指令重设仓库地址。这样在新建仓库，我们仍旧可以保留珍贵的 commit history，便于版本回滚。</p><pre><code class="lang-bash">git remote rm origin # 删除原有仓库链接
git remote add origin git@github.com:[GithubUsername]/[SourceRepo].git #[SourceRepo]为新的存放源码的github私有仓库
git checkout -b master # 切换到master分支，
#2020年10月后github新建仓库默认分支改为main，注意更改
# 如果不是，后面的所有设置的分支记得保持一致
git add .
git commit -m &quot;github action update&quot;
git push origin master
#2020年10月后github新建仓库默认分支改为main，注意更改</code></pre></li><li><p>可能遇到的 bug<br>因为 solitude 主题文件夹下的.git 文件夹的存在，那么主题文件夹会被识别子项目。从而无法被上传到源码仓库。若是遇到添加屏蔽项，但是还是无法正常上传主题文件夹的情况。请先将本地源码中的 themes 文件夹移动到别的目录下。然后 commit 一次。接着将 themes 文件夹移动回来，再 commit 一次。</p><div style="border-left: 4px solid #8250df; background-color: #f1e5ff; padding: 16px; margin: 16px 0; border-radius: 4px;">
  <strong style="color: #FA3107;">❗ 重要</strong><br>
<span style="color: #ff6600;">要是还不行，那就删了 solitude 主题文件夹下的.git 文件夹，然后再重复上述的 commit 操作。
</span>
</div><p></details></p></li></ol><h1>挖坑</h1><p>大致写到这，未来或许会有<del>下一章</del>挖坑？但是目前通用的就到这，然后后续会写Qexo的简单使用方法、solitude的一些配置更改和我踩坑经历吧。</p>]]></content:encoded>
        </item>
                <item>
            <title>Markdown 强调语法</title>
            <link>https://blog.zsx815.top/archives/12/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/12/</guid>
            <pubDate>Thu, 17 Jul 25 18:11:00 +0800</pubDate>
            <pubDateFormatted>2025年07月17日18:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; 原文链接: <a href="https://markdown.com.cn/basic-syntax/emphasis.html">https://markdown.com.cn/basic-syntax/emphasis.html</a></p><h2>Markdown 强调语法</h2><p>通过将文本设置为粗体或斜体来强调其重要性。</p><h3>粗体（Bold）</h3><p>要加粗文本，请在单词或短语的前后各添加两个星号（asterisks）或下划线（underscores）。如需加粗一个单词或短语的中间部分用以表示强调的话，请在要加粗部分的两侧各添加两个星号（asterisks）。</p><table><thead><tr><th align="center">Markdown语法</th><th align="center">HTML</th><th align="center">预览效果</th></tr></thead><tbody><tr><td align="center"><code>I just love **bold text**.</code></td><td align="center"><code>I just love &lt;strong&gt;bold text&lt;/strong&gt;.</code></td><td align="center">I just love <strong>bold text</strong>.</td></tr><tr><td align="center"><code>I just love __bold text__.</code></td><td align="center"><code>I just love &lt;strong&gt;bold text&lt;/strong&gt;.</code></td><td align="center">I just love <strong>bold text</strong>.</td></tr><tr><td align="center"><code>Love**is**bold</code></td><td align="center"><code>Love&lt;strong&gt;is&lt;/strong&gt;bold</code></td><td align="center">Love <strong>is</strong> bold</td></tr></tbody></table><h3>粗体（Bold）用法最佳实践</h3><p>Markdown 应用程序在如何处理单词或短语中间的下划线上并不一致。为兼容考虑，在单词或短语中间部分加粗的话，请使用星号（asterisks）。</p><table><thead><tr><th align="center">✅  Do this</th><th align="center">❌  Don't do this</th></tr></thead><tbody><tr><td align="center"><code>Love**is**bold</code></td><td align="center"><code>Love__is__bold</code></td></tr></tbody></table><h3>斜体（Italic）</h3><p>要用斜体显示文本，请在单词或短语前后添加一个星号（asterisk）或下划线（underscore）。要斜体突出单词的中间部分，请在字母前后各添加一个星号，中间不要带空格。</p><table><thead><tr><th align="center">Markdown语法</th><th align="center">HTML</th><th align="center">预览效果</th></tr></thead><tbody><tr><td align="center"><code>This text is ***really important***.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is <strong><em>really important</em></strong>.</td></tr><tr><td align="center"><code>This text is ___really important___.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is ___really important___.</td></tr><tr><td align="center"><code>This text is __*really important*__.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is __<em>really important</em>__.</td></tr><tr><td align="center"><code>This text is **_really important_**.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is <strong><em>really important</em></strong>.</td></tr><tr><td align="center"><code>This is really***very***important text.</code></td><td align="center"><code>This is really&lt;strong&gt;&lt;em&gt;very&lt;/em&gt;&lt;/strong&gt;important text.</code></td><td align="center">This is really <strong><em>very</em></strong> important text.</td></tr></tbody></table><h3>粗体（Bold）和斜体（Italic）用法的最佳实践</h3><p>Markdown 应用程序在处理单词或短语中间添加的下划线上并不一致。为了实现兼容性，请使用星号将单词或短语的中间部分加粗并以斜体显示，以示重要。</p><table><thead><tr><th align="center">✅  Do this</th><th align="center">❌  Don't do this</th></tr></thead><tbody><tr><td align="center"><code>This is really***very***important text.</code></td><td align="center"><code>This is really___very___important text.</code></td></tr></tbody></table>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; 原文链接: <a href="https://markdown.com.cn/basic-syntax/emphasis.html">https://markdown.com.cn/basic-syntax/emphasis.html</a></p><h2>Markdown 强调语法</h2><p>通过将文本设置为粗体或斜体来强调其重要性。</p><h3>粗体（Bold）</h3><p>要加粗文本，请在单词或短语的前后各添加两个星号（asterisks）或下划线（underscores）。如需加粗一个单词或短语的中间部分用以表示强调的话，请在要加粗部分的两侧各添加两个星号（asterisks）。</p><table><thead><tr><th align="center">Markdown语法</th><th align="center">HTML</th><th align="center">预览效果</th></tr></thead><tbody><tr><td align="center"><code>I just love **bold text**.</code></td><td align="center"><code>I just love &lt;strong&gt;bold text&lt;/strong&gt;.</code></td><td align="center">I just love <strong>bold text</strong>.</td></tr><tr><td align="center"><code>I just love __bold text__.</code></td><td align="center"><code>I just love &lt;strong&gt;bold text&lt;/strong&gt;.</code></td><td align="center">I just love <strong>bold text</strong>.</td></tr><tr><td align="center"><code>Love**is**bold</code></td><td align="center"><code>Love&lt;strong&gt;is&lt;/strong&gt;bold</code></td><td align="center">Love <strong>is</strong> bold</td></tr></tbody></table><h3>粗体（Bold）用法最佳实践</h3><p>Markdown 应用程序在如何处理单词或短语中间的下划线上并不一致。为兼容考虑，在单词或短语中间部分加粗的话，请使用星号（asterisks）。</p><table><thead><tr><th align="center">✅  Do this</th><th align="center">❌  Don't do this</th></tr></thead><tbody><tr><td align="center"><code>Love**is**bold</code></td><td align="center"><code>Love__is__bold</code></td></tr></tbody></table><h3>斜体（Italic）</h3><p>要用斜体显示文本，请在单词或短语前后添加一个星号（asterisk）或下划线（underscore）。要斜体突出单词的中间部分，请在字母前后各添加一个星号，中间不要带空格。</p><table><thead><tr><th align="center">Markdown语法</th><th align="center">HTML</th><th align="center">预览效果</th></tr></thead><tbody><tr><td align="center"><code>This text is ***really important***.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is <strong><em>really important</em></strong>.</td></tr><tr><td align="center"><code>This text is ___really important___.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is ___really important___.</td></tr><tr><td align="center"><code>This text is __*really important*__.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is __<em>really important</em>__.</td></tr><tr><td align="center"><code>This text is **_really important_**.</code></td><td align="center"><code>This text is &lt;strong&gt;&lt;em&gt;really important&lt;/em&gt;&lt;/strong&gt;.</code></td><td align="center">This text is <strong><em>really important</em></strong>.</td></tr><tr><td align="center"><code>This is really***very***important text.</code></td><td align="center"><code>This is really&lt;strong&gt;&lt;em&gt;very&lt;/em&gt;&lt;/strong&gt;important text.</code></td><td align="center">This is really <strong><em>very</em></strong> important text.</td></tr></tbody></table><h3>粗体（Bold）和斜体（Italic）用法的最佳实践</h3><p>Markdown 应用程序在处理单词或短语中间添加的下划线上并不一致。为了实现兼容性，请使用星号将单词或短语的中间部分加粗并以斜体显示，以示重要。</p><table><thead><tr><th align="center">✅  Do this</th><th align="center">❌  Don't do this</th></tr></thead><tbody><tr><td align="center"><code>This is really***very***important text.</code></td><td align="center"><code>This is really___very___important text.</code></td></tr></tbody></table>]]></content:encoded>
        </item>
                <item>
            <title>Markdown 换行语法</title>
            <link>https://blog.zsx815.top/archives/15/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/15/</guid>
            <pubDate>Sat, 28 Jun 25 22:11:00 +0800</pubDate>
            <pubDateFormatted>2025年06月28日22:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; 原文链接: <a href="https://markdown.com.cn/basic-syntax/line-breaks.html">https://markdown.com.cn/basic-syntax/line-breaks.html</a></p><h2>Markdown 换行语法</h2><p>在一行的末尾添加两个或多个空格，然后按回车键,即可创建一个换行(<code>&lt;br&gt;</code>)。</p><p>| Markdown语法 |    HTML |    预览效果 |<br>| :---: | :---: | :---: | <br>| <code>This is the first line.  </code><br /><code>And this is the second line.</code> | <code>This is the first line.&lt;br&gt;</code><br /> <code>And this is the second line.</code> | This is the first line.<br /> And this is the second line. |</p><h2>换行（Line Break）用法的最佳实践</h2><p>几乎每个 Markdown 应用程序都支持两个或多个空格进行换行，称为 <code>结尾空格（trailing whitespace)</code> 的方式，但这是有争议的，因为很难在编辑器中直接看到空格，并且很多人在每个句子后面都会有意或无意地添加两个空格。由于这个原因，你可能要使用除结尾空格以外的其它方式来换行。幸运的是，几乎每个 Markdown 应用程序都支持另一种换行方式：HTML 的 <code>&lt;br /&gt;</code> 标签。<br /></p><p>为了兼容性，请在行尾添加“结尾空格”或 HTML 的 <code>&lt;br&gt;</code> 标签来实现换行。<br /></p><p>还有两种其他方式我并不推荐使用。CommonMark 和其它几种轻量级标记语言支持在行尾添加反斜杠 (<code>\</code>) 的方式实现换行，但是并非所有 Markdown 应用程序都支持此种方式，因此从兼容性的角度来看，不推荐使用。并且至少有两种轻量级标记语言支持无须在行尾添加任何内容，只须键入回车键（<code>return</code>）即可实现换行。</p><table><thead><tr><th align="center">✅  Do this</th><th align="center">❌  Don't do this</th></tr></thead><tbody><tr><td align="center"><code>First line with two spaces after.  </code><br /> <code>And the next line.</code></td><td align="center"><code>First line with a backslash after.\</code> <br /> <code>And the next line.</code></td></tr><tr><td align="center"><code>First line with the HTML tag after.&lt;br&gt;</code><br /> <code>And the next line.</code></td><td align="center"><code>First line with nothing after.</code><br /> <code>And the next line.</code></td></tr></tbody></table>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; 原文链接: <a href="https://markdown.com.cn/basic-syntax/line-breaks.html">https://markdown.com.cn/basic-syntax/line-breaks.html</a></p><h2>Markdown 换行语法</h2><p>在一行的末尾添加两个或多个空格，然后按回车键,即可创建一个换行(<code>&lt;br&gt;</code>)。</p><p>| Markdown语法 |    HTML |    预览效果 |<br>| :---: | :---: | :---: | <br>| <code>This is the first line.  </code><br /><code>And this is the second line.</code> | <code>This is the first line.&lt;br&gt;</code><br /> <code>And this is the second line.</code> | This is the first line.<br /> And this is the second line. |</p><h2>换行（Line Break）用法的最佳实践</h2><p>几乎每个 Markdown 应用程序都支持两个或多个空格进行换行，称为 <code>结尾空格（trailing whitespace)</code> 的方式，但这是有争议的，因为很难在编辑器中直接看到空格，并且很多人在每个句子后面都会有意或无意地添加两个空格。由于这个原因，你可能要使用除结尾空格以外的其它方式来换行。幸运的是，几乎每个 Markdown 应用程序都支持另一种换行方式：HTML 的 <code>&lt;br /&gt;</code> 标签。<br /></p><p>为了兼容性，请在行尾添加“结尾空格”或 HTML 的 <code>&lt;br&gt;</code> 标签来实现换行。<br /></p><p>还有两种其他方式我并不推荐使用。CommonMark 和其它几种轻量级标记语言支持在行尾添加反斜杠 (<code>\</code>) 的方式实现换行，但是并非所有 Markdown 应用程序都支持此种方式，因此从兼容性的角度来看，不推荐使用。并且至少有两种轻量级标记语言支持无须在行尾添加任何内容，只须键入回车键（<code>return</code>）即可实现换行。</p><table><thead><tr><th align="center">✅  Do this</th><th align="center">❌  Don't do this</th></tr></thead><tbody><tr><td align="center"><code>First line with two spaces after.  </code><br /> <code>And the next line.</code></td><td align="center"><code>First line with a backslash after.\</code> <br /> <code>And the next line.</code></td></tr><tr><td align="center"><code>First line with the HTML tag after.&lt;br&gt;</code><br /> <code>And the next line.</code></td><td align="center"><code>First line with nothing after.</code><br /> <code>And the next line.</code></td></tr></tbody></table>]]></content:encoded>
        </item>
                <item>
            <title>资源分享：涂鹿Toolooz</title>
            <link>https://blog.zsx815.top/archives/7/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/7/</guid>
            <pubDate>Mon, 19 May 25 23:11:00 +0800</pubDate>
            <pubDateFormatted>2025年05月19日23:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->## 涂鹿Toolooz：曲线文字绘制设计工具，轻松创建沿任意路径排布的精美文字</p><p>　　涂鹿Toolooz，在线曲线文字绘制工具，可使文字沿任意路径排列，打造独特视觉效果。为您的徽标、标题、艺术作品赋予生命力与创意。</p><p>　　支持自定义画布尺寸、文本内容、字体、间距、颜色、描边等，还支持多个绘图工具和选择文本是否重复，可导出为 PNG、WebP 和 SVG 格式，免费使用，无需注册。</p><h2>网站介绍</h2><h3>截图</h3><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505191632987.png" alt="" title=""></p><h3>特色</h3><h4>自由绘制路径</h4><p>　　使用鼠标或触控笔自由绘制路径，或选择预设形状如圆形、方形、椭圆等，轻松创建文字轨迹。</p><h4>文本样式丰富</h4><p>　　自定义字体、大小、颜色、间距等属性，支持文本背景带，打造丰富多样的文字效果。</p><h4>交互式编辑</h4><p>　　直观的选择、移动、缩放和旋转功能，让您精确控制每个文字路径的位置和外观。</p><h4>灵活配置</h4><p>　　自定义画布尺寸、背景色、缩放级别等，适应各种设计场景和需求。</p><h4>多格式导出</h4><p>　　将设计导出为PNG、SVG或WEBP格式，可自定义分辨率和尺寸，轻松应用于各种场景。</p><h4>模板库</h4><p>　　内置多种精美模板，一键应用，快速开始您的创意设计项目</p><h2>应用场景</h2><p>　　涂鹿曲线文字绘制设计工具适用于多种创意设计</p><p>　　创建独特的环形或自定义形状品牌徽标，增强品牌视觉识别度。#社交媒体 #创意设计</p><p>　　为社交媒体平台设计吸引眼球的曲线文字图片，提高内容吸引力。创意海报设计</p><p>　　创建个性化海报和宣传材料，为活动和产品增添创意元素。</p><h2>网站链接</h2><p>　　<a href="https://toolooz.com/">https://toolooz.com</a></p><hr><h2>原文链接</h2><p>　　<a href="https://www.appmiao.com/836/">https://www.appmiao.com/836/</a></p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->## 涂鹿Toolooz：曲线文字绘制设计工具，轻松创建沿任意路径排布的精美文字</p><p>　　涂鹿Toolooz，在线曲线文字绘制工具，可使文字沿任意路径排列，打造独特视觉效果。为您的徽标、标题、艺术作品赋予生命力与创意。</p><p>　　支持自定义画布尺寸、文本内容、字体、间距、颜色、描边等，还支持多个绘图工具和选择文本是否重复，可导出为 PNG、WebP 和 SVG 格式，免费使用，无需注册。</p><h2>网站介绍</h2><h3>截图</h3><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505191632987.png" alt="" title=""></p><h3>特色</h3><h4>自由绘制路径</h4><p>　　使用鼠标或触控笔自由绘制路径，或选择预设形状如圆形、方形、椭圆等，轻松创建文字轨迹。</p><h4>文本样式丰富</h4><p>　　自定义字体、大小、颜色、间距等属性，支持文本背景带，打造丰富多样的文字效果。</p><h4>交互式编辑</h4><p>　　直观的选择、移动、缩放和旋转功能，让您精确控制每个文字路径的位置和外观。</p><h4>灵活配置</h4><p>　　自定义画布尺寸、背景色、缩放级别等，适应各种设计场景和需求。</p><h4>多格式导出</h4><p>　　将设计导出为PNG、SVG或WEBP格式，可自定义分辨率和尺寸，轻松应用于各种场景。</p><h4>模板库</h4><p>　　内置多种精美模板，一键应用，快速开始您的创意设计项目</p><h2>应用场景</h2><p>　　涂鹿曲线文字绘制设计工具适用于多种创意设计</p><p>　　创建独特的环形或自定义形状品牌徽标，增强品牌视觉识别度。#社交媒体 #创意设计</p><p>　　为社交媒体平台设计吸引眼球的曲线文字图片，提高内容吸引力。创意海报设计</p><p>　　创建个性化海报和宣传材料，为活动和产品增添创意元素。</p><h2>网站链接</h2><p>　　<a href="https://toolooz.com/">https://toolooz.com</a></p><hr><h2>原文链接</h2><p>　　<a href="https://www.appmiao.com/836/">https://www.appmiao.com/836/</a></p>]]></content:encoded>
        </item>
                <item>
            <title>来将 Telegram 当音乐播放器吧！</title>
            <link>https://blog.zsx815.top/archives/10/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/10/</guid>
            <pubDate>Thu, 15 May 25 19:11:00 +0800</pubDate>
            <pubDateFormatted>2025年05月15日19:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->## 来将 Telegram 当音乐播放器吧！（寻找音乐、即时歌词、无损音乐不失真压缩）</p><h3>步骤一：到 <a href="https://t.me/music_v1bot">@music_v1bot</a> 下载歌曲，并找到歌词</h3><p>　　<em>输入指令： /search （你想要的歌名）</em></p><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151340118.jpg" alt="" title=""></p><h3>步骤二：<a href="https://telegra.ph/Mtmanager-02-10-2">下载 MT 管理器（点我）</a></h3><blockquote><strong><em><u>开启：下载好的歌词文件</u></em></strong></blockquote><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151343982.jpg" alt="" title=""></p><h3>步骤三：最右上角、搜索\&gt;勾选正则化，替换（全部替换）</h3><blockquote><p><em>输入：[(\d{2}:\d{2}).\d+]</em></p><p><em>替换：$1</em></p></blockquote><p><code>注意：&quot;$1&quot;后面要加一个空格(英文)。</code></p><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151346330.jpg" alt="" title=""></p><blockquote>代码作者：Aric</blockquote><p>　　并将选取好的歌词，粘贴到音乐文件就完成了。</p><h3><a href="https://t.me/TESTLIVEUP">（我是范例-点我查看）</a></h3><div style="text-align:center; font-weight:bold; text-decoration:underline;">须知</div><blockquote>使用：“.FLAC“格式的音乐文件，有时候不能正常显示歌词时间轴，是正常的，所以你可能要转换特定的格式，如.mp3，或是.ogg 或.m4a 的歌曲。</blockquote><p>　　→ 如果你对音乐品质有极致追求，也有电脑 🖥️，我个人极度推荐使用 dBpowerAMP 这类型工具，将无损音乐格式转换成 m4a （水果的算法：QAAC 编码的音乐），目前可以<a href="https://telegra.ph/QAAC-%E5%8E%8B%E7%BC%A9%E9%9F%B3%E4%B9%90%E6%8A%80%E6%9C%AF%E8%AF%A6%E8%A7%A3-08-22">算是当今世界上最好的压缩算法，在通讯界享有盛名</a>，且压缩后可以到接近百分之百还原。（甚至连对音乐/声学研究的职业工作者都讚叹不已）笔者强烈推荐，只叹手机没有类似的软件。专门转成 QAAC 编码的。</p><h3><a href="https://t.me/haoruanfenxianggroup/369211">🖥️ 电脑版 dBpowerAMP 下载/教学请点我</a></h3><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151358822.jpg" alt="" title="">​</p><hr><h3>拓展</h3><p>　　以上是原文内容，如果你改了音乐格式失去了原本的封面，歌手等等东西，一般来说是不妨碍什么的，如果你一定要改的话，可以使用<a href="https://t.me/kemiaosw_me/394">音乐标签</a>。具体使用很简单，我不多赘述，给个视频你就大致明白了：​<code> </code>​</p><p><a href="https://cdn.jsdmirror.com/gh/zsxcoder/picx-images-hosting@master/cover/yinyuebiaoqian.webp"><img src="https://cdn.jsdmirror.com/gh/zsxcoder/picx-images-hosting@master/cover/yinyuebiaoqian.webp" alt="" title=""></a></p><p>　　同时，如果你想更换音乐格式，有很多种方法，以下给一个<a href="https://convertio.co/zh/flac-m4a/">网站</a>。</p><hr><h3>原文链接</h3><p>　　<a href="https://telegra.ph/Telegram-Real-Time-sync-lyrics-05-14">https://telegra.ph/Telegram-Real-Time-sync-lyrics-05-14</a></p><p>　　‍</p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->## 来将 Telegram 当音乐播放器吧！（寻找音乐、即时歌词、无损音乐不失真压缩）</p><h3>步骤一：到 <a href="https://t.me/music_v1bot">@music_v1bot</a> 下载歌曲，并找到歌词</h3><p>　　<em>输入指令： /search （你想要的歌名）</em></p><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151340118.jpg" alt="" title=""></p><h3>步骤二：<a href="https://telegra.ph/Mtmanager-02-10-2">下载 MT 管理器（点我）</a></h3><blockquote><strong><em><u>开启：下载好的歌词文件</u></em></strong></blockquote><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151343982.jpg" alt="" title=""></p><h3>步骤三：最右上角、搜索\&gt;勾选正则化，替换（全部替换）</h3><blockquote><p><em>输入：[(\d{2}:\d{2}).\d+]</em></p><p><em>替换：$1</em></p></blockquote><p><code>注意：&quot;$1&quot;后面要加一个空格(英文)。</code></p><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151346330.jpg" alt="" title=""></p><blockquote>代码作者：Aric</blockquote><p>　　并将选取好的歌词，粘贴到音乐文件就完成了。</p><h3><a href="https://t.me/TESTLIVEUP">（我是范例-点我查看）</a></h3><div style="text-align:center; font-weight:bold; text-decoration:underline;">须知</div><blockquote>使用：“.FLAC“格式的音乐文件，有时候不能正常显示歌词时间轴，是正常的，所以你可能要转换特定的格式，如.mp3，或是.ogg 或.m4a 的歌曲。</blockquote><p>　　→ 如果你对音乐品质有极致追求，也有电脑 🖥️，我个人极度推荐使用 dBpowerAMP 这类型工具，将无损音乐格式转换成 m4a （水果的算法：QAAC 编码的音乐），目前可以<a href="https://telegra.ph/QAAC-%E5%8E%8B%E7%BC%A9%E9%9F%B3%E4%B9%90%E6%8A%80%E6%9C%AF%E8%AF%A6%E8%A7%A3-08-22">算是当今世界上最好的压缩算法，在通讯界享有盛名</a>，且压缩后可以到接近百分之百还原。（甚至连对音乐/声学研究的职业工作者都讚叹不已）笔者强烈推荐，只叹手机没有类似的软件。专门转成 QAAC 编码的。</p><h3><a href="https://t.me/haoruanfenxianggroup/369211">🖥️ 电脑版 dBpowerAMP 下载/教学请点我</a></h3><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505151358822.jpg" alt="" title="">​</p><hr><h3>拓展</h3><p>　　以上是原文内容，如果你改了音乐格式失去了原本的封面，歌手等等东西，一般来说是不妨碍什么的，如果你一定要改的话，可以使用<a href="https://t.me/kemiaosw_me/394">音乐标签</a>。具体使用很简单，我不多赘述，给个视频你就大致明白了：​<code> </code>​</p><p><a href="https://cdn.jsdmirror.com/gh/zsxcoder/picx-images-hosting@master/cover/yinyuebiaoqian.webp"><img src="https://cdn.jsdmirror.com/gh/zsxcoder/picx-images-hosting@master/cover/yinyuebiaoqian.webp" alt="" title=""></a></p><p>　　同时，如果你想更换音乐格式，有很多种方法，以下给一个<a href="https://convertio.co/zh/flac-m4a/">网站</a>。</p><hr><h3>原文链接</h3><p>　　<a href="https://telegra.ph/Telegram-Real-Time-sync-lyrics-05-14">https://telegra.ph/Telegram-Real-Time-sync-lyrics-05-14</a></p><p>　　‍</p>]]></content:encoded>
        </item>
                <item>
            <title>资源分享： DROP</title>
            <link>https://blog.zsx815.top/archives/19/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/19/</guid>
            <pubDate>Fri, 09 May 25 21:24:00 +0800</pubDate>
            <pubDateFormatted>2025年05月09日21:24</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->### 网站简介</p><p>DROP 是一个便捷的文件分享与托管平台，云存储工具，提供免费10GB的存储空间，支持大文件的快速上传与分享。</p><p>支持上传图片、视频、压缩文件和PDF，选择适合文件的文档后，点击拷贝链接即可直接获得分享链接。采用AI驱动技术，确保文件传输的高效性和安全性，同时提供简洁直观的用户界面，方便用户管理和分享文件。DROP 适用于个人用户和创作者，可轻松展示和分发作品</p><hr><h3>截图</h3><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505092144042.png" alt="" title=""></p><hr><h3>功能特色</h3><ul><li><strong>免费10GB存储</strong>：新用户可免费享受10GB的存储空间，满足日常文件分享需求。</li><li><strong>大文件支持</strong>：支持大文件的快速上传与分享，适合分享高清视频、大型文档等。</li><li><strong>AI驱动</strong>：采用AI技术优化文件传输和管理，提升用户体验。</li><li><strong>隐私保护</strong>：提供文件访问控制，保护用户隐私和数据安全。</li><li><strong>简洁界面</strong>：直观的用户界面，易于上手，方便文件管理。</li><li><strong>多平台支持</strong>：支持多种设备和操作系统，方便随时随地访问文件。</li></ul><hr><h3>网站地址</h3><p><a href="https://drop.space/">https://drop.space/</a></p><hr><p><strong>原文链接</strong>: <a href="https://www.appmiu.com/31115.html">https://www.appmiu.com/31115.html</a></p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->### 网站简介</p><p>DROP 是一个便捷的文件分享与托管平台，云存储工具，提供免费10GB的存储空间，支持大文件的快速上传与分享。</p><p>支持上传图片、视频、压缩文件和PDF，选择适合文件的文档后，点击拷贝链接即可直接获得分享链接。采用AI驱动技术，确保文件传输的高效性和安全性，同时提供简洁直观的用户界面，方便用户管理和分享文件。DROP 适用于个人用户和创作者，可轻松展示和分发作品</p><hr><h3>截图</h3><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505092144042.png" alt="" title=""></p><hr><h3>功能特色</h3><ul><li><strong>免费10GB存储</strong>：新用户可免费享受10GB的存储空间，满足日常文件分享需求。</li><li><strong>大文件支持</strong>：支持大文件的快速上传与分享，适合分享高清视频、大型文档等。</li><li><strong>AI驱动</strong>：采用AI技术优化文件传输和管理，提升用户体验。</li><li><strong>隐私保护</strong>：提供文件访问控制，保护用户隐私和数据安全。</li><li><strong>简洁界面</strong>：直观的用户界面，易于上手，方便文件管理。</li><li><strong>多平台支持</strong>：支持多种设备和操作系统，方便随时随地访问文件。</li></ul><hr><h3>网站地址</h3><p><a href="https://drop.space/">https://drop.space/</a></p><hr><p><strong>原文链接</strong>: <a href="https://www.appmiu.com/31115.html">https://www.appmiu.com/31115.html</a></p>]]></content:encoded>
        </item>
                <item>
            <title>tgtalk免费部署</title>
            <link>https://blog.zsx815.top/archives/9/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/9/</guid>
            <pubDate>Sun, 04 May 25 21:01:00 +0800</pubDate>
            <pubDateFormatted>2025年05月04日21:01</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->## 部署 API</p><p>访问 <a href="https://gist.github.com/FloatSheep/55db67d9e8148149ebbcb0f9f6b0d901">Gist</a> 并获取其中所有代码</p><blockquote>需要注意，本 API Worker 脚本基于 ChenYFan 修改，包含了本项目需要使用的功能，请勿随意更改脚本内容<br>TGTalker-Frontend V2 的 API 不兼容 V1</blockquote><p>进入 <a href="https://dash.cloudflare.com">Cloudflare 仪表盘</a></p><p>选择创建应用程序 -&gt; 创建 Worker -&gt; 修改名称（部署）-&gt; 编辑代码</p><p>在其中粘贴你复制的所有代码，并且修改 ChannelName 为你的频道名称，部署并访问 Worker 查看是否能正确返回内容</p><p>接着你可以为你的 Worker 绑定一个域名</p><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505042340004.png" alt="" title=""><br><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505042340138.png" alt="" title=""><br><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505042340963.png" alt="" title=""></p><p>保存，然后将你绑定的域名填入配置中的 api 项即可。</p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->## 部署 API</p><p>访问 <a href="https://gist.github.com/FloatSheep/55db67d9e8148149ebbcb0f9f6b0d901">Gist</a> 并获取其中所有代码</p><blockquote>需要注意，本 API Worker 脚本基于 ChenYFan 修改，包含了本项目需要使用的功能，请勿随意更改脚本内容<br>TGTalker-Frontend V2 的 API 不兼容 V1</blockquote><p>进入 <a href="https://dash.cloudflare.com">Cloudflare 仪表盘</a></p><p>选择创建应用程序 -&gt; 创建 Worker -&gt; 修改名称（部署）-&gt; 编辑代码</p><p>在其中粘贴你复制的所有代码，并且修改 ChannelName 为你的频道名称，部署并访问 Worker 查看是否能正确返回内容</p><p>接着你可以为你的 Worker 绑定一个域名</p><p><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505042340004.png" alt="" title=""><br><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505042340138.png" alt="" title=""><br><img src="https://cdn.jsdelivr.net/gh/kmfx/tuchuang@main/img/202505042340963.png" alt="" title=""></p><p>保存，然后将你绑定的域名填入配置中的 api 项即可。</p>]]></content:encoded>
        </item>
                <item>
            <title>Umami博客访问统计Vercel+Cloudflare Wokers部署</title>
            <link>https://blog.zsx815.top/archives/8/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/8/</guid>
            <pubDate>Mon, 07 Apr 25 17:11:00 +0800</pubDate>
            <pubDateFormatted>2025年04月07日17:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->## 第一部分：Vercel+Umami</p><ol><li><p>第一步<br> 1.1 <kbd>Fork</kbd>​<a href="https://github.com/umami-software/umami">umami</a>到自己的Github仓库</p><p><img src="https://s2.loli.net/2025/04/06/c4xDVNrsBpTM8YZ.webp" alt="" title=""></p><p>1.2 创建项目<br><img src="https://s2.loli.net/2025/04/06/GX9OdivuxF5pJzH.webp" alt="" title=""><br>index.mdx</p></li><li>第二步</li></ol><p>　2.1 创建<a href="https://vercel.com/login">Verce</a>l账号，这里我就省略了，因为GitHub可以直接进行授权即可。</p><p>2.2 在你授权以后，首先创建<kbd>Postgres</kbd>数据库，直接一路下一步，创建好就行，可以给下面的连接复制出来</p><p><img src="https://s2.loli.net/2025/04/06/K69FpfmjZxcu3Ad.webp" alt="" title=""></p><p><img src="https://s2.loli.net/2025/04/06/7OieEKGht4kgSux.webp" alt="" title=""></p><p>　　点击<kbd>Copy Snippet</kbd>​,就可以，记住在粘贴的时候是我画线里面的部分，双引号都不需要 ，因为要设置环境变量。</p><p>　　 2.3 在创建好数据库以后，回到主页面的<kbd>Overview</kbd>​，然后右上角有一个<kbd>Add New</kbd>​选择添加<kbd>Project</kbd>​，选择你<kbd>Fork</kbd>​的<kbd>umami</kbd>​，添加即可。</p><pre><code>2.4 设置环境变量，`DATABASE_URL`​和`HASH_SALT`​和`TRACKER_SCRIPT_NAME`​，其中`DATABASE_URL`​的值就是上面划线的部分，其他的两个环境变量都是对应的值是String自己可以随意定义。</code></pre><p>　　 2.5 设置好以后点击<kbd>Deploy</kbd>​，等待大约两分钟左右，自动部署完成，部署完成以后可以通过下图种面板上面给的链接可以直接访问。</p><p><img src="https://s2.loli.net/2025/04/06/ahX2wHLrfYAD7ZW.webp" alt="" title=""></p><p>　　 2.6 打开以后会跳出登录地址，默认的登录密码是<kbd>adminumami</kbd>​，登录进去以后，设置给自己密码修改了，然后就是设置里面添加网站，给你要统计的网站添加进去，到此，别人访问你的网站你可以通过面板看到统计数据了。</p><h2>第二部分：Umami+Cloudflare worker</h2><p>这一部分主要是让你的博客上面能展示的访问数据，效果如下：</p><p><img src="https://s2.loli.net/2025/04/06/fR71aFG4oMD29Pz.webp" alt="image" title="image"></p><ol><li>注册<kbd>CloudFlare</kbd>​账号，然后进去以后，选择<kbd>Workers</kbd>​和<kbd>Pages</kbd>​，点击<kbd>创建</kbd>​，再点击<kbd>部署</kbd></li></ol><p><img src="https://s2.loli.net/2025/04/06/CYojqdGHkiuFepQ.webp" alt="" title=""></p><p><img src="https://s2.loli.net/2025/04/06/6B2rXxk4Uu71GQC.webp" alt="" title=""></p><p>　　部署以后，进去点击编辑代码，将里面的代码进行替换：</p><pre><code>addEventListener(&#039;fetch&#039;, event =&gt; {
  event.respondWith(handleRequest(event));
});

const API_BASE_URL = &#039;https://umami.yourdomain.com&#039;;  // 替换你的刚才部署的umami的域名
const TOKEN = &#039;your_token&#039;; // 获取的token
const WEBSITE_ID = &#039;your_website_id&#039;; // 在umami添加网站的 webstie id
const CACHE_KEY = &#039;umami_cache&#039;;
const CACHE_TIME = 600; // Cache time in seconds

async function fetchUmamiData(startAt, endAt) {
  const url = `${API_BASE_URL}/api/websites/${WEBSITE_ID}/stats?startAt=${startAt}&amp;endAt=${endAt}`;
  const response = await fetch(url, {
    headers: {
      &#039;Authorization&#039;: `Bearer ${TOKEN}`,
      &#039;Content-Type&#039;: &#039;application/json&#039;
    }
  });

  if (!response.ok) {
    console.error(`Error fetching data: ${response.statusText}`);
    return null;
  }

  return response.json();
}

async function handleRequest(event) {
  const cache = await caches.open(CACHE_KEY);
  const cachedResponse = await cache.match(event.request);

  if (cachedResponse) {
    return cachedResponse;
  }

  const now = Date.now();
  const todayStart = new Date(now).setHours(0, 0, 0, 0);
  const yesterdayStart = new Date(now - 86400000).setHours(0, 0, 0, 0);
  const lastMonthStart = new Date(now).setMonth(new Date(now).getMonth() - 1);
  const lastYearStart = new Date(now).setFullYear(new Date(now).getFullYear() - 1);

  const [todayData, yesterdayData, lastMonthData, lastYearData] = await Promise.all([
    fetchUmamiData(todayStart, now),
    fetchUmamiData(yesterdayStart, todayStart),
    fetchUmamiData(lastMonthStart, now),
    fetchUmamiData(lastYearStart, now)
  ]);

  const responseData = {
    today_uv: todayData?.visitors?.value ?? null,
    today_pv: todayData?.pageviews?.value ?? null,
    yesterday_uv: yesterdayData?.visitors?.value ?? null,
    yesterday_pv: yesterdayData?.pageviews?.value ?? null,
    last_month_pv: lastMonthData?.pageviews?.value ?? null,
    last_year_pv: lastYearData?.pageviews?.value ?? null
  };

  const jsonResponse = new Response(JSON.stringify(responseData), {
    headers: {
      &#039;Content-Type&#039;: &#039;application/json&#039;,
      &#039;Access-Control-Allow-Origin&#039;: &#039;*&#039;,
      &#039;Access-Control-Allow-Methods&#039;: &#039;GET, POST, PUT, DELETE, OPTIONS&#039;,
      &#039;Access-Control-Allow-Headers&#039;: &#039;Content-Type, Authorization&#039;
    }
  });

  event.waitUntil(cache.put(event.request, jsonResponse.clone()));

  return jsonResponse;
}</code></pre><p>　　但是里面有几个比较重要的参数需要修改<code>API_BASE_URL</code>​、<code>TOKEN</code>​、<code>WEBSITE_ID</code>​其中<code>API_BASE_URL</code>​和<code>WEBSITE_ID</code>​已经是有的，<code>WEBSITE_ID</code>​在<kbd>umami</kbd>​中的设置，选择你已经添加好的网站，点击<kbd>编辑</kbd>​，会出现网站的<code>WEBSITE_ID</code>​：</p><p><img src="https://s2.loli.net/2025/04/06/eFHEYB45nQOUAML.webp" alt="" title=""></p><p>　　 2.2 获取<kbd>token</kbd>​，在想<kbd>api</kbd>​测试网站，<a href="https://hoppscotch.io/">hoppscotch</a>，跳转到这个页面以后，如下图所示</p><p><img src="https://s2.loli.net/2025/04/06/vXrQmtpu4HdIasN.webp" alt="" title=""></p><p>　　  2.2.1 请求方式选择<kbd>post</kbd>​，链接填写方式是：</p><pre><code>https://你的umami域名或者是链接/api/auth/login</code></pre><p>　　  2.2.2 请求体选择<kbd>Body</kbd>​参数格式选择<kbd>application/json</kbd></p><pre><code>{
 &quot;username&quot;:&quot;用户名&quot;,
 &quot;password&quot;:&quot;密码&quot;
}</code></pre><p>　　  2.2.3 返回结果中<kbd>token</kbd>​里面的内容就是需要的<kbd>token</kbd></p><pre><code>{
  &quot;token&quot;: &quot;你的token&quot;, # 你需要记录下来的内容
  &quot;user&quot;: {
    &quot;id&quot;: &quot;41e2b680-648e-4b09-bcd7-3e2b10c06264&quot;,
    &quot;username&quot;: &quot;admin&quot;,
    &quot;role&quot;: &quot;admin&quot;,
    &quot;createdAt&quot;: &quot;2024-11-12T09:18:12.766Z&quot;,
    &quot;isAdmin&quot;: true
  }
}</code></pre><p>　　到这里，你部署<code>api</code>​所需要的所有参数内容都已经有了，给替换进去即可。</p><p>　　 2.3 测试在你部署好以后，会有一个链接，当然你如果是用<kbd>cloudflare</kbd>​代理你的域名，可以直接进行关联。</p><p><img src="https://s2.loli.net/2025/04/07/IPCS2rhLbiaX3G8.webp" alt="" title=""></p><p>　　然后点击或则是复制粘贴到浏览器，请求以后会出来下面的结果：</p><p><img src="https://s2.loli.net/2025/04/07/M9wsiYKBoGyLI8T.webp" alt="" title=""></p><p>　　如果没有结果，建议你先去你部署的umami面板里面看看有没有数据，有数据的情况下，这里请求都会有数据的，清理浏览器缓存开代理在测试。</p><h2>第三部分：添加博客统计</h2><p>　　将数据添加到<kbd>about</kbd>​页面</p><pre><code>tj: # 统计
  provider: custom # custom
  url: 你的数据接口地址
  img: https://7.isyangs.cn/1/65eb2e9109826-1.png # 背景
  desc: # 卡片左下角描述</code></pre><p>　　配置完成~</p><p>　　感谢<a href="https://blog.starsharbor.com/">starsharbor</a>大佬博客的指导，<a href="https://blog.starsharbor.com/posts/solitude-about_umami/">原文</a></p><hr><h2>作者原文</h2><p>作者: Couture<br>链接: <a href="https://www.coutures.top/posts/27233.html">https://www.coutures.top/posts/27233.html</a><br>来源: Couture<br>著作权归作者所有。 商业转载请联系作者获得授权，非商业转载请注明出处。</p>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->## 第一部分：Vercel+Umami</p><ol><li><p>第一步<br> 1.1 <kbd>Fork</kbd>​<a href="https://github.com/umami-software/umami">umami</a>到自己的Github仓库</p><p><img src="https://s2.loli.net/2025/04/06/c4xDVNrsBpTM8YZ.webp" alt="" title=""></p><p>1.2 创建项目<br><img src="https://s2.loli.net/2025/04/06/GX9OdivuxF5pJzH.webp" alt="" title=""><br>index.mdx</p></li><li>第二步</li></ol><p>　2.1 创建<a href="https://vercel.com/login">Verce</a>l账号，这里我就省略了，因为GitHub可以直接进行授权即可。</p><p>2.2 在你授权以后，首先创建<kbd>Postgres</kbd>数据库，直接一路下一步，创建好就行，可以给下面的连接复制出来</p><p><img src="https://s2.loli.net/2025/04/06/K69FpfmjZxcu3Ad.webp" alt="" title=""></p><p><img src="https://s2.loli.net/2025/04/06/7OieEKGht4kgSux.webp" alt="" title=""></p><p>　　点击<kbd>Copy Snippet</kbd>​,就可以，记住在粘贴的时候是我画线里面的部分，双引号都不需要 ，因为要设置环境变量。</p><p>　　 2.3 在创建好数据库以后，回到主页面的<kbd>Overview</kbd>​，然后右上角有一个<kbd>Add New</kbd>​选择添加<kbd>Project</kbd>​，选择你<kbd>Fork</kbd>​的<kbd>umami</kbd>​，添加即可。</p><pre><code>2.4 设置环境变量，`DATABASE_URL`​和`HASH_SALT`​和`TRACKER_SCRIPT_NAME`​，其中`DATABASE_URL`​的值就是上面划线的部分，其他的两个环境变量都是对应的值是String自己可以随意定义。</code></pre><p>　　 2.5 设置好以后点击<kbd>Deploy</kbd>​，等待大约两分钟左右，自动部署完成，部署完成以后可以通过下图种面板上面给的链接可以直接访问。</p><p><img src="https://s2.loli.net/2025/04/06/ahX2wHLrfYAD7ZW.webp" alt="" title=""></p><p>　　 2.6 打开以后会跳出登录地址，默认的登录密码是<kbd>adminumami</kbd>​，登录进去以后，设置给自己密码修改了，然后就是设置里面添加网站，给你要统计的网站添加进去，到此，别人访问你的网站你可以通过面板看到统计数据了。</p><h2>第二部分：Umami+Cloudflare worker</h2><p>这一部分主要是让你的博客上面能展示的访问数据，效果如下：</p><p><img src="https://s2.loli.net/2025/04/06/fR71aFG4oMD29Pz.webp" alt="image" title="image"></p><ol><li>注册<kbd>CloudFlare</kbd>​账号，然后进去以后，选择<kbd>Workers</kbd>​和<kbd>Pages</kbd>​，点击<kbd>创建</kbd>​，再点击<kbd>部署</kbd></li></ol><p><img src="https://s2.loli.net/2025/04/06/CYojqdGHkiuFepQ.webp" alt="" title=""></p><p><img src="https://s2.loli.net/2025/04/06/6B2rXxk4Uu71GQC.webp" alt="" title=""></p><p>　　部署以后，进去点击编辑代码，将里面的代码进行替换：</p><pre><code>addEventListener(&#039;fetch&#039;, event =&gt; {
  event.respondWith(handleRequest(event));
});

const API_BASE_URL = &#039;https://umami.yourdomain.com&#039;;  // 替换你的刚才部署的umami的域名
const TOKEN = &#039;your_token&#039;; // 获取的token
const WEBSITE_ID = &#039;your_website_id&#039;; // 在umami添加网站的 webstie id
const CACHE_KEY = &#039;umami_cache&#039;;
const CACHE_TIME = 600; // Cache time in seconds

async function fetchUmamiData(startAt, endAt) {
  const url = `${API_BASE_URL}/api/websites/${WEBSITE_ID}/stats?startAt=${startAt}&amp;endAt=${endAt}`;
  const response = await fetch(url, {
    headers: {
      &#039;Authorization&#039;: `Bearer ${TOKEN}`,
      &#039;Content-Type&#039;: &#039;application/json&#039;
    }
  });

  if (!response.ok) {
    console.error(`Error fetching data: ${response.statusText}`);
    return null;
  }

  return response.json();
}

async function handleRequest(event) {
  const cache = await caches.open(CACHE_KEY);
  const cachedResponse = await cache.match(event.request);

  if (cachedResponse) {
    return cachedResponse;
  }

  const now = Date.now();
  const todayStart = new Date(now).setHours(0, 0, 0, 0);
  const yesterdayStart = new Date(now - 86400000).setHours(0, 0, 0, 0);
  const lastMonthStart = new Date(now).setMonth(new Date(now).getMonth() - 1);
  const lastYearStart = new Date(now).setFullYear(new Date(now).getFullYear() - 1);

  const [todayData, yesterdayData, lastMonthData, lastYearData] = await Promise.all([
    fetchUmamiData(todayStart, now),
    fetchUmamiData(yesterdayStart, todayStart),
    fetchUmamiData(lastMonthStart, now),
    fetchUmamiData(lastYearStart, now)
  ]);

  const responseData = {
    today_uv: todayData?.visitors?.value ?? null,
    today_pv: todayData?.pageviews?.value ?? null,
    yesterday_uv: yesterdayData?.visitors?.value ?? null,
    yesterday_pv: yesterdayData?.pageviews?.value ?? null,
    last_month_pv: lastMonthData?.pageviews?.value ?? null,
    last_year_pv: lastYearData?.pageviews?.value ?? null
  };

  const jsonResponse = new Response(JSON.stringify(responseData), {
    headers: {
      &#039;Content-Type&#039;: &#039;application/json&#039;,
      &#039;Access-Control-Allow-Origin&#039;: &#039;*&#039;,
      &#039;Access-Control-Allow-Methods&#039;: &#039;GET, POST, PUT, DELETE, OPTIONS&#039;,
      &#039;Access-Control-Allow-Headers&#039;: &#039;Content-Type, Authorization&#039;
    }
  });

  event.waitUntil(cache.put(event.request, jsonResponse.clone()));

  return jsonResponse;
}</code></pre><p>　　但是里面有几个比较重要的参数需要修改<code>API_BASE_URL</code>​、<code>TOKEN</code>​、<code>WEBSITE_ID</code>​其中<code>API_BASE_URL</code>​和<code>WEBSITE_ID</code>​已经是有的，<code>WEBSITE_ID</code>​在<kbd>umami</kbd>​中的设置，选择你已经添加好的网站，点击<kbd>编辑</kbd>​，会出现网站的<code>WEBSITE_ID</code>​：</p><p><img src="https://s2.loli.net/2025/04/06/eFHEYB45nQOUAML.webp" alt="" title=""></p><p>　　 2.2 获取<kbd>token</kbd>​，在想<kbd>api</kbd>​测试网站，<a href="https://hoppscotch.io/">hoppscotch</a>，跳转到这个页面以后，如下图所示</p><p><img src="https://s2.loli.net/2025/04/06/vXrQmtpu4HdIasN.webp" alt="" title=""></p><p>　　  2.2.1 请求方式选择<kbd>post</kbd>​，链接填写方式是：</p><pre><code>https://你的umami域名或者是链接/api/auth/login</code></pre><p>　　  2.2.2 请求体选择<kbd>Body</kbd>​参数格式选择<kbd>application/json</kbd></p><pre><code>{
 &quot;username&quot;:&quot;用户名&quot;,
 &quot;password&quot;:&quot;密码&quot;
}</code></pre><p>　　  2.2.3 返回结果中<kbd>token</kbd>​里面的内容就是需要的<kbd>token</kbd></p><pre><code>{
  &quot;token&quot;: &quot;你的token&quot;, # 你需要记录下来的内容
  &quot;user&quot;: {
    &quot;id&quot;: &quot;41e2b680-648e-4b09-bcd7-3e2b10c06264&quot;,
    &quot;username&quot;: &quot;admin&quot;,
    &quot;role&quot;: &quot;admin&quot;,
    &quot;createdAt&quot;: &quot;2024-11-12T09:18:12.766Z&quot;,
    &quot;isAdmin&quot;: true
  }
}</code></pre><p>　　到这里，你部署<code>api</code>​所需要的所有参数内容都已经有了，给替换进去即可。</p><p>　　 2.3 测试在你部署好以后，会有一个链接，当然你如果是用<kbd>cloudflare</kbd>​代理你的域名，可以直接进行关联。</p><p><img src="https://s2.loli.net/2025/04/07/IPCS2rhLbiaX3G8.webp" alt="" title=""></p><p>　　然后点击或则是复制粘贴到浏览器，请求以后会出来下面的结果：</p><p><img src="https://s2.loli.net/2025/04/07/M9wsiYKBoGyLI8T.webp" alt="" title=""></p><p>　　如果没有结果，建议你先去你部署的umami面板里面看看有没有数据，有数据的情况下，这里请求都会有数据的，清理浏览器缓存开代理在测试。</p><h2>第三部分：添加博客统计</h2><p>　　将数据添加到<kbd>about</kbd>​页面</p><pre><code>tj: # 统计
  provider: custom # custom
  url: 你的数据接口地址
  img: https://7.isyangs.cn/1/65eb2e9109826-1.png # 背景
  desc: # 卡片左下角描述</code></pre><p>　　配置完成~</p><p>　　感谢<a href="https://blog.starsharbor.com/">starsharbor</a>大佬博客的指导，<a href="https://blog.starsharbor.com/posts/solitude-about_umami/">原文</a></p><hr><h2>作者原文</h2><p>作者: Couture<br>链接: <a href="https://www.coutures.top/posts/27233.html">https://www.coutures.top/posts/27233.html</a><br>来源: Couture<br>著作权归作者所有。 商业转载请联系作者获得授权，非商业转载请注明出处。</p>]]></content:encoded>
        </item>
                <item>
            <title>Git 同步上游仓库的更新</title>
            <link>https://blog.zsx815.top/archives/18/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/18/</guid>
            <pubDate>Fri, 04 Apr 25 22:16:00 +0800</pubDate>
            <pubDateFormatted>2025年04月04日22:16</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->## Git 同步上游仓库的更新</p><p>　　使用一个 Github Template 创建了我自己的仓库，需要同步一下补丁更新，总不能自己手抄一遍吧，搜了一下解决方案。</p><p>　　记录一下。</p><h3>添加上游仓库</h3><p>　　给上游仓库取个名字，如果将命名为 <code>upstream</code>​ ，可以在本地仓库中运行以下命令：</p><pre><code class="lang-sh">git remote add upstream https://github.com/$&lt;upstream-repo&gt;.git</code></pre><h3>获取上游仓库的更改</h3><p>　　运行以下命令以获取上游仓库中的所有分支和提交：</p><pre><code class="lang-sh">git fetch upstream</code></pre><h3>合并上游更改</h3><p>　　现在，将上游 main 分支的更改合并到您的本地 main 分支：</p><pre><code class="lang-sh">git merge upstream/main --allow-unrelated-histories</code></pre><p>　　如果只需要合并特定的 commit ：</p><pre><code class="lang-sh">git cherry-pick &lt;commit-hash&gt;</code></pre><p>　　也可以使用</p><pre><code class="lang-sh">gcp &lt;commit-hash&gt;</code></pre><p>　　commit-hash 可以直接从 github 网页上复制。</p><p>　　这时 commit 的作者是源仓库的作者， Vercel 提示我 Build 失败，需要升级到 Pro，可以再修改一个文件，自己添加一条 commit 。</p><p>　　当然这很不优雅，可以使用下面的命令获取更改到文件，但是不会提交 commit ，</p><pre><code class="lang-sh">git cherry-pick &lt;commit-hash&gt; --no-commit</code></pre><p>　　然后手动提交一下</p><pre><code class="lang-sh">git commit -m &quot;commit information&quot;</code></pre><h3>解决冲突</h3><p>　　如何自己已经修改过源代码，在合并过程中可能发生冲突，需要手动解决。  <br>Git 也会进行提示，手动编辑冲突文件并保存，然后再提交更改。</p><h3>批量提交</h3><pre><code class="lang-sh">git cherry-pick &lt;起始提交&gt;^..&lt;结束提交&gt;</code></pre><p>　　如果有冲突会按照顺序处理，然后执行， continue 直到结束</p><pre><code class="lang-sh">git cherry-pick --continue</code></pre><ul><li>​<code>&lt;起始提交&gt;</code>​：范围的开始点（不包含此提交，除非用 \&lt;起始提交\&gt;\~ 或 \&lt;起始提交\&gt;^）。</li><li>​<code>&lt;结束提交&gt;</code>​：范围的结束点（包含此提交）。</li><li>​<code>^</code>​ 是 Git 的语法，用于指定“之前的提交”。</li><li>​<code>..</code>​ 表示范围。</li></ul><h3>推送</h3><pre><code class="lang-sh">git push origin main</code></pre><p>　　当然默认来说，并不会推送到新加入的 <code>upstream</code>​ ，直接 <code>git push</code>​ 即可</p><p>　　如果不再需要同步，可以删除上游的仓库</p><pre><code class="lang-sh">git remote remove upstream</code></pre>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->## Git 同步上游仓库的更新</p><p>　　使用一个 Github Template 创建了我自己的仓库，需要同步一下补丁更新，总不能自己手抄一遍吧，搜了一下解决方案。</p><p>　　记录一下。</p><h3>添加上游仓库</h3><p>　　给上游仓库取个名字，如果将命名为 <code>upstream</code>​ ，可以在本地仓库中运行以下命令：</p><pre><code class="lang-sh">git remote add upstream https://github.com/$&lt;upstream-repo&gt;.git</code></pre><h3>获取上游仓库的更改</h3><p>　　运行以下命令以获取上游仓库中的所有分支和提交：</p><pre><code class="lang-sh">git fetch upstream</code></pre><h3>合并上游更改</h3><p>　　现在，将上游 main 分支的更改合并到您的本地 main 分支：</p><pre><code class="lang-sh">git merge upstream/main --allow-unrelated-histories</code></pre><p>　　如果只需要合并特定的 commit ：</p><pre><code class="lang-sh">git cherry-pick &lt;commit-hash&gt;</code></pre><p>　　也可以使用</p><pre><code class="lang-sh">gcp &lt;commit-hash&gt;</code></pre><p>　　commit-hash 可以直接从 github 网页上复制。</p><p>　　这时 commit 的作者是源仓库的作者， Vercel 提示我 Build 失败，需要升级到 Pro，可以再修改一个文件，自己添加一条 commit 。</p><p>　　当然这很不优雅，可以使用下面的命令获取更改到文件，但是不会提交 commit ，</p><pre><code class="lang-sh">git cherry-pick &lt;commit-hash&gt; --no-commit</code></pre><p>　　然后手动提交一下</p><pre><code class="lang-sh">git commit -m &quot;commit information&quot;</code></pre><h3>解决冲突</h3><p>　　如何自己已经修改过源代码，在合并过程中可能发生冲突，需要手动解决。  <br>Git 也会进行提示，手动编辑冲突文件并保存，然后再提交更改。</p><h3>批量提交</h3><pre><code class="lang-sh">git cherry-pick &lt;起始提交&gt;^..&lt;结束提交&gt;</code></pre><p>　　如果有冲突会按照顺序处理，然后执行， continue 直到结束</p><pre><code class="lang-sh">git cherry-pick --continue</code></pre><ul><li>​<code>&lt;起始提交&gt;</code>​：范围的开始点（不包含此提交，除非用 \&lt;起始提交\&gt;\~ 或 \&lt;起始提交\&gt;^）。</li><li>​<code>&lt;结束提交&gt;</code>​：范围的结束点（包含此提交）。</li><li>​<code>^</code>​ 是 Git 的语法，用于指定“之前的提交”。</li><li>​<code>..</code>​ 表示范围。</li></ul><h3>推送</h3><pre><code class="lang-sh">git push origin main</code></pre><p>　　当然默认来说，并不会推送到新加入的 <code>upstream</code>​ ，直接 <code>git push</code>​ 即可</p><p>　　如果不再需要同步，可以删除上游的仓库</p><pre><code class="lang-sh">git remote remove upstream</code></pre>]]></content:encoded>
        </item>
                <item>
            <title>Markdown 段落语法</title>
            <link>https://blog.zsx815.top/archives/13/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/13/</guid>
            <pubDate>Thu, 13 Feb 25 18:11:00 +0800</pubDate>
            <pubDateFormatted>2025年02月13日18:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; 原文位置: <a href="https://markdown.com.cn/basic-syntax/paragraphs.html">https://markdown.com.cn/basic-syntax/paragraphs.html</a></p><h2>Markdown 段落</h2><p>要创建段落，请使用空白行将一行或多行文本进行分隔。</p><table><thead><tr><th>Markdown语法</th><th>HTML</th><th>预览效果</th></tr></thead><tbody><tr><td><code>I really like using Markdown.</code></td><td><code>&lt;p&gt;I really like using Markdown.&lt;/p&gt;</code></td><td><p>I really like using Markdown.</p></td></tr><tr><td><code>I think I&#039;ll use it to format all of my documents from now on.</code></td><td><code>&lt;p&gt;I think I&#039;ll use it to format all of my documents from now on.&lt;/p&gt;</code></td><td><p>I think I'll use it to format all of my documents from now on.</p></td></tr></tbody></table><h2>段落（Paragraph）用法的最佳实践</h2><p>不要用空格（spaces）或制表符（ tabs）缩进段落。</p><table><thead><tr><th>✅  Do this</th><th>❌  Don't do this</th></tr></thead><tbody><tr><td><code>Don&#039;t put tabs or spaces in front of your paragraphs.</code></td><td><code>    This can result in unexpected formatting problems.</code></td></tr><tr><td><code>Keep lines left-aligned like this.</code></td><td><code>  Don&#039;t add tabs or spaces in front of paragraphs.</code></td></tr></tbody></table>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; 原文位置: <a href="https://markdown.com.cn/basic-syntax/paragraphs.html">https://markdown.com.cn/basic-syntax/paragraphs.html</a></p><h2>Markdown 段落</h2><p>要创建段落，请使用空白行将一行或多行文本进行分隔。</p><table><thead><tr><th>Markdown语法</th><th>HTML</th><th>预览效果</th></tr></thead><tbody><tr><td><code>I really like using Markdown.</code></td><td><code>&lt;p&gt;I really like using Markdown.&lt;/p&gt;</code></td><td><p>I really like using Markdown.</p></td></tr><tr><td><code>I think I&#039;ll use it to format all of my documents from now on.</code></td><td><code>&lt;p&gt;I think I&#039;ll use it to format all of my documents from now on.&lt;/p&gt;</code></td><td><p>I think I'll use it to format all of my documents from now on.</p></td></tr></tbody></table><h2>段落（Paragraph）用法的最佳实践</h2><p>不要用空格（spaces）或制表符（ tabs）缩进段落。</p><table><thead><tr><th>✅  Do this</th><th>❌  Don't do this</th></tr></thead><tbody><tr><td><code>Don&#039;t put tabs or spaces in front of your paragraphs.</code></td><td><code>    This can result in unexpected formatting problems.</code></td></tr><tr><td><code>Keep lines left-aligned like this.</code></td><td><code>  Don&#039;t add tabs or spaces in front of paragraphs.</code></td></tr></tbody></table>]]></content:encoded>
        </item>
                <item>
            <title>Markdown-标题语法 </title>
            <link>https://blog.zsx815.top/archives/14/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/14/</guid>
            <pubDate>Wed, 12 Feb 25 18:56:00 +0800</pubDate>
            <pubDateFormatted>2025年02月12日18:56</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; 原文位置: <a href="https://markdown.com.cn/basic-syntax/headings.html">https://markdown.com.cn/basic-syntax/headings.html</a></p><h1>Markdown 标题语法</h1><p>要创建标题，请在单词或短语前面添加井号 (#) 。<code>#</code> 的数量代表了标题的级别。例如，添加三个 <code>#</code> 表示创建一个三级标题 (<code>&lt;h3&gt;</code>) (例如：<code>### My Header</code>)。</p><table><thead><tr><th>Markdown语法</th><th>HTML</th><th>预览效果</th></tr></thead><tbody><tr><td><code># Heading level 1</code></td><td>&lt;h1&gt;Heading level 1&lt;/h1&gt;</td><td><h1>Heading level 1</h1></td></tr><tr><td><code>## Heading level 2</code></td><td>&lt;h2&gt;Heading level 1&lt;/h2&gt;</td><td><h2>Heading level 2</h2></td></tr><tr><td><code>### Heading level 3</code></td><td>&lt;h3&gt;Heading level 1&lt;/h3&gt;</td><td><h3>Heading level 3</h3></td></tr><tr><td><code>#### Heading level 4</code></td><td>&lt;h4&gt;Heading level 1&lt;/h4&gt;</td><td><h4>Heading level 4</h4></td></tr><tr><td><code>##### Heading level 5</code></td><td>&lt;h5&gt;Heading level 1&lt;/h5&gt;</td><td><h5>Heading level 5</h5></td></tr><tr><td><code>###### Heading level 6</code></td><td>&lt;h6&gt;Heading level 1&lt;/h6&gt;</td><td><h6>Heading level 6</h6></td></tr></tbody></table><h2>可选语法</h2><p>还可以在文本下方添加任意数量的 == 号来标识一级标题，或者 -- 号来标识二级标题。</p><table><thead><tr><th>Markdown语法</th><th>HTML</th><th><div style="width:100px;">预览效果</div></th></tr></thead><tbody><tr><td><code>Heading level 1</code><br /><code>===============</code></td><td>&lt;h1&gt;Heading level 1&lt;/h1&gt;</td><td><h1>Heading level 1</h1></td></tr><tr><td><code>Heading level 2</code><br /><code>---------------</code></td><td>&lt;h2&gt;Heading level 2&lt;/h2&gt;</td><td><h2>Heading level 2</h2></td></tr></tbody></table><h2>最佳实践</h2><p>不同的 <strong>Markdown</strong> 应用程序处理 <code>#</code> 和标题之间的空格方式并不一致。为了兼容考虑，请用一个空格在 <code>#</code> 和标题之间进行分隔。</p><table><thead><tr><th>✅  Do this</th><th>❌  Don't do this</th></tr></thead><tbody><tr><td><code># Here&#039;s a Heading</code></td><td><code>#Here&#039;s a Heading</code></td></tr></tbody></table>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; 原文位置: <a href="https://markdown.com.cn/basic-syntax/headings.html">https://markdown.com.cn/basic-syntax/headings.html</a></p><h1>Markdown 标题语法</h1><p>要创建标题，请在单词或短语前面添加井号 (#) 。<code>#</code> 的数量代表了标题的级别。例如，添加三个 <code>#</code> 表示创建一个三级标题 (<code>&lt;h3&gt;</code>) (例如：<code>### My Header</code>)。</p><table><thead><tr><th>Markdown语法</th><th>HTML</th><th>预览效果</th></tr></thead><tbody><tr><td><code># Heading level 1</code></td><td>&lt;h1&gt;Heading level 1&lt;/h1&gt;</td><td><h1>Heading level 1</h1></td></tr><tr><td><code>## Heading level 2</code></td><td>&lt;h2&gt;Heading level 1&lt;/h2&gt;</td><td><h2>Heading level 2</h2></td></tr><tr><td><code>### Heading level 3</code></td><td>&lt;h3&gt;Heading level 1&lt;/h3&gt;</td><td><h3>Heading level 3</h3></td></tr><tr><td><code>#### Heading level 4</code></td><td>&lt;h4&gt;Heading level 1&lt;/h4&gt;</td><td><h4>Heading level 4</h4></td></tr><tr><td><code>##### Heading level 5</code></td><td>&lt;h5&gt;Heading level 1&lt;/h5&gt;</td><td><h5>Heading level 5</h5></td></tr><tr><td><code>###### Heading level 6</code></td><td>&lt;h6&gt;Heading level 1&lt;/h6&gt;</td><td><h6>Heading level 6</h6></td></tr></tbody></table><h2>可选语法</h2><p>还可以在文本下方添加任意数量的 == 号来标识一级标题，或者 -- 号来标识二级标题。</p><table><thead><tr><th>Markdown语法</th><th>HTML</th><th><div style="width:100px;">预览效果</div></th></tr></thead><tbody><tr><td><code>Heading level 1</code><br /><code>===============</code></td><td>&lt;h1&gt;Heading level 1&lt;/h1&gt;</td><td><h1>Heading level 1</h1></td></tr><tr><td><code>Heading level 2</code><br /><code>---------------</code></td><td>&lt;h2&gt;Heading level 2&lt;/h2&gt;</td><td><h2>Heading level 2</h2></td></tr></tbody></table><h2>最佳实践</h2><p>不同的 <strong>Markdown</strong> 应用程序处理 <code>#</code> 和标题之间的空格方式并不一致。为了兼容考虑，请用一个空格在 <code>#</code> 和标题之间进行分隔。</p><table><thead><tr><th>✅  Do this</th><th>❌  Don't do this</th></tr></thead><tbody><tr><td><code># Here&#039;s a Heading</code></td><td><code>#Here&#039;s a Heading</code></td></tr></tbody></table>]]></content:encoded>
        </item>
                <item>
            <title>Markdown-速查表</title>
            <link>https://blog.zsx815.top/archives/11/</link>
            <guid isPermaLink="true">https://blog.zsx815.top/archives/11/</guid>
            <pubDate>Tue, 11 Feb 25 18:11:00 +0800</pubDate>
            <pubDateFormatted>2025年02月11日18:11</pubDateFormatted>
            <dc:creator>ZSXの小站</dc:creator>
            <description><![CDATA[<p><!--markdown-->&gt; 原文位置: <a href="https://markdown.com.cn/cheat-sheet.html#%E6%80%BB%E8%A7%88">https://markdown.com.cn/cheat-sheet.html#%E6%80%BB%E8%A7%88</a></p><h1>总览</h1><p>Markdown 速查表提供了所有 <strong>Markdown</strong><br>语法元素的基本解释。如果你想了解某些语法元素的更多信息，请参阅更详细的<br><strong>基本语法</strong> 和 <strong>扩展语法</strong>.</p><h2>基本语法</h2><p>这些是 <strong>John Gruber</strong> 的原始设计文档中列出的元素。所有 <strong>Markdown</strong><br>应用程序都支持这些元素。</p><table><thead><tr><th>元素</th><th>Markdown 语法</th></tr></thead><tbody><tr><td>标题（Heading）</td><td># H1 一级标题<br /> ## H2 二级标题<br /> ### H3 三级标题</td></tr><tr><td>粗体（Bold）</td><td>**bold text**</td></tr><tr><td>斜体（Italic）</td><td>*italicized text*</td></tr><tr><td>引用块（Blockquote）</td><td>&gt; blockquote</td></tr><tr><td>有序列表（Ordered List）</td><td>1. First item<br /> 2. Second item<br /> 3. Third item</td></tr><tr><td>无序列表（Unordered List）</td><td>- First item<br /> - Second item<br /> - Third item</td></tr><tr><td>代码（Code）</td><td><code>code</code></td></tr><tr><td>分隔线（Horizontal Rule）</td><td>---</td></tr><tr><td>链接（Link）</td><td>[title](<a href="https://www.example.com">https://www.example.com</a>)</td></tr><tr><td>图片（Image）</td><td>\![alt text](image.jpg)</td></tr></tbody></table><h2>扩展语法</h2><p>这些元素通过添加额外的功能扩展了基本语法。但是，并非所有 <strong>Markdown</strong><br>应用程序都支持这些元素。</p><table>
  <thead>
    <tr>
      <th>元素</th>
      <th>Markdown 语法</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>表格（Table）</td>
      <td>
        <code>| Syntax | Description |</code><br>
        <code>| ----------- | ----------- |</code><br>
        <code>| Header | Title |</code><br>
        <code>| Paragraph | Text |</code>
      </td>
    </tr>
    <tr>
      <td>代码块（Fenced Code Block）</td>
      <td>
        <code>```</code><br>
        <code>{</code><br>
        <code>"firstName": "John",</code><br>
        <code>"lastName": "Smith",</code><br>
        <code>"age": 25</code><br>
        <code>}</code><br>
        <code>```</code>
      </td>
    </tr>
    <tr>
      <td>脚注（Footnote）</td>
      <td>
        Here's a sentence with a footnote.<code>[^1]</code><br>
        <code>[^1]</code>: This is the footnote.
      </td>
    </tr>
    <tr>
      <td>标题编号（Heading ID）</td>
      <td><code>### My Great Heading{#custom-id}</code></td>
    </tr>
    <tr>
      <td>定义列表（Definition List）</td>
      <td>
        term<br>
        : definition
      </td>
    </tr>
    <tr>
      <td>任务列表（Task List）</td>
      <td>
        <code>- [x] Write the press release</code><br>
        <code>- [ ] Update the website</code><br>
        <code>- [ ] Contact the media</code>
      </td>
    </tr>
  </tbody>
</table>]]></description>
            <content:encoded><![CDATA[<p><!--markdown-->&gt; 原文位置: <a href="https://markdown.com.cn/cheat-sheet.html#%E6%80%BB%E8%A7%88">https://markdown.com.cn/cheat-sheet.html#%E6%80%BB%E8%A7%88</a></p><h1>总览</h1><p>Markdown 速查表提供了所有 <strong>Markdown</strong><br>语法元素的基本解释。如果你想了解某些语法元素的更多信息，请参阅更详细的<br><strong>基本语法</strong> 和 <strong>扩展语法</strong>.</p><h2>基本语法</h2><p>这些是 <strong>John Gruber</strong> 的原始设计文档中列出的元素。所有 <strong>Markdown</strong><br>应用程序都支持这些元素。</p><table><thead><tr><th>元素</th><th>Markdown 语法</th></tr></thead><tbody><tr><td>标题（Heading）</td><td># H1 一级标题<br /> ## H2 二级标题<br /> ### H3 三级标题</td></tr><tr><td>粗体（Bold）</td><td>**bold text**</td></tr><tr><td>斜体（Italic）</td><td>*italicized text*</td></tr><tr><td>引用块（Blockquote）</td><td>&gt; blockquote</td></tr><tr><td>有序列表（Ordered List）</td><td>1. First item<br /> 2. Second item<br /> 3. Third item</td></tr><tr><td>无序列表（Unordered List）</td><td>- First item<br /> - Second item<br /> - Third item</td></tr><tr><td>代码（Code）</td><td><code>code</code></td></tr><tr><td>分隔线（Horizontal Rule）</td><td>---</td></tr><tr><td>链接（Link）</td><td>[title](<a href="https://www.example.com">https://www.example.com</a>)</td></tr><tr><td>图片（Image）</td><td>\![alt text](image.jpg)</td></tr></tbody></table><h2>扩展语法</h2><p>这些元素通过添加额外的功能扩展了基本语法。但是，并非所有 <strong>Markdown</strong><br>应用程序都支持这些元素。</p><table>
  <thead>
    <tr>
      <th>元素</th>
      <th>Markdown 语法</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>表格（Table）</td>
      <td>
        <code>| Syntax | Description |</code><br>
        <code>| ----------- | ----------- |</code><br>
        <code>| Header | Title |</code><br>
        <code>| Paragraph | Text |</code>
      </td>
    </tr>
    <tr>
      <td>代码块（Fenced Code Block）</td>
      <td>
        <code>```</code><br>
        <code>{</code><br>
        <code>"firstName": "John",</code><br>
        <code>"lastName": "Smith",</code><br>
        <code>"age": 25</code><br>
        <code>}</code><br>
        <code>```</code>
      </td>
    </tr>
    <tr>
      <td>脚注（Footnote）</td>
      <td>
        Here's a sentence with a footnote.<code>[^1]</code><br>
        <code>[^1]</code>: This is the footnote.
      </td>
    </tr>
    <tr>
      <td>标题编号（Heading ID）</td>
      <td><code>### My Great Heading{#custom-id}</code></td>
    </tr>
    <tr>
      <td>定义列表（Definition List）</td>
      <td>
        term<br>
        : definition
      </td>
    </tr>
    <tr>
      <td>任务列表（Task List）</td>
      <td>
        <code>- [x] Write the press release</code><br>
        <code>- [ ] Update the website</code><br>
        <code>- [ ] Contact the media</code>
      </td>
    </tr>
  </tbody>
</table>]]></content:encoded>
        </item>
            </channel>
</rss>
        