<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>斑斓的博客</title>
  
  <subtitle>欢迎来到我的博客，希望你在这里能有收获</subtitle>
  <link href="http://hexo.banlan.nyc.mn/atom.xml" rel="self"/>
  
  <link href="http://hexo.banlan.nyc.mn/"/>
  <updated>2026-03-20T07:10:43.320Z</updated>
  <id>http://hexo.banlan.nyc.mn/</id>
  
  <author>
    <name>banlan</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>压缩wsl发行版/docker的文件大小</title>
    <link href="http://hexo.banlan.nyc.mn/posts/61159d4a.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/61159d4a.html</id>
    <published>2026-03-20T07:04:53.000Z</published>
    <updated>2026-03-20T07:10:43.320Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><hr><h3 id="1-确保-Docker-和-WSL-已完全关闭"><a href="#1-确保-Docker-和-WSL-已完全关闭" class="headerlink" title="1. 确保 Docker 和 WSL 已完全关闭"></a>1. 确保 Docker 和 WSL 已完全关闭</h3><ul><li>右键系统托盘区的 Docker 图标，选择 <strong>Quit Docker Desktop</strong>。</li><li>在 <strong>管理员权限的 PowerShell</strong> 中执行：<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wsl <span class="literal">--shutdown</span></span><br></pre></td></tr></table></figure></li></ul><h3 id="2-启动-diskpart-并执行压缩"><a href="#2-启动-diskpart-并执行压缩" class="headerlink" title="2. 启动 diskpart 并执行压缩"></a>2. 启动 diskpart 并执行压缩</h3><p>在同一个管理员 PowerShell 窗口中，依次执行：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 进入 diskpart 工具</span></span><br><span class="line">diskpart</span><br></pre></td></tr></table></figure><p>此时命令行提示符会变成 <code>DISKPART&gt;</code>，然后逐条输入以下命令（每输完一行按回车）：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">select vdisk file=&quot;D:\Download\Docker_images\DockerDesktopWSL\disk\docker_data.vhdx&quot;</span><br><span class="line">attach vdisk readonly</span><br><span class="line">compact vdisk</span><br><span class="line">detach vdisk</span><br><span class="line">exit</span><br></pre></td></tr></table></figure><ul><li>如果路径中包含空格或特殊字符，请确保用双引号括起来。</li><li><code>attach vdisk readonly</code> 会以只读方式挂载虚拟磁盘，确保压缩时不破坏数据。</li><li><code>compact vdisk</code> 执行压缩，可能需要几分钟时间，请耐心等待。</li><li>完成后 <code>detach vdisk</code> 卸载虚拟磁盘，<code>exit</code> 退出 diskpart。</li></ul><h3 id="3-验证压缩效果"><a href="#3-验证压缩效果" class="headerlink" title="3. 验证压缩效果"></a>3. 验证压缩效果</h3><p>压缩完成后，可以查看 <code>docker_data.vhdx</code> 文件大小是否明显减小。然后重新启动 Docker Desktop，一切功能正常，所有镜像和容器都不会丢失。</p><hr>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>针对DO200$无法ssh连接的办法</title>
    <link href="http://hexo.banlan.nyc.mn/posts/74b9fa61.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/74b9fa61.html</id>
    <published>2025-09-21T13:26:04.000Z</published>
    <updated>2025-09-21T13:50:30.424Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>DigitalOcean的学生包机器通常无法在国内ssh连接，显示closed by foreign host。而官网处的console也进不去，只能通过acess里面的recovery那个终端来使用，但那个终端不是很稳定，故需要其他解决办法。</p><h2 id="解决办法"><a href="#解决办法" class="headerlink" title="解决办法"></a>解决办法</h2><h3 id="方法1-使用1Panel面板进行管理"><a href="#方法1-使用1Panel面板进行管理" class="headerlink" title="方法1.使用1Panel面板进行管理"></a>方法1.使用1Panel面板进行管理</h3><p>运行安装脚本：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash -c &quot;$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)&quot;</span><br></pre></td></tr></table></figure><p>安装完成后根据默认的ip:port访问面板，使用账号密码进入即可<br><a href="https://1panel.cn/">1Panel官网</a></p><h3 id="方法2-添加代理服务器"><a href="#方法2-添加代理服务器" class="headerlink" title="方法2.添加代理服务器"></a>方法2.添加代理服务器</h3><p>使用finalshell的，可以添加代理服务器，有可能行。如果不行，使用TUN模式。</p><h3 id="方法3-方法2不行的情况"><a href="#方法3-方法2不行的情况" class="headerlink" title="方法3.方法2不行的情况"></a>方法3.方法2不行的情况</h3><p>按照方法2也无法连接的话，大概率是TUN模式禁止22端口，可修改22端口为其他的高位端口。</p><ul><li>编辑&#x2F;etc&#x2F;ssh&#x2F;sshd_config</li><li>找到Port 22的配置，默认是被注释了的，打开注释（删除#），然后在下面新增一行：Port 2222（你自己想设置的端口号）</li><li>重启sshd服务：<code>systemctl restart sshd</code>或者<code>service sshd restart</code></li><li>防火墙开放该端口<br>如果是ufw的：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ufw allow 2222</span><br><span class="line">ufw reload</span><br></pre></td></tr></table></figure>如果是firewalld的：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --zone=public --add-port=2222/tcp --permanent</span><br><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure>去比如finalshell里面测试能够连接的话，回来把Port 22的配置注释掉，然后重启sshd服务。如果不行，再换个端口。</li></ul><hr><p><img src="https://b2images.490996.xyz/file/1758461318314_image.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="网络知识" scheme="http://hexo.banlan.nyc.mn/categories/%E7%BD%91%E7%BB%9C%E7%9F%A5%E8%AF%86/"/>
    
    
    <category term="VPS" scheme="http://hexo.banlan.nyc.mn/tags/VPS/"/>
    
  </entry>
  
  <entry>
    <title>解决Windows的打开方式列表里残留有卸载程序的注册信息</title>
    <link href="http://hexo.banlan.nyc.mn/posts/1245406f.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/1245406f.html</id>
    <published>2025-08-21T00:28:48.000Z</published>
    <updated>2025-08-21T00:34:49.601Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><p><img src="https://linux.do/uploads/default/original/4X/e/4/a/e4a01604d49df7478e3bb63bf5bf1444df137e48.jpeg"><br>如图所示，有时候弹出“打开方式”的时候，会出现一些没有图标的程序，要么是被卸载的程序，要么是软件更新后残留的旧程序文件，去除方法：</p><h4 id="清理注册表残留"><a href="#清理注册表残留" class="headerlink" title="清理注册表残留"></a>清理注册表残留</h4><p>1.win+R 输入<code>regedit</code>打开注册表<br>2.定位到以下路径</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">计算机\HKEY_CLASSES_ROOT\Applications</span><br></pre></td></tr></table></figure><p>找到要删除的程序exe子项，比如图中所示的<code>Happ.exe</code><br>还可检查（针对.webp的）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.webp\OpenWithList</span><br><span class="line">HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.webp\OpenWithProgids</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="常用技巧" scheme="http://hexo.banlan.nyc.mn/categories/%E5%B8%B8%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
    <category term="Windows" scheme="http://hexo.banlan.nyc.mn/tags/Windows/"/>
    
  </entry>
  
  <entry>
    <title>serv00部署gpt-load &amp;&amp; Passenger进程保活</title>
    <link href="http://hexo.banlan.nyc.mn/posts/b1012466.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/b1012466.html</id>
    <published>2025-08-18T11:24:33.000Z</published>
    <updated>2026-02-02T04:40:39.516Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h3 id="0-前提，部署到make-run那一步，还未进行pm2保活"><a href="#0-前提，部署到make-run那一步，还未进行pm2保活" class="headerlink" title="0.前提，部署到make run那一步，还未进行pm2保活"></a>0.前提，部署到<code>make run</code>那一步，还未进行pm2保活</h3><p><a href="https://linux.do/t/topic/835935">https://linux.do/t/topic/835935</a></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/tbphp/gpt-load.git</span><br><span class="line">cd gpt-load</span><br><span class="line">go mod tidy</span><br><span class="line"># 创建配置</span><br><span class="line">cp .env.example .env</span><br><span class="line"># 登陆serv00开放端口</span><br><span class="line">make run</span><br><span class="line"># 会打印出启动成功日志</span><br><span class="line"></span><br><span class="line">pm2保活（可选）</span><br><span class="line">go build -o gpt-load-server .</span><br><span class="line">pm2 start ./gpt-load-server --name gpt-load</span><br></pre></td></tr></table></figure><h3 id="1-开始，参考下面讲的passenger保活进程，"><a href="#1-开始，参考下面讲的passenger保活进程，" class="headerlink" title="1.开始，参考下面讲的passenger保活进程，"></a>1.开始，参考下面讲的passenger保活进程，</h3><p><a href="https://github.com/hkfires/Keep-Serv00-Alive">https://github.com/hkfires/Keep-Serv00-Alive</a></p><h3 id="2-app-js代码："><a href="#2-app-js代码：" class="headerlink" title="2.app.js代码："></a>2.<code>app.js</code>代码：</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line">const express = require(&quot;express&quot;);</span><br><span class="line">const &#123; exec &#125; = require(&quot;child_process&quot;);</span><br><span class="line">const fs = require(&quot;fs&quot;);</span><br><span class="line">const path = require(&quot;path&quot;);</span><br><span class="line">const app = express();</span><br><span class="line"></span><br><span class="line">// ================== 配置区域 ==================</span><br><span class="line">const port = process.env.PORT || 3000;</span><br><span class="line">const USER = &quot;username&quot;;</span><br><span class="line">const TARGET_PORT = &quot;30345&quot;;</span><br><span class="line">const WORK_DIR = `/home/$&#123;USER&#125;/gpt-load`;</span><br><span class="line">const CMD = `./gpt-load-server`;</span><br><span class="line">const PROCESS_NAME = &quot;gpt-load-server&quot;;</span><br><span class="line"></span><br><span class="line">// 日志文件路径 (在 public_nodejs 目录下)</span><br><span class="line">const LOG_FILE = path.join(__dirname, &#x27;keeper.log&#x27;);</span><br><span class="line"></span><br><span class="line">// 🛑 新增：暂停开关文件路径 (只要这个文件存在，脚本就不干活)</span><br><span class="line">const STOP_FILE = path.join(__dirname, &#x27;stop.txt&#x27;);</span><br><span class="line">// ============================================</span><br><span class="line"></span><br><span class="line">// 自定义日志函数：同时输出到控制台和文件</span><br><span class="line">function log(message) &#123;</span><br><span class="line">    const time = new Date().toLocaleString();</span><br><span class="line">    const logMsg = `[$&#123;time&#125;] $&#123;message&#125;\n`;</span><br><span class="line">    </span><br><span class="line">    // 1. 尝试写入文件</span><br><span class="line">    try &#123;</span><br><span class="line">        fs.appendFileSync(LOG_FILE, logMsg);</span><br><span class="line">    &#125; catch (e) &#123;</span><br><span class="line">        // 如果写文件失败，至少打印到 stderr</span><br><span class="line">        console.error(`Log write error: $&#123;e.message&#125;`);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    // 2. 输出到控制台 (保留标准输出)</span><br><span class="line">    console.log(logMsg.trim());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function keepAlive() &#123;</span><br><span class="line">    // ============================================================</span><br><span class="line">    // 🛑 新增：维护模式检测</span><br><span class="line">    // 如果目录下存在 stop.txt，直接跳过后续所有检查</span><br><span class="line">    if (fs.existsSync(STOP_FILE)) &#123;</span><br><span class="line">        // 为了防止日志刷屏，这里可以选择不打印，或者每次跳过时打印</span><br><span class="line">        // 这里设置为每次周期都记录一下，方便确认状态</span><br><span class="line">        log(&quot;🛑 Maintenance Mode Active (stop.txt found). Skipping checks.&quot;);</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line">    // ============================================================</span><br><span class="line"></span><br><span class="line">    // 1. 核心检测：查端口 (保持原有逻辑)</span><br><span class="line">    exec(`sockstat -4 -l -P tcp | grep $&#123;TARGET_PORT&#125;`, (err, stdout) =&gt; &#123;</span><br><span class="line">        if (stdout &amp;&amp; stdout.includes(TARGET_PORT)) &#123;</span><br><span class="line">            log(`Port $&#123;TARGET_PORT&#125; is UP. Service is healthy.`);</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">            log(`Port $&#123;TARGET_PORT&#125; is DOWN. Initiating restart sequence...`);</span><br><span class="line">            </span><br><span class="line">            // 2. 清理旧进程</span><br><span class="line">            log(`Cleaning up any stuck &#x27;$&#123;PROCESS_NAME&#125;&#x27; processes...`);</span><br><span class="line">            exec(`pkill -f &quot;$&#123;PROCESS_NAME&#125;&quot;`, () =&gt; &#123;</span><br><span class="line">                </span><br><span class="line">                // 3. 启动新进程</span><br><span class="line">                log(`Starting new instance...`);</span><br><span class="line">                // 注意：gpt-load 自身的日志依然写到它自己的 gpt-load.log 里</span><br><span class="line">                exec(`cd $&#123;WORK_DIR&#125; &amp;&amp; $&#123;CMD&#125; &gt; gpt-load.log 2&gt;&amp;1 &amp;`, (startErr) =&gt; &#123;</span><br><span class="line">                    if (startErr) log(`Start failed: $&#123;startErr&#125;`);</span><br><span class="line">                    else log(`Start command sent successfully.`);</span><br><span class="line">                &#125;);</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 启动时立即检查</span><br><span class="line">log(&quot;Keeper Service Started.&quot;);</span><br><span class="line">keepAlive();</span><br><span class="line"></span><br><span class="line">// 每 60 秒检查一次</span><br><span class="line">setInterval(keepAlive, 60 * 1000);</span><br><span class="line"></span><br><span class="line">// 修改：Web 访问时也能看到状态</span><br><span class="line">app.get(&quot;/&quot;, (req, res) =&gt; &#123;</span><br><span class="line">    if (fs.existsSync(STOP_FILE)) &#123;</span><br><span class="line">        res.send(&quot;🛑 Service is in MAINTENANCE MODE (stop.txt detected).&quot;);</span><br><span class="line">    &#125; else &#123;</span><br><span class="line">        res.send(`✅ Keeper is watching port $&#123;TARGET_PORT&#125;`);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.listen(port, () =&gt; log(`Keeper listening on port $&#123;port&#125;`));</span><br></pre></td></tr></table></figure><p>部分网路节点存在<strong>非标准端口阻断</strong>的问题，导致访问502<br>新的app.js，转发端口，来实现纯域名访问</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line">const express = require(&quot;express&quot;);</span><br><span class="line">const &#123; exec &#125; = require(&quot;child_process&quot;);</span><br><span class="line">const fs = require(&quot;fs&quot;);</span><br><span class="line">const path = require(&quot;path&quot;);</span><br><span class="line">const &#123; createProxyMiddleware &#125; = require(&quot;http-proxy-middleware&quot;); // 引入代理插件</span><br><span class="line">const app = express();</span><br><span class="line"></span><br><span class="line">// ================== 配置区域 ==================</span><br><span class="line">const port = process.env.PORT || 3000;</span><br><span class="line">const USER = &quot;username&quot;;</span><br><span class="line">const TARGET_PORT = &quot;30345&quot;;</span><br><span class="line">const WORK_DIR = `/home/$&#123;USER&#125;/gpt-load`;</span><br><span class="line">const CMD = `./gpt-load-server`;</span><br><span class="line">const PROCESS_NAME = &quot;gpt-load-server&quot;;</span><br><span class="line"></span><br><span class="line">// 日志文件</span><br><span class="line">const LOG_FILE = path.join(__dirname, &#x27;keeper.log&#x27;);</span><br><span class="line">// 暂停开关</span><br><span class="line">const STOP_FILE = path.join(__dirname, &#x27;stop.txt&#x27;);</span><br><span class="line">// ============================================</span><br><span class="line"></span><br><span class="line">function log(message) &#123;</span><br><span class="line">    const time = new Date().toLocaleString();</span><br><span class="line">    const logMsg = `[$&#123;time&#125;] $&#123;message&#125;\n`;</span><br><span class="line">    try &#123; fs.appendFileSync(LOG_FILE, logMsg); &#125; catch (e) &#123;&#125;</span><br><span class="line">    console.log(logMsg.trim());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function keepAlive() &#123;</span><br><span class="line">    if (fs.existsSync(STOP_FILE)) &#123;</span><br><span class="line">        log(&quot;🛑 Maintenance Mode Active (stop.txt found). Skipping checks.&quot;);</span><br><span class="line">        return; </span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    exec(`sockstat -4 -l -P tcp | grep $&#123;TARGET_PORT&#125;`, (err, stdout) =&gt; &#123;</span><br><span class="line">        if (stdout &amp;&amp; stdout.includes(TARGET_PORT)) &#123;</span><br><span class="line">            log(`Port $&#123;TARGET_PORT&#125; is UP. Service is healthy.`);</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">            log(`Port $&#123;TARGET_PORT&#125; is DOWN. Initiating restart sequence...`);</span><br><span class="line">            log(`Cleaning up any stuck &#x27;$&#123;PROCESS_NAME&#125;&#x27; processes...`);</span><br><span class="line">            exec(`pkill -f &quot;$&#123;PROCESS_NAME&#125;&quot;`, () =&gt; &#123;</span><br><span class="line">                log(`Starting new instance...`);</span><br><span class="line">                exec(`cd $&#123;WORK_DIR&#125; &amp;&amp; $&#123;CMD&#125; &gt; gpt-load.log 2&gt;&amp;1 &amp;`, (startErr) =&gt; &#123;</span><br><span class="line">                    if (startErr) log(`Start failed: $&#123;startErr&#125;`);</span><br><span class="line">                    else log(`Start command sent successfully.`);</span><br><span class="line">                &#125;);</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 启动保活逻辑</span><br><span class="line">log(&quot;Keeper Service Started.&quot;);</span><br><span class="line">keepAlive();</span><br><span class="line">setInterval(keepAlive, 60 * 1000);</span><br><span class="line"></span><br><span class="line">// ================== 路由配置 ==================</span><br><span class="line"></span><br><span class="line">// 1. 特殊页面：查看保活状态 (访问 /keeper-status)</span><br><span class="line">app.get(&quot;/keeper-status&quot;, (req, res) =&gt; &#123;</span><br><span class="line">    if (fs.existsSync(STOP_FILE)) &#123;</span><br><span class="line">        res.send(&quot;🛑 Service is in MAINTENANCE MODE (stop.txt detected).&quot;);</span><br><span class="line">    &#125; else &#123;</span><br><span class="line">        res.send(`✅ Keeper is watching port $&#123;TARGET_PORT&#125;. Service acts as Reverse Proxy.`);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">// 2. 反向代理：把所有其他请求转发给 gpt-load (30345)</span><br><span class="line">// 这样你直接访问域名，就等于访问了 30345，但不用担心代理节点屏蔽端口</span><br><span class="line">app.use(&quot;/&quot;, createProxyMiddleware(&#123;</span><br><span class="line">    target: `http://127.0.0.1:$&#123;TARGET_PORT&#125;`,</span><br><span class="line">    changeOrigin: true,</span><br><span class="line">    ws: true, // 支持 WebSocket (如果 gpt-load 需要)</span><br><span class="line">    onError: (err, req, res) =&gt; &#123;</span><br><span class="line">        res.status(502).send(`</span><br><span class="line">            &lt;h1&gt;502 Bad Gateway&lt;/h1&gt;</span><br><span class="line">            &lt;p&gt;Keeper is running, but gpt-load-server (Port $&#123;TARGET_PORT&#125;) seems down or starting.&lt;/p&gt;</span><br><span class="line">            &lt;p&gt;Check &lt;a href=&quot;/keeper-status&quot;&gt;/keeper-status&lt;/a&gt; for details.&lt;/p&gt;</span><br><span class="line">        `);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;));</span><br><span class="line"></span><br><span class="line">app.listen(port, () =&gt; log(`Keeper &amp; Proxy listening on port $&#123;port&#125;`));</span><br></pre></td></tr></table></figure><p>显示keeper.log版本</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br></pre></td><td class="code"><pre><span class="line">const express = require(&quot;express&quot;);</span><br><span class="line">const &#123; exec &#125; = require(&quot;child_process&quot;);</span><br><span class="line">const fs = require(&quot;fs&quot;);</span><br><span class="line">const path = require(&quot;path&quot;);</span><br><span class="line">const os = require(&quot;os&quot;);</span><br><span class="line">const &#123; createProxyMiddleware &#125; = require(&quot;http-proxy-middleware&quot;); // 引入代理插件</span><br><span class="line">const app = express();</span><br><span class="line"></span><br><span class="line">// ================== 配置区域 ==================</span><br><span class="line">const port = process.env.PORT || 3000;</span><br><span class="line">const USER = &quot;username&quot;;</span><br><span class="line">const TARGET_PORT = &quot;30345&quot;;</span><br><span class="line">const WORK_DIR = `/home/$&#123;USER&#125;/gpt-load`;</span><br><span class="line">const CMD = `./gpt-load-server`;</span><br><span class="line">const PROCESS_NAME = &quot;gpt-load-server&quot;;</span><br><span class="line"></span><br><span class="line">// 系统资源配额（根据您的实际环境配置）</span><br><span class="line">const RESOURCE_QUOTAS = &#123;</span><br><span class="line">    disk: &#123;</span><br><span class="line">        total: 3.00 * 1024 * 1024 * 1024, // 3GB in bytes</span><br><span class="line">        unit: &#x27;GB&#x27;</span><br><span class="line">    &#125;,</span><br><span class="line">    processes: &#123;</span><br><span class="line">        max: 20</span><br><span class="line">    &#125;,</span><br><span class="line">    memory: &#123;</span><br><span class="line">        total: 512, // MB</span><br><span class="line">        unit: &#x27;MB&#x27;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">// 日志文件</span><br><span class="line">const LOG_FILE = path.join(__dirname, &#x27;keeper.log&#x27;);</span><br><span class="line">// 暂停开关</span><br><span class="line">const STOP_FILE = path.join(__dirname, &#x27;stop.txt&#x27;);</span><br><span class="line">// ============================================</span><br><span class="line"></span><br><span class="line">function log(message) &#123;</span><br><span class="line">    const time = new Date().toLocaleString();</span><br><span class="line">    const logMsg = `[$&#123;time&#125;] $&#123;message&#125;\n`;</span><br><span class="line">    try &#123; fs.appendFileSync(LOG_FILE, logMsg); &#125; catch (e) &#123;&#125;</span><br><span class="line">    console.log(logMsg.trim());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 缓存系统信息以减少重复计算</span><br><span class="line">let systemInfoCache = null;</span><br><span class="line">let lastSystemInfoTime = 0;</span><br><span class="line">const CACHE_DURATION = 30000; // 30秒缓存</span><br><span class="line"></span><br><span class="line">// 获取系统资源信息（适用于 serv00 容器环境）</span><br><span class="line">function getSystemInfo() &#123;</span><br><span class="line">    const now = Date.now();</span><br><span class="line"></span><br><span class="line">    // 如果缓存有效，直接返回</span><br><span class="line">    if (systemInfoCache &amp;&amp; (now - lastSystemInfoTime) &lt; CACHE_DURATION) &#123;</span><br><span class="line">        return systemInfoCache;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    try &#123;</span><br><span class="line">        // 获取配置的总内存配额</span><br><span class="line">        const quotaTotal = RESOURCE_QUOTAS.memory.total * 1024 * 1024; // 转换为字节</span><br><span class="line">        let actualUsed = 0;</span><br><span class="line">        let detectionMethod = &#x27;估算&#x27;;</span><br><span class="line"></span><br><span class="line">        // 方法1: 尝试通过 ps 命令获取当前用户所有进程的内存总和（FreeBSD）</span><br><span class="line">        // RSS 字段表示常驻内存大小</span><br><span class="line">        exec(`ps -U $&#123;process.env.USER || USER&#125; -o rss= 2&gt;/dev/null | awk &#x27;&#123;s+=$1&#125; END &#123;print s&#125;&#x27;`, (err, stdout) =&gt; &#123;</span><br><span class="line">            if (!err &amp;&amp; stdout &amp;&amp; !isNaN(parseFloat(stdout))) &#123;</span><br><span class="line">                // ps 返回的是 KB，转换为字节</span><br><span class="line">                const psMem = parseFloat(stdout.trim()) * 1024;</span><br><span class="line">                if (psMem &gt; 0) &#123;</span><br><span class="line">                    actualUsed = psMem;</span><br><span class="line">                    detectionMethod = &#x27;ps 进程汇总&#x27;;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            // 如果 ps 方法失败，回退到当前进程 + 预估</span><br><span class="line">            if (actualUsed === 0) &#123;</span><br><span class="line">                const processMem = process.memoryUsage();</span><br><span class="line">                actualUsed = processMem.rss;</span><br><span class="line">                detectionMethod = &#x27;当前进程估算&#x27;;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            // 转换为 MB</span><br><span class="line">            const usedMemMB = actualUsed / 1024 / 1024;</span><br><span class="line">            const totalMemMB = quotaTotal / 1024 / 1024;</span><br><span class="line">            const freeMemMB = Math.max(0, totalMemMB - usedMemMB);</span><br><span class="line">            const usagePercent = ((usedMemMB / totalMemMB) * 100).toFixed(1);</span><br><span class="line"></span><br><span class="line">            const sysInfo = &#123;</span><br><span class="line">                timestamp: new Date().toLocaleString(),</span><br><span class="line">                memory: &#123;</span><br><span class="line">                    total: totalMemMB.toFixed(1) + &#x27; MB&#x27;,</span><br><span class="line">                    used: usedMemMB.toFixed(1) + &#x27; MB&#x27;,</span><br><span class="line">                    free: freeMemMB.toFixed(1) + &#x27; MB&#x27;,</span><br><span class="line">                    quotaUsagePercent: usagePercent + &#x27;%&#x27;,</span><br><span class="line">                    quota: `$&#123;usedMemMB.toFixed(1)&#125;/$&#123;RESOURCE_QUOTAS.memory.total&#125; $&#123;RESOURCE_QUOTAS.memory.unit&#125; ($&#123;detectionMethod&#125;)`</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;;</span><br><span class="line"></span><br><span class="line">            // 更新缓存</span><br><span class="line">            systemInfoCache = sysInfo;</span><br><span class="line">            lastSystemInfoTime = now;</span><br><span class="line"></span><br><span class="line">            return sysInfo;</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        // 同步返回（首次调用可能为空）</span><br><span class="line">        const processMem = process.memoryUsage();</span><br><span class="line">        actualUsed = processMem.rss * 2; // 临时估算，下次缓存会有准确值</span><br><span class="line"></span><br><span class="line">        const usedMemMB = actualUsed / 1024 / 1024;</span><br><span class="line">        const totalMemMB = quotaTotal / 1024 / 1024;</span><br><span class="line">        const usagePercent = ((usedMemMB / totalMemMB) * 100).toFixed(1);</span><br><span class="line"></span><br><span class="line">        const sysInfo = &#123;</span><br><span class="line">            timestamp: new Date().toLocaleString(),</span><br><span class="line">            memory: &#123;</span><br><span class="line">                total: totalMemMB.toFixed(1) + &#x27; MB&#x27;,</span><br><span class="line">                used: usedMemMB.toFixed(1) + &#x27; MB&#x27;,</span><br><span class="line">                free: (totalMemMB - usedMemMB).toFixed(1) + &#x27; MB&#x27;,</span><br><span class="line">                quotaUsagePercent: usagePercent + &#x27;%&#x27;,</span><br><span class="line">                quota: `$&#123;usedMemMB.toFixed(1)&#125;/$&#123;RESOURCE_QUOTAS.memory.total&#125; $&#123;RESOURCE_QUOTAS.memory.unit&#125; (初始化中...)`</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        systemInfoCache = sysInfo;</span><br><span class="line">        lastSystemInfoTime = now;</span><br><span class="line"></span><br><span class="line">        return sysInfo;</span><br><span class="line">    &#125; catch (error) &#123;</span><br><span class="line">        return &#123;</span><br><span class="line">            error: &#x27;Memory detection failed: &#x27; + error.message,</span><br><span class="line">            timestamp: new Date().toLocaleString()</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 读取最近的 keeper.log 内容（限制行数以节省资源）</span><br><span class="line">function getRecentLogs(maxLines = 50) &#123;</span><br><span class="line">    try &#123;</span><br><span class="line">        if (!fs.existsSync(LOG_FILE)) &#123;</span><br><span class="line">            return [&#x27;Log file not found&#x27;];</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        const content = fs.readFileSync(LOG_FILE, &#x27;utf8&#x27;);</span><br><span class="line">        const lines = content.split(&#x27;\n&#x27;).filter(line =&gt; line.trim() !== &#x27;&#x27;);</span><br><span class="line">        // 返回最后 maxLines 行</span><br><span class="line">        return lines.slice(-maxLines);</span><br><span class="line">    &#125; catch (error) &#123;</span><br><span class="line">        return [`Error reading log: $&#123;error.message&#125;`];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function keepAlive() &#123;</span><br><span class="line">    if (fs.existsSync(STOP_FILE)) &#123;</span><br><span class="line">        log(&quot;🛑 Maintenance Mode Active (stop.txt found). Skipping checks.&quot;);</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    exec(`sockstat -4 -l -P tcp | grep $&#123;TARGET_PORT&#125;`, (err, stdout) =&gt; &#123;</span><br><span class="line">        if (stdout &amp;&amp; stdout.includes(TARGET_PORT)) &#123;</span><br><span class="line">            log(`Port $&#123;TARGET_PORT&#125; is UP. Service is healthy.`);</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">            log(`Port $&#123;TARGET_PORT&#125; is DOWN. Initiating restart sequence...`);</span><br><span class="line">            log(`Cleaning up any stuck &#x27;$&#123;PROCESS_NAME&#125;&#x27; processes...`);</span><br><span class="line">            exec(`pkill -f &quot;$&#123;PROCESS_NAME&#125;&quot;`, () =&gt; &#123;</span><br><span class="line">                log(`Starting new instance...`);</span><br><span class="line">                exec(`cd $&#123;WORK_DIR&#125; &amp;&amp; $&#123;CMD&#125; &gt; gpt-load.log 2&gt;&amp;1 &amp;`, (startErr) =&gt; &#123;</span><br><span class="line">                    if (startErr) log(`Start failed: $&#123;startErr&#125;`);</span><br><span class="line">                    else log(`Start command sent successfully.`);</span><br><span class="line">                &#125;);</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 启动保活逻辑</span><br><span class="line">log(&quot;Keeper Service Started.&quot;);</span><br><span class="line">keepAlive();</span><br><span class="line">setInterval(keepAlive, 60 * 1000);</span><br><span class="line"></span><br><span class="line">// ================== 路由配置 ==================</span><br><span class="line"></span><br><span class="line">// 1. 特殊页面：查看保活状态 (访问 /keeper-status)</span><br><span class="line">app.get(&quot;/keeper-status&quot;, (req, res) =&gt; &#123;</span><br><span class="line">    const sysInfo = getSystemInfo();</span><br><span class="line">    const logs = getRecentLogs(30); // 显示最近30行日志</span><br><span class="line">    </span><br><span class="line">    let html = `</span><br><span class="line">    &lt;!DOCTYPE html&gt;</span><br><span class="line">    &lt;html&gt;</span><br><span class="line">    &lt;head&gt;</span><br><span class="line">        &lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;</span><br><span class="line">        &lt;title&gt;Keeper Status Dashboard&lt;/title&gt;</span><br><span class="line">        &lt;style&gt;</span><br><span class="line">            body &#123; font-family: Arial, sans-serif; margin: 20px; background-color: #f5f5f5; &#125;</span><br><span class="line">            .container &#123; max-width: 1200px; margin: 0 auto; &#125;</span><br><span class="line">            .card &#123; background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); &#125;</span><br><span class="line">            .status-header &#123; text-align: center; color: #333; &#125;</span><br><span class="line">            .status-indicator &#123;</span><br><span class="line">                display: inline-block;</span><br><span class="line">                padding: 10px 20px;</span><br><span class="line">                border-radius: 20px;</span><br><span class="line">                font-weight: bold;</span><br><span class="line">                margin: 10px 0;</span><br><span class="line">            &#125;</span><br><span class="line">            .status-active &#123; background-color: #d4edda; color: #155724; &#125;</span><br><span class="line">            .status-maintenance &#123; background-color: #fff3cd; color: #856404; &#125;</span><br><span class="line">            .grid &#123; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; &#125;</span><br><span class="line">            .resource-card &#123; background: #f8f9fa; border-left: 4px solid #007bff; &#125;</span><br><span class="line">            .log-container &#123; background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 5px; font-family: &#x27;Courier New&#x27;, monospace; font-size: 12px; max-height: 400px; overflow-y: auto; &#125;</span><br><span class="line">            .log-entry &#123; margin: 2px 0; &#125;</span><br><span class="line">            .log-error &#123; color: #ff6b6b; &#125;</span><br><span class="line">            .log-success &#123; color: #51cf66; &#125;</span><br><span class="line">            .log-warning &#123; color: #ffd43b; &#125;</span><br><span class="line">            .refresh-btn &#123;</span><br><span class="line">                background: #007bff;</span><br><span class="line">                color: white;</span><br><span class="line">                border: none;</span><br><span class="line">                padding: 10px 20px;</span><br><span class="line">                border-radius: 5px;</span><br><span class="line">                cursor: pointer;</span><br><span class="line">                margin: 10px 5px;</span><br><span class="line">            &#125;</span><br><span class="line">            .refresh-btn:hover &#123; background: #0056b3; &#125;</span><br><span class="line">            h2 &#123; color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; &#125;</span><br><span class="line">            .metric &#123; margin: 10px 0; &#125;</span><br><span class="line">            .metric-label &#123; font-weight: bold; color: #555; &#125;</span><br><span class="line">            .metric-value &#123; color: #007bff; font-family: &#x27;Courier New&#x27;, monospace; &#125;</span><br><span class="line">            .quota-info &#123; font-size: 12px; color: #666; margin-top: 5px; &#125;</span><br><span class="line">            .usage-bar &#123;</span><br><span class="line">                height: 8px;</span><br><span class="line">                background-color: #e9ecef;</span><br><span class="line">                border-radius: 4px;</span><br><span class="line">                margin: 8px 0;</span><br><span class="line">                overflow: hidden;</span><br><span class="line">            &#125;</span><br><span class="line">            .usage-fill &#123;</span><br><span class="line">                height: 100%;</span><br><span class="line">                background-color: #28a745;</span><br><span class="line">                transition: width 0.3s ease;</span><br><span class="line">            &#125;</span><br><span class="line">            .usage-warning &#123; background-color: #ffc107; &#125;</span><br><span class="line">            .usage-danger &#123; background-color: #dc3545; &#125;</span><br><span class="line">        &lt;/style&gt;</span><br><span class="line">    &lt;/head&gt;</span><br><span class="line">    &lt;body&gt;</span><br><span class="line">        &lt;div class=&quot;container&quot;&gt;</span><br><span class="line">            &lt;div class=&quot;card&quot;&gt;</span><br><span class="line">                &lt;h1 class=&quot;status-header&quot;&gt;keeper Status Dashboard&lt;/h1&gt;</span><br><span class="line">                &lt;div class=&quot;status-indicator $&#123;fs.existsSync(STOP_FILE) ? &#x27;status-maintenance&#x27; : &#x27;status-active&#x27;&#125;&quot;&gt;</span><br><span class="line">                    $&#123;fs.existsSync(STOP_FILE) ? &#x27;🛑 MAINTENANCE MODE&#x27; : &#x27;✅ ACTIVE MODE&#x27;&#125;</span><br><span class="line">                &lt;/div&gt;</span><br><span class="line">                &lt;p&gt;Monitoring port: &lt;strong&gt;$&#123;TARGET_PORT&#125;&lt;/strong&gt;&lt;/p&gt;</span><br><span class="line">                &lt;p&gt;Last updated: &lt;strong&gt;$&#123;sysInfo.timestamp&#125;&lt;/strong&gt;&lt;/p&gt;</span><br><span class="line">                &lt;button class=&quot;refresh-btn&quot; onclick=&quot;location.reload()&quot;&gt;Refresh Status&lt;/button&gt;</span><br><span class="line">                &lt;button class=&quot;refresh-btn&quot; onclick=&quot;window.location.href=&#x27;/&#x27;&quot;&gt;Go to Main Site&lt;/button&gt;</span><br><span class="line">            &lt;/div&gt;</span><br><span class="line">    `;</span><br><span class="line"></span><br><span class="line">    // 系统资源信息（仅显示内存）</span><br><span class="line">    if (!sysInfo.error) &#123;</span><br><span class="line">        html += `</span><br><span class="line">            &lt;div class=&quot;grid&quot;&gt;</span><br><span class="line">                &lt;div class=&quot;card resource-card&quot;&gt;</span><br><span class="line">                    &lt;h2&gt;💾 Memory Information&lt;/h2&gt;</span><br><span class="line">                    &lt;div class=&quot;metric&quot;&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-label&quot;&gt;Total Memory:&lt;/span&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-value&quot;&gt;$&#123;sysInfo.memory.total&#125;&lt;/span&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;div class=&quot;metric&quot;&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-label&quot;&gt;Used Memory:&lt;/span&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-value&quot;&gt;$&#123;sysInfo.memory.used&#125;&lt;/span&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;div class=&quot;metric&quot;&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-label&quot;&gt;Free Memory:&lt;/span&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-value&quot;&gt;$&#123;sysInfo.memory.free&#125;&lt;/span&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;div class=&quot;metric&quot;&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-label&quot;&gt;Quota Usage:&lt;/span&gt;</span><br><span class="line">                        &lt;span class=&quot;metric-value&quot;&gt;$&#123;sysInfo.memory.quotaUsagePercent&#125;&lt;/span&gt;</span><br><span class="line">                        &lt;div class=&quot;quota-info&quot;&gt;Quota: $&#123;sysInfo.memory.quota&#125;&lt;/div&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;div class=&quot;usage-bar&quot;&gt;</span><br><span class="line">                        &lt;div class=&quot;usage-fill $&#123;parseFloat(sysInfo.memory.quotaUsagePercent) &gt; 80 ? &#x27;usage-warning&#x27; : parseFloat(sysInfo.memory.quotaUsagePercent) &gt; 90 ? &#x27;usage-danger&#x27; : &#x27;&#x27;&#125;&quot; </span><br><span class="line">                             style=&quot;width: $&#123;parseFloat(sysInfo.memory.quotaUsagePercent)&#125;%&quot;&gt;&lt;/div&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                &lt;/div&gt;</span><br><span class="line">            &lt;/div&gt;</span><br><span class="line">        `;</span><br><span class="line">    &#125; else &#123;</span><br><span class="line">        html += `</span><br><span class="line">            &lt;div class=&quot;card&quot;&gt;</span><br><span class="line">                &lt;h2&gt;⚠️ Memory Information Error&lt;/h2&gt;</span><br><span class="line">                &lt;p&gt;$&#123;sysInfo.error&#125;&lt;/p&gt;</span><br><span class="line">            &lt;/div&gt;</span><br><span class="line">        `;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    // 日志显示</span><br><span class="line">    html += `</span><br><span class="line">            &lt;div class=&quot;card&quot;&gt;</span><br><span class="line">                &lt;h2&gt;📝 Recent Keeper Logs&lt;/h2&gt;</span><br><span class="line">                &lt;div class=&quot;log-container&quot;&gt;</span><br><span class="line">    `;</span><br><span class="line">    </span><br><span class="line">    logs.forEach(logEntry =&gt; &#123;</span><br><span class="line">        if (logEntry.trim()) &#123;</span><br><span class="line">            // 为不同类型的日志添加颜色</span><br><span class="line">            let logClass = &#x27;log-entry&#x27;;</span><br><span class="line">            if (logEntry.includes(&#x27;ERROR&#x27;) || logEntry.includes(&#x27;FAILED&#x27;)) &#123;</span><br><span class="line">                logClass += &#x27; log-error&#x27;;</span><br><span class="line">            &#125; else if (logEntry.includes(&#x27;SUCCESS&#x27;) || logEntry.includes(&#x27;UP&#x27;) || logEntry.includes(&#x27;healthy&#x27;)) &#123;</span><br><span class="line">                logClass += &#x27; log-success&#x27;;</span><br><span class="line">            &#125; else if (logEntry.includes(&#x27;MAINTENANCE&#x27;) || logEntry.includes(&#x27;STOP&#x27;)) &#123;</span><br><span class="line">                logClass += &#x27; log-warning&#x27;;</span><br><span class="line">            &#125;</span><br><span class="line">            </span><br><span class="line">            html += `&lt;div class=&quot;$&#123;logClass&#125;&quot;&gt;$&#123;logEntry&#125;&lt;/div&gt;`;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    html += `</span><br><span class="line">                &lt;/div&gt;</span><br><span class="line">            &lt;/div&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">    &lt;/body&gt;</span><br><span class="line">    &lt;/html&gt;</span><br><span class="line">    `;</span><br><span class="line"></span><br><span class="line">    res.send(html);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">// 2. 反向代理：把所有其他请求转发给 gpt-load (30345)</span><br><span class="line">// 这样你直接访问域名，就等于访问了 30345，但不用担心代理节点屏蔽端口</span><br><span class="line">app.use(&quot;/&quot;, createProxyMiddleware(&#123;</span><br><span class="line">    target: `http://127.0.0.1:$&#123;TARGET_PORT&#125;`,</span><br><span class="line">    changeOrigin: true,</span><br><span class="line">    ws: true, // 支持 WebSocket (如果 gpt-load 需要)</span><br><span class="line">    onError: (err, req, res) =&gt; &#123;</span><br><span class="line">        res.status(502).send(`</span><br><span class="line">            &lt;h1&gt;502 Bad Gateway&lt;/h1&gt;</span><br><span class="line">            &lt;p&gt;Keeper is running, but gpt-load-server (Port $&#123;TARGET_PORT&#125;) seems down or starting.&lt;/p&gt;</span><br><span class="line">            &lt;p&gt;Check &lt;a href=&quot;/keeper-status&quot;&gt;/keeper-status&lt;/a&gt; for details.&lt;/p&gt;</span><br><span class="line">        `);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;));</span><br><span class="line"></span><br><span class="line">app.listen(port, () =&gt; log(`Keeper &amp; Proxy listening on port $&#123;port&#125;`));</span><br></pre></td></tr></table></figure><p><del>### 3.启动程序（要以绝对路径启动，不然……app.js没办法重启gpt-load-server）</del><br><del>启动gpt-load-server</del></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd /home/username/gpt-load</span><br><span class="line">nohup ./gpt-load-server &gt; gpt-load.log 2&gt;&amp;1 &amp;</span><br></pre></td></tr></table></figure><p><del>启动app.js</del>（<em>在serv00网站restart就行，会自动生成keeper.log</em>）</p><p><del>&#96;&#96;&#96;</del><br><del>cd &#x2F;home&#x2F;username&#x2F;domains&#x2F;username.serv00.net&#x2F;public_nodejs</del><br><del>nohup node app.js &gt; app.log 2&gt;&amp;1 &amp;</del><br><del>&#96;&#96;&#96;</del></p><h4 id="4-验证"><a href="#4-验证" class="headerlink" title="4.验证"></a>4.验证</h4><p>手动杀掉gpt-load-server</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pkill -f gpt-load-server</span><br></pre></td></tr></table></figure><p>在public_nodejs目录</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[id@s9]:&lt;~/domains/id.serv00.net/public_nodejs&gt;$ pkill -f gpt-load-server</span><br><span class="line">[id@s9]:&lt;~/domains/id.serv00.net/public_nodejs&gt;$ tail -f keeper.log</span><br></pre></td></tr></table></figure><p><del>查看app.log</del> keeper.log</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tail -f keeper.log</span><br></pre></td></tr></table></figure><p>显示下面则成功：<br><img src="https://linux.do/uploads/default/original/4X/7/8/d/78d5daaf762d4737faeae9a09737d9f9a2b296c6.jpeg" alt="image|690x236"></p><h4 id="5-暂停保活（开启维护模式）："><a href="#5-暂停保活（开启维护模式）：" class="headerlink" title="5.暂停保活（开启维护模式）："></a>5.暂停保活（开启维护模式）：</h4><p>进入app.js所在目录创建 stop.txt 文件：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">touch stop.txt</span><br></pre></td></tr></table></figure><h4 id="恢复保活（关闭维护模式）："><a href="#恢复保活（关闭维护模式）：" class="headerlink" title="恢复保活（关闭维护模式）："></a>恢复保活（关闭维护模式）：</h4><p>删除 stop.txt 文件：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rm stop.txt</span><br></pre></td></tr></table></figure><p>PS：最简单的还是pm2保活，官方也没看到说禁止，说的是最好用passenger，访问我用的域名+端口，可以自己试试passenger反代去掉端口</p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="开发调优" scheme="http://hexo.banlan.nyc.mn/categories/%E5%BC%80%E5%8F%91%E8%B0%83%E4%BC%98/"/>
    
    
    <category term="serv00 &amp;&amp; go" scheme="http://hexo.banlan.nyc.mn/tags/serv00-go/"/>
    
  </entry>
  
  <entry>
    <title>Git代理设置</title>
    <link href="http://hexo.banlan.nyc.mn/posts/35adffec.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/35adffec.html</id>
    <published>2025-08-17T14:25:18.000Z</published>
    <updated>2025-09-26T11:24:29.529Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h3 id="1-临时代理设置"><a href="#1-临时代理设置" class="headerlink" title="1.临时代理设置"></a>1.临时代理设置</h3><blockquote><p>只对当前命令行会话生效，命令行窗口关闭后失效</p></blockquote><p>命令：<br>在Linux下，命令行窗口内执行：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">export http_proxy=http://代理服务器地址:端口号 #比如export http_proxy=http://127.0.0.1:7890</span><br><span class="line">export https_proxy=http://代理服务器地址:端口号</span><br><span class="line"># 如果代理服务器需要用户名和密码</span><br><span class="line"># export http_proxy=http://用户名:密码@代理服务器地址:端口号</span><br><span class="line"># export https_proxy=http://用户名:密码@代理服务器地址:端口号</span><br></pre></td></tr></table></figure><p>在Windows下，命令行窗口内执行：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$env:http_proxy = &quot;http://127.0.0.1:7890&quot;</span><br><span class="line">$env:https_proxy = &quot;http://127.0.0.1:7890&quot;</span><br></pre></td></tr></table></figure><p>对于GitHub push的话，一般不会生效，直接指定：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git -c http.proxy=&quot;http://127.0.0.1:7890&quot; push</span><br></pre></td></tr></table></figure><p>验证：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 查看当前会话的 HTTP/HTTPS 代理设置</span><br><span class="line">Get-ChildItem Env: | Where-Object &#123; $_.Name -match &quot;proxy&quot; &#125;</span><br><span class="line"># 或直接输出</span><br><span class="line">echo &quot;HTTP_PROXY: $env:http_proxy&quot;</span><br><span class="line">echo &quot;HTTPS_PROXY: $env:https_proxy&quot;</span><br></pre></td></tr></table></figure><p>取消临时代理：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">unset http_proxy</span><br><span class="line">unset https_proxy</span><br></pre></td></tr></table></figure><h3 id="2-永久全局代理设置"><a href="#2-永久全局代理设置" class="headerlink" title="2.永久全局代理设置"></a>2.永久全局代理设置</h3><blockquote><p>对所有Git操作生效，永久有效（除非手动修改）</p></blockquote><p>命令：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">git config --global http.proxy http://代理服务器地址:端口号</span><br><span class="line">git config --global https.proxy http://代理服务器地址:端口号</span><br><span class="line"># 如果代理服务器需要用户名和密码</span><br><span class="line"># git config --global http.proxy http://用户名:密码@代理服务器地址:端口号</span><br><span class="line"># git config --global https.proxy http://用户名:密码@代理服务器地址:端口号</span><br></pre></td></tr></table></figure><p>查看全局代理设置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config --global --get http.proxy</span><br><span class="line">git config --global --get https.proxy</span><br></pre></td></tr></table></figure><p>取消全局代理设置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config --global --unset http.proxy</span><br><span class="line">git config --global --unset https.proxy</span><br></pre></td></tr></table></figure><p>存储位置：”C:\Users\banlan.gitconfig”，可通过文本编辑器自行修改</p><h3 id="3-与系统环境变量的区别"><a href="#3-与系统环境变量的区别" class="headerlink" title="3.与系统环境变量的区别"></a>3.与系统环境变量的区别</h3><p>系统-&gt;高级系统设置-&gt;环境变量-&gt;系统变量</p><p>三者的区别和关系</p><table><thead><tr><th>特性</th><th>Git 全局配置</th><th>临时环境变量</th><th>系统环境变量</th></tr></thead><tbody><tr><td>存储位置</td><td>~&#x2F;.gitconfig</td><td>仅在当前会话有效</td><td>操作系统相关</td></tr><tr><td>优先级</td><td>最高 (Git 优先使用自己的配置)</td><td>中</td><td>最低 (除非没有其他配置)</td></tr><tr><td>作用范围</td><td>仅影响 Git 命令</td><td>仅影响当前 shell 会话</td><td>影响所有使用系统代理的程序</td></tr><tr><td>持久性</td><td>永久 (除非手动修改)</td><td>临时, 关闭 shell 失效</td><td>永久 (除非手动修改)</td></tr></tbody></table><p>关系：</p><ul><li>Git 首先会检查自己的全局配置 (~&#x2F;.gitconfig) 中是否设置了代理。 如果设置了，就使用 Git 全局配置。</li><li>如果没有设置 Git 全局代理，Git 可能会检查临时环境变量 (http_proxy, https_proxy)。</li><li>如果临时环境变量也没有设置，Git 有时 (不总是) 会尝试使用系统环境变量。 但这种依赖性并不稳定，不推荐依赖系统环境变量来设置 Git 代理。</li></ul><p>总结：</p><ul><li>优先级： Git 全局配置 &gt; 临时环境变量 &gt; 系统环境变量 （一般来说）。</li><li>最佳实践： 推荐使用 Git 全局配置来设置 Git 代理。 如果只需要临时使用代理，可以使用临时环境变量。 避免依赖系统环境变量来配置 Git 代理。</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="网络知识" scheme="http://hexo.banlan.nyc.mn/categories/%E7%BD%91%E7%BB%9C%E7%9F%A5%E8%AF%86/"/>
    
    
    <category term="Git代理" scheme="http://hexo.banlan.nyc.mn/tags/Git%E4%BB%A3%E7%90%86/"/>
    
  </entry>
  
  <entry>
    <title>Windows资源管理器侧边栏有两个onedrive问题解决</title>
    <link href="http://hexo.banlan.nyc.mn/posts/4d061636.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/4d061636.html</id>
    <published>2025-08-05T12:06:26.000Z</published>
    <updated>2025-08-16T08:42:18.333Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h4 id="1-问题场景"><a href="#1-问题场景" class="headerlink" title="1.问题场景"></a>1.问题场景</h4><p>刚换的电脑，onedrive时不时就喜欢弹出来，然后就顺手点击一下登陆，结果在文件资源管理器快速访问上面出现两个onedrive，想删掉一个<br><img src="https://linux.do/uploads/default/original/4X/5/3/9/539a9bdfa52d97dbb49a076bd8c6e745a2f6862d.png"></p><h4 id="导致原因"><a href="#导致原因" class="headerlink" title="导致原因"></a>导致原因</h4><p>应该是win11预置了onedrive，结果刚才点击登录没仔细看又下了一个还是怎么的，导致显示两个onedrive</p><h4 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h4><ul><li>win+R 输入<code>regedit</code>进入注册表</li><li>找到<code>HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace</code>，找到<code>OneDrive - Personal</code> 条目的文件夹并复制文件夹ID<br><img src="https://linux.do/uploads/default/original/4X/c/4/1/c41b3619e41561579c72080cb38f7f61db30ec36.png"></li><li>注册表中定位到<code>HKEY_CLASSES_ROOT\CLSID\文件夹ID</code>，把<code>System.IsPinnedtoNameSpaceTree</code>的值改为<code>0</code>，关掉资源管理器重新打开可以看到效果。<br><img src="https://linux.do/uploads/default/original/4X/1/5/e/15e80b874753c351ffe031e4c8f50d335b35bf1e.png"></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="Windows小记" scheme="http://hexo.banlan.nyc.mn/categories/Windows%E5%B0%8F%E8%AE%B0/"/>
    
    
    <category term="小技巧" scheme="http://hexo.banlan.nyc.mn/tags/%E5%B0%8F%E6%8A%80%E5%B7%A7/"/>
    
  </entry>
  
  <entry>
    <title>Docker更新镜像-myself</title>
    <link href="http://hexo.banlan.nyc.mn/posts/a361f4e3.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/a361f4e3.html</id>
    <published>2025-06-30T11:07:57.000Z</published>
    <updated>2025-06-30T11:29:38.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h2 id="一、我找到并使用过的方法"><a href="#一、我找到并使用过的方法" class="headerlink" title="一、我找到并使用过的方法"></a>一、我找到并使用过的方法</h2><h3 id="1-对于使用docker命令部署的应用"><a href="#1-对于使用docker命令部署的应用" class="headerlink" title="1.对于使用docker命令部署的应用"></a>1.对于使用docker命令部署的应用</h3><p>查看容器名字</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps</span><br></pre></td></tr></table></figure><p>查看是否有挂载卷，以及容器映射到本地的路径</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker inspect 容器名 --format &#x27;&#123;&#123;json .Mounts&#125;&#125;&#x27;</span><br></pre></td></tr></table></figure><h4 id="1-1-第一种情况：没有挂载"><a href="#1-1-第一种情况：没有挂载" class="headerlink" title="1.1 第一种情况：没有挂载"></a>1.1 第一种情况：没有挂载</h4><p><img src="https://linux.do/uploads/default/original/4X/1/6/3/1638b1dd3254e894065c61316d10404a0a548e76.png" alt="image|690x43"></p><ul><li>拉取最新镜像<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull 镜像名称:标签</span><br></pre></td></tr></table></figure>一般 xxx:latest</li><li>停止并删除旧容器<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker stop 容器名</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker rm 容器名</span><br></pre></td></tr></table></figure></li><li>删除旧的镜像（可选）<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker rmi xxx:旧标签</span><br></pre></td></tr></table></figure><blockquote><p>如果镜像一直都是名为xxx:latest的话就别这样删，我是搭配docker desktop for Windows使用的，旧的镜像会变成灰色显示未使用，直接点击删除即可</p></blockquote></li><li>使用新的镜像启动容器<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d --name 新容器名称 -p port_yourself_wanted:container_port xxx:tag</span><br></pre></td></tr></table></figure><blockquote><p>在desktop点一下run就行</p></blockquote></li></ul><hr><h4 id="1-2第二种情况：有挂载"><a href="#1-2第二种情况：有挂载" class="headerlink" title="1.2第二种情况：有挂载"></a>1.2第二种情况：有挂载</h4><p>数据卷挂载</p><p><img src="https://linux.do/uploads/default/original/4X/a/d/b/adb229932628519210afc27ae62b9cd87f849457.png" alt="image|690x34"></p><p>绑定挂载</p><p><img src="https://linux.do/uploads/default/original/4X/f/4/7/f47ebab65398a77a538a757017fc6ab550d1c24c.png" alt="image|690x50"></p><ul><li>备份（可选）——以veloera为例<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">tar -czvf veloera-backup-logs.tar.gz -C /mnt/d/Veleora/veloera/logs .</span><br><span class="line">tar -czvf veloera-backup-data.tar.gz -C /mnt/d/Veleora/veloera/data .</span><br></pre></td></tr></table></figure>——以openwebui为例<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker cp open-webui:/app/backend/data ./open-webui-backup</span><br></pre></td></tr></table></figure></li><li>停止并删除旧容器<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker stop 容器名</span><br><span class="line">docker rm 容器名</span><br></pre></td></tr></table></figure></li><li>拉取新镜像<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull xxx:latest</span><br></pre></td></tr></table></figure></li><li>启动新容器并直接挂载旧数据<blockquote><p>绑定挂载</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">docker run -d \</span><br><span class="line">--name &lt;新容器名称&gt; \</span><br><span class="line">-p 3000:8080 \</span><br><span class="line">-v /mnt/d/Veleora/veloera/logs:/app/logs \</span><br><span class="line">-v /mnt/d/Veleora/veloera/data:/data \</span><br><span class="line">&lt;镜像名称&gt;:&lt;版本&gt;</span><br></pre></td></tr></table></figure><blockquote><p>数据卷挂载</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d -p 3000:8080 -v open-webui:/app/backend/data --name open-webui ghcr.io/open-webui/open-webui:main</span><br></pre></td></tr></table></figure><a href="https://docs.openwebui.com/getting-started/updating/">OpenWebUI文档参考</a><blockquote><p>绑定挂载和数据卷挂载（不使用-v）在删除旧容器时仍保留</p></blockquote></li></ul><h4 id="如果采用备份"><a href="#如果采用备份" class="headerlink" title="如果采用备份"></a>如果采用备份</h4><blockquote><p>1.创建新的数据卷</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;docker volume create open-webui-new</span><br></pre></td></tr></table></figure><p>2.备份数据恢复到新数据卷（麻烦）<br>3.启动新容器</p></blockquote><hr><ul><li>直接恢复到宿主机目录<br>绑定挂载：<br>解压<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">tar -xzvf veloera-data-backup.tar.gz -C /path/to/data</span><br><span class="line">tar -xzvf veloera-logs-backup.tar.gz -C /path/to/logs</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">docker run -d --name 容器名 \</span><br><span class="line">    -p 3000:8080 \</span><br><span class="line">    -v /path/to/data:/app/data \</span><br><span class="line">    -v /path/to/logs:/app/logs \</span><br><span class="line">    xxx:latest</span><br></pre></td></tr></table></figure>数据卷挂载：<br>创建新容器<br>恢复备份<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker cp ./open-webui-backup open-webui-new:/app/backend/data</span><br></pre></td></tr></table></figure></li></ul><hr><h3 id="2-使用docker-compose部署的应用"><a href="#2-使用docker-compose部署的应用" class="headerlink" title="2.使用docker compose部署的应用"></a>2.使用docker compose部署的应用</h3><p>2.1到docker-compose所在文件夹下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker-compose pull</span><br></pre></td></tr></table></figure><p>2.2重启容器</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker-compose up -d --remove-orphans</span><br></pre></td></tr></table></figure><p>2.3删除旧镜像（可选⚠）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker image prune </span><br></pre></td></tr></table></figure><p>不建议直接用，还是指定某个没用的镜像吧，我用的desktop点一下删除就完了（删错了当我倒霉）</p><h3 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h3><blockquote><p>1.尽可能避免使用docker run运行容器，所有容器尽可能使用 &lt;任意路径&gt;&#x2F;&lt;软件名称&gt;&#x2F; docker-compose.yaml，挂载的文件使用本地路径.&#x2F;映射，<br>2.需要迁移的时候整个文件夹打包带走，docker compose up -d运行即可。</p></blockquote><hr><p><a href="https://cloud.tencent.com/developer/article/2086860">腾讯云参考</a></p><h2 id="二、找到但没用过的方法"><a href="#二、找到但没用过的方法" class="headerlink" title="二、找到但没用过的方法"></a>二、找到但没用过的方法</h2><h3 id="1-使用Portainer面板"><a href="#1-使用Portainer面板" class="headerlink" title="1.使用Portainer面板"></a>1.使用Portainer面板</h3><h3 id="2-使用watchtower"><a href="#2-使用watchtower" class="headerlink" title="2.使用watchtower"></a>2.使用watchtower</h3>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="技术分享" scheme="http://hexo.banlan.nyc.mn/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    
    
    <category term="docker" scheme="http://hexo.banlan.nyc.mn/tags/docker/"/>
    
  </entry>
  
  <entry>
    <title>Microsoft Edge Beta油猴类扩展开发人员模式开启未反应临时解决办法</title>
    <link href="http://hexo.banlan.nyc.mn/posts/46058762.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/46058762.html</id>
    <published>2025-06-29T16:23:50.000Z</published>
    <updated>2025-06-29T16:45:16.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><p>由于Manifest V3的原因，导致在edge浏览器上脚本猫、篡改猴安装好后会显示让你开启开发人员模式，但是你已经开启了，却没有被识别出来<br>如图所示：</p><hr><p><img src="https://linux.do/uploads/default/original/4X/3/0/a/30a73fb86daa582deab9b42efc2b2e0a903388b7.png" alt="1"></p><hr><p><img src="https://linux.do/uploads/default/original/4X/6/9/b/69bcc80588e88c7d6646bcb733c698b3219ab0a3.png" alt="2"></p><hr><h3 id="临时解决办法"><a href="#临时解决办法" class="headerlink" title="临时解决办法"></a>临时解决办法</h3><p>1.更换到对应扩展的beta版本<br>2.更换浏览器<br>3.在扩展管理页面控制台使用命令：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">chrome.developerPrivate.updateExtensionConfiguration(&#123;extensionId: &quot;扩展id&quot;, userScriptsAccess: true&#125;);</span><br></pre></td></tr></table></figure><p>参考：<a href="https://github.com/scriptscat/scriptcat/issues/418#issuecomment-2994772406">[BUG]打开特定网页显示异常！ · Issue #418 · scriptscat&#x2F;scriptcat · GitHub</a></p><hr><p>等待Microsoft尽快修复<br><del>水一下hh</del></p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="常用技巧" scheme="http://hexo.banlan.nyc.mn/categories/%E5%B8%B8%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
    <category term="小技巧" scheme="http://hexo.banlan.nyc.mn/tags/%E5%B0%8F%E6%8A%80%E5%B7%A7/"/>
    
  </entry>
  
  <entry>
    <title>记梦开篇</title>
    <link href="http://hexo.banlan.nyc.mn/posts/1587fe55.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/1587fe55.html</id>
    <published>2025-06-25T16:19:12.000Z</published>
    <updated>2025-06-30T12:57:02.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>2025年6月25日，我开始在博客里面记下每一次看见她的梦。</p><h3 id="第一篇"><a href="#第一篇" class="headerlink" title="第一篇"></a>第一篇</h3><p>我梦到我回到了高中，那天张老师又要我们考试了，但是我一个人却往教室外面朝他办公室跑去，好像要拿什么东西，半路上遇到张老师，他问我干嘛去，我说我去你办公室拿个东西，至于考试我潜意识传达的意思是我不考，我会了，嗯，就这个意思，现实里我只是在中游飘荡，不过梦里面我想怎么就怎么了。</p><p>要到他办公室的时候，在路上碰到了她，梦里面我也没奇怪为什么她还不回教室准备考试，我也没问，潜意识里面保留的意识还是我和她已经不是朋友了，可是在梦里，这会才开始，所以暂时还是美好的，因此，她还是我朋友，只有我有后面的所有真实记忆（我知道我和她已经不是朋友了）。<br>她也往办公室那边去，不知道为什么，鬼使神差地，我加了点速，跑过去跟在她后面，感觉到我跑过来跟在她后面，她转过头对我笑道，跟着我干嘛？<br>我说我也要去办公室，她笑了笑，和我一起过去，不知道为什么，心里确实有一种开心的感觉，就好像她还是我的朋友，关系更好的那种。</p><p>到办公室后面的情节已经记得不太清了，结果却是和之前每一次梦一样，总有一些原因，我和她会各有事情，然后分开走，然后梦醒了……</p><hr><p><img src="https://linux.do/uploads/default/original/4X/a/4/a/a4a0c8a80070343c1ee2fe68456580d030937f44.jpeg" alt="image.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- 
&lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    paddin</summary>
      
    
    
    
    <category term="生活随笔" scheme="http://hexo.banlan.nyc.mn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="记梦" scheme="http://hexo.banlan.nyc.mn/tags/%E8%AE%B0%E6%A2%A6/"/>
    
  </entry>
  
  <entry>
    <title>localhost和127.0.0.1到底有没有区别?</title>
    <link href="http://hexo.banlan.nyc.mn/posts/fb6ebb11.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/fb6ebb11.html</id>
    <published>2025-01-08T08:09:54.000Z</published>
    <updated>2025-06-30T13:05:06.000Z</updated>
    
    <content type="html"><![CDATA[<h3 id="1-虽然-localhost-和-127-0-0-1-大部分情况下可以互换使用，它们的本质不同"><a href="#1-虽然-localhost-和-127-0-0-1-大部分情况下可以互换使用，它们的本质不同" class="headerlink" title="1. 虽然 localhost 和 127.0.0.1 大部分情况下可以互换使用，它们的本质不同"></a>1. 虽然 localhost 和 127.0.0.1 大部分情况下可以互换使用，它们的本质不同</h3><h3 id="2-localhost-是域名，更广泛-，更抽象。"><a href="#2-localhost-是域名，更广泛-，更抽象。" class="headerlink" title="2. localhost 是域名，更广泛 ，更抽象。"></a>2. localhost 是域名，更广泛 ，更抽象。</h3><h3 id="3-127-0-0-1-是-IP-地址，更具体一点"><a href="#3-127-0-0-1-是-IP-地址，更具体一点" class="headerlink" title="3. 127.0.0.1 是 IP 地址，更具体一点"></a>3. 127.0.0.1 是 IP 地址，更具体一点</h3><h3 id="4-127-0-0-1-仅支持-IPV4-访问"><a href="#4-127-0-0-1-仅支持-IPV4-访问" class="headerlink" title="4. 127.0.0.1 仅支持 IPV4 访问"></a>4. 127.0.0.1 仅支持 IPV4 访问</h3><h3 id="5-localhost-需要通过-DNS-或-hosts-文件解析为-IP-地址，127-7-0-0-1-直接访问"><a href="#5-localhost-需要通过-DNS-或-hosts-文件解析为-IP-地址，127-7-0-0-1-直接访问" class="headerlink" title="5. localhost 需要通过 DNS 或 hosts 文件解析为 IP 地址，127.7.0.0.1 直接访问"></a>5. localhost 需要通过 DNS 或 hosts 文件解析为 IP 地址，127.7.0.0.1 直接访问</h3><h3 id="6-localhost-默认可以解析为-IPv4（127-0-0-1）或-IPv6（-1）地址，如果你的程序只支持-IPv4，而-localhost-被解析为-IPv6-地址，可能会导致连接失败"><a href="#6-localhost-默认可以解析为-IPv4（127-0-0-1）或-IPv6（-1）地址，如果你的程序只支持-IPv4，而-localhost-被解析为-IPv6-地址，可能会导致连接失败" class="headerlink" title="6. localhost 默认可以解析为 IPv4（127.0.0.1）或 IPv6（::1）地址，如果你的程序只支持 IPv4，而 localhost 被解析为 IPv6 地址，可能会导致连接失败"></a>6. localhost 默认可以解析为 IPv4（127.0.0.1）或 IPv6（::1）地址，如果你的程序只支持 IPv4，而 localhost 被解析为 IPv6 地址，可能会导致连接失败</h3><!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> -->]]></content>
    
    
      
      
    <summary type="html">&lt;h3 id=&quot;1-虽然-localhost-和-127-0-0-1-大部分情况下可以互换使用，它们的本质不同&quot;&gt;&lt;a href=&quot;#1-虽然-localhost-和-127-0-0-1-大部分情况下可以互换使用，它们的本质不同&quot; class=&quot;headerlink&quot; title</summary>
      
    
    
    
    <category term="网络知识" scheme="http://hexo.banlan.nyc.mn/categories/%E7%BD%91%E7%BB%9C%E7%9F%A5%E8%AF%86/"/>
    
    
    <category term="ip&amp;domain" scheme="http://hexo.banlan.nyc.mn/tags/ip-domain/"/>
    
  </entry>
  
  <entry>
    <title>ipinfo的curl使用</title>
    <link href="http://hexo.banlan.nyc.mn/posts/e6116d0f.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/e6116d0f.html</id>
    <published>2025-01-07T07:48:39.000Z</published>
    <updated>2025-06-30T13:05:02.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="win-R-输入cmd-然后输入"><a href="#win-R-输入cmd-然后输入" class="headerlink" title="win+R 输入cmd 然后输入"></a>win+R 输入cmd 然后输入</h2><figure class="highlight bash"><figcaption><span>显示公网ip（无代理的本地ip）</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl ipinfo.io</span><br></pre></td></tr></table></figure><figure class="highlight bash"><figcaption><span>也可以查看本地ip</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl cip.cc</span><br></pre></td></tr></table></figure><figure class="highlight bash"><figcaption><span>查看指定ip的信息（ipinfo一样）</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl cip.cc/127.0.0.1</span><br></pre></td></tr></table></figure><figure class="highlight bash"><figcaption><span>查看代理时的ip（3066替换为你的代理的端口）</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -x 127.0.0.1:3066 ipinfo.io</span><br></pre></td></tr></table></figure><p><img src="https://linux.do/uploads/default/original/4X/5/1/1/511284cdd86ae33eb914163ed848b0da99331971.jpeg" alt="微信截图_20250107161129.png"></p><!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> -->]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;win-R-输入cmd-然后输入&quot;&gt;&lt;a href=&quot;#win-R-输入cmd-然后输入&quot; class=&quot;headerlink&quot; title=&quot;win+R 输入cmd 然后输入&quot;&gt;&lt;/a&gt;win+R 输入cmd 然后输入&lt;/h2&gt;&lt;figure class=&quot;hi</summary>
      
    
    
    
    <category term="常用技巧" scheme="http://hexo.banlan.nyc.mn/categories/%E5%B8%B8%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
    <category term="ip check" scheme="http://hexo.banlan.nyc.mn/tags/ip-check/"/>
    
  </entry>
  
  <entry>
    <title>使用vscode+github+cloudflare简约博客搭建</title>
    <link href="http://hexo.banlan.nyc.mn/posts/70e9d98c.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/70e9d98c.html</id>
    <published>2024-12-31T15:58:06.000Z</published>
    <updated>2025-06-30T13:01:30.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="写点生活即可"><a href="#写点生活即可" class="headerlink" title="写点生活即可"></a>写点生活即可</h1><p><img src="https://linux.do/uploads/default/original/4X/2/b/1/2b13efa3eabfcf73fff98cf5244d55da5471afa1.jpeg" alt="微信截图_20250113234833.png"></p><hr><p><img src="https://linux.do/uploads/default/original/4X/5/e/d/5ed249a8fd852a0f489032809325e5384e5e6b2f.jpeg" alt="_20250113234825.jpg"></p><h2 id="用来写点小东西（清爽一点）"><a href="#用来写点小东西（清爽一点）" class="headerlink" title="用来写点小东西（清爽一点）"></a>用来写点小东西（清爽一点）</h2><h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><h3 id="1-克隆仓库"><a href="#1-克隆仓库" class="headerlink" title="1.克隆仓库"></a>1.克隆仓库</h3><h4 id="在代码编辑器（以vscode为例）"><a href="#在代码编辑器（以vscode为例）" class="headerlink" title="在代码编辑器（以vscode为例）"></a>在代码编辑器（以vscode为例）</h4><p><code>ctrl+i</code>打开终端，新建空目录</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="built_in">mkdir</span> sblog</span><br></pre></td></tr></table></figure><p>进入该目录</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> sblog</span><br></pre></td></tr></table></figure><p>克隆仓库过来</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/2005zs/simpleblog.git</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">git <span class="built_in">clone</span> git@github.com:2005zs/simpleblog.git//https不通的时候，用ssh来<span class="built_in">clone</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>进入目录</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> simpleblog</span><br></pre></td></tr></table></figure><h3 id="2-安装依赖"><a href="#2-安装依赖" class="headerlink" title="2.安装依赖"></a>2.安装依赖</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">npm ci</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">npm install gray-matter</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="OK，这就好了，现在就可以开始写博客了"><a href="#OK，这就好了，现在就可以开始写博客了" class="headerlink" title="OK，这就好了，现在就可以开始写博客了"></a>OK，这就好了，现在就可以开始写博客了</h2><h2 id="3-新建博客"><a href="#3-新建博客" class="headerlink" title="3.新建博客"></a>3.新建博客</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">npm run new</span><br></pre></td></tr></table></figure><p><img src="https://linux.do/uploads/default/original/4X/c/7/6/c76ccd760d108524f4638abfb9ddbb2eec0e6e3b.png" alt="_20241231231438.jpg"><br><code>npm run new</code>后显示<code>请输入博客标题</code>，回车后使用键盘 :arrow_up: :arrow_down:进行选择<br><img src="https://linux.do/uploads/default/original/4X/5/1/7/517cffd963ee736cbfb992ab651bf4d1a0706a41.jpeg" alt="_20241231231317.jpg"><br>然后可以选择封面图片（上面博客列表看）<br>再选择优先级大于1则置顶</p><h2 id="4-本地生成预览"><a href="#4-本地生成预览" class="headerlink" title="4.本地生成预览"></a>4.本地生成预览</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run preview</span><br></pre></td></tr></table></figure><p>如果要修改直接在博客文件修改后在浏览器刷新显示即可</p><h2 id="5-推送github仓库"><a href="#5-推送github仓库" class="headerlink" title="5.推送github仓库"></a>5.推送github仓库</h2><h3 id="这里我没有在框架里面加那些东西，比较麻烦，就直接采用最原始的方法了"><a href="#这里我没有在框架里面加那些东西，比较麻烦，就直接采用最原始的方法了" class="headerlink" title="这里我没有在框架里面加那些东西，比较麻烦，就直接采用最原始的方法了"></a>这里我没有在框架里面加那些东西，比较麻烦，就直接采用最原始的方法了</h3><p><del>我懒</del></p><h4 id="你可能会用到"><a href="#你可能会用到" class="headerlink" title="你可能会用到"></a>你可能会用到</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> git@github.com:2005zs/simpleblog.git//https不通的时候，用ssh来<span class="built_in">clone</span></span><br><span class="line">git remote remove origin  //移除现有的 HTTPS 远程仓库</span><br><span class="line">git remote add origin git@github.com:name/repo.git  //添加 SSH 远程仓库</span><br><span class="line">git push -u origin master  //推送代码到远程仓库</span><br><span class="line">git remote -v  //查看远程仓库</span><br><span class="line">git remote set-url origin git@github.com:name/repo.git  //设置远程仓库</span><br><span class="line">git add .  //暂存所有更改</span><br><span class="line">git commit -m <span class="string">&quot;first commit&quot;</span>  //提交更改</span><br><span class="line">git push -u origin master  //推送代码到远程仓库</span><br><span class="line">git <span class="built_in">log</span>  //查看提交历史</span><br></pre></td></tr></table></figure><h3 id="建议使用ssh克隆和推送，https的反正我是经常不行-sweat-smile-sweat-smile"><a href="#建议使用ssh克隆和推送，https的反正我是经常不行-sweat-smile-sweat-smile" class="headerlink" title="建议使用ssh克隆和推送，https的反正我是经常不行 :sweat_smile: :sweat_smile:"></a>建议使用ssh克隆和推送，https的反正我是经常不行 :sweat_smile: :sweat_smile:</h3><h2 id="6-推送仓库后可选cf或github的pages部署"><a href="#6-推送仓库后可选cf或github的pages部署" class="headerlink" title="6.推送仓库后可选cf或github的pages部署"></a>6.推送仓库后可选cf或github的pages部署</h2><h2 id="部署到github的pages"><a href="#部署到github的pages" class="headerlink" title="部署到github的pages"></a>部署到github的pages</h2><h4 id="1-请将仓库命名为-username-github-io"><a href="#1-请将仓库命名为-username-github-io" class="headerlink" title="1.请将仓库命名为 username.github.io"></a>1.请将仓库命名为 <code>username.github.io</code></h4><h4 id="2-请到Actions-Pages-Static-HTML-然后config，然后会帮你生成static-yaml，然后点击Run-workflow，然后会自动部署到github-pages，成功后访问name-github-io即可"><a href="#2-请到Actions-Pages-Static-HTML-然后config，然后会帮你生成static-yaml，然后点击Run-workflow，然后会自动部署到github-pages，成功后访问name-github-io即可" class="headerlink" title="2.请到Actions-&gt;Pages-&gt;Static HTML,然后config，然后会帮你生成static.yaml，然后点击Run workflow，然后会自动部署到github pages，成功后访问name.github.io即可"></a>2.请到<code>Actions</code>-&gt;<code>Pages</code>-&gt;<code>Static HTML</code>,然后<code>config</code>，然后会帮你生成static.yaml，然后点击<code>Run workflow</code>，然后会自动部署到github pages，成功后访问name.github.io即可</h4><h2 id="部署到cloudflare"><a href="#部署到cloudflare" class="headerlink" title="部署到cloudflare"></a>部署到cloudflare</h2><h4 id="cloudflare账户链接github"><a href="#cloudflare账户链接github" class="headerlink" title="cloudflare账户链接github"></a>cloudflare账户链接github</h4><p>在<code>构建设置</code>中输入<code>构建命令</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">node scripts/bl.js build</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>保存部署即可</p><h2 id="7-成果"><a href="#7-成果" class="headerlink" title="7.成果"></a>7.成果</h2><p><a href="https://zyx.ruo.my/">地址 </a>   <a href="https://github.com/2005zs">作者</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;写点生活即可&quot;&gt;&lt;a href=&quot;#写点生活即可&quot; class=&quot;headerlink&quot; title=&quot;写点生活即可&quot;&gt;&lt;/a&gt;写点生活即可&lt;/h1&gt;&lt;p&gt;&lt;img src=&quot;https://linux.do/uploads/default/original/4X</summary>
      
    
    
    
    <category term="技术分享" scheme="http://hexo.banlan.nyc.mn/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    
    
    <category term="blog" scheme="http://hexo.banlan.nyc.mn/tags/blog/"/>
    
  </entry>
  
  <entry>
    <title>破解加密ppt文件使其能够正常转换为pdf</title>
    <link href="http://hexo.banlan.nyc.mn/posts/40a67fe1.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/40a67fe1.html</id>
    <published>2024-11-08T14:10:32.000Z</published>
    <updated>2025-06-30T12:48:18.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h2 id="PS-感谢L站的-pengzhile-佬友"><a href="#PS-感谢L站的-pengzhile-佬友" class="headerlink" title="PS:感谢L站的 @pengzhile 佬友"></a>PS:感谢L站的 @pengzhile 佬友</h2><h3 id="1-首先打开WinRAR或者7Zip之类的压缩软件（ppt本身是一种压缩文件）"><a href="#1-首先打开WinRAR或者7Zip之类的压缩软件（ppt本身是一种压缩文件）" class="headerlink" title="1.首先打开WinRAR或者7Zip之类的压缩软件（ppt本身是一种压缩文件）"></a>1.首先打开WinRAR或者7Zip之类的压缩软件（ppt本身是一种压缩文件）</h3><h3 id="2-在文件资源管理器中找到要解除加密的ppt-pptx文件"><a href="#2-在文件资源管理器中找到要解除加密的ppt-pptx文件" class="headerlink" title="2.在文件资源管理器中找到要解除加密的ppt&#x2F;pptx文件"></a>2.在文件资源管理器中找到要解除加密的ppt&#x2F;pptx文件</h3><h3 id="3-右键打开压缩文件"><a href="#3-右键打开压缩文件" class="headerlink" title="3.右键打开压缩文件"></a>3.右键打开压缩文件</h3><h3 id="3-打开ppt文件"><a href="#3-打开ppt文件" class="headerlink" title="3.打开ppt文件"></a>3.打开ppt文件</h3><p><img src="https://linux.do/uploads/default/original/4X/b/5/9/b591ced88dc57da6f7a1f5bf6351b0e760804884.jpeg" alt="1.jpg"></p><h3 id="5-右键编辑（查看）这个-ppt-presentation-xml文件"><a href="#5-右键编辑（查看）这个-ppt-presentation-xml文件" class="headerlink" title="5.右键编辑（查看）这个 &#x2F;ppt&#x2F;presentation.xml文件"></a>5.右键编辑（查看）这个 &#x2F;ppt&#x2F;presentation.xml文件</h3><p><img src="https://linux.do/uploads/default/original/4X/2/2/d/22dc8844441bf9fb7d2ebead230aa5c55cb27407.jpeg" alt="2.jpg"></p><h3 id="6-Ctrl-F查找-modifyVerifier"><a href="#6-Ctrl-F查找-modifyVerifier" class="headerlink" title="6.Ctrl+F查找 modifyVerifier"></a>6.Ctrl+F查找 modifyVerifier</h3><p><img src="https://linux.do/uploads/default/original/4X/a/9/0/a901f6f3ceffd320b7acb22b27e74081dac25ae0.jpeg" alt="3.png"></p><h3 id="7-然后把这个整个p标签给干掉，然后保存文件，更新压缩包内容，于是就能编辑ppt了。有了编辑ppt的权限，就能用Adobe-acrobat转换为pdf了；或者用powerpoint打开，到主页左侧可以看到使用Adobe-acrobat转换为pdf"><a href="#7-然后把这个整个p标签给干掉，然后保存文件，更新压缩包内容，于是就能编辑ppt了。有了编辑ppt的权限，就能用Adobe-acrobat转换为pdf了；或者用powerpoint打开，到主页左侧可以看到使用Adobe-acrobat转换为pdf" class="headerlink" title="7.然后把这个整个p标签给干掉，然后保存文件，更新压缩包内容，于是就能编辑ppt了。有了编辑ppt的权限，就能用Adobe acrobat转换为pdf了；或者用powerpoint打开，到主页左侧可以看到使用Adobe acrobat转换为pdf"></a>7.然后把这个整个p标签给干掉，然后保存文件，更新压缩包内容，于是就能编辑ppt了。有了编辑ppt的权限，就能用Adobe acrobat转换为pdf了；或者用powerpoint打开，到主页左侧可以看到使用Adobe acrobat转换为pdf</h3><h2 id="解除加密批处理脚本（-pengzhile）"><a href="#解除加密批处理脚本（-pengzhile）" class="headerlink" title="解除加密批处理脚本（@pengzhile）"></a>解除加密批处理脚本（@pengzhile）</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br></pre></td><td class="code"><pre><span class="line">import os</span><br><span class="line">import shutil</span><br><span class="line">import zipfile</span><br><span class="line">import tempfile</span><br><span class="line">import argparse</span><br><span class="line">from lxml import etree</span><br><span class="line">from concurrent.futures import ProcessPoolExecutor, as_completed</span><br><span class="line">import multiprocessing</span><br><span class="line"></span><br><span class="line">def remove_modify_verifier(input_pptx, output_pptx):</span><br><span class="line">    try:</span><br><span class="line">        with tempfile.TemporaryDirectory() as tmpdir:</span><br><span class="line">            with zipfile.ZipFile(input_pptx, <span class="string">&#x27;r&#x27;</span>) as zip_ref:</span><br><span class="line">                zip_ref.extractall(tmpdir)</span><br><span class="line"></span><br><span class="line">            presentation_xml_path = os.path.join(tmpdir, <span class="string">&#x27;ppt&#x27;</span>, <span class="string">&#x27;presentation.xml&#x27;</span>)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> not os.path.exists(presentation_xml_path):</span><br><span class="line">                <span class="built_in">return</span> False, <span class="string">&quot;找不到 ppt/presentation.xml 文件。&quot;</span></span><br><span class="line"></span><br><span class="line">            parser = etree.XMLParser(remove_blank_text=True)</span><br><span class="line">            tree = etree.parse(presentation_xml_path, parser)</span><br><span class="line">            root = tree.getroot()</span><br><span class="line"></span><br><span class="line">            namespaces = &#123;<span class="string">&#x27;p&#x27;</span>: <span class="string">&#x27;http://schemas.openxmlformats.org/presentationml/2006/main&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line">            modify_verifiers = root.findall(<span class="string">&#x27;.//p:modifyVerifier&#x27;</span>, namespaces)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> not modify_verifiers:</span><br><span class="line">                pass</span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="keyword">for</span> verifier <span class="keyword">in</span> modify_verifiers:</span><br><span class="line">                    parent = verifier.getparent()</span><br><span class="line">                    parent.remove(verifier)</span><br><span class="line"></span><br><span class="line">                tree.write(presentation_xml_path, xml_declaration=True, encoding=<span class="string">&#x27;UTF-8&#x27;</span>, pretty_print=True)</span><br><span class="line"></span><br><span class="line">            with zipfile.ZipFile(output_pptx, <span class="string">&#x27;w&#x27;</span>, zipfile.ZIP_DEFLATED) as zip_out:</span><br><span class="line">                <span class="keyword">for</span> foldername, subfolders, filenames <span class="keyword">in</span> os.walk(tmpdir):</span><br><span class="line">                    <span class="keyword">for</span> filename <span class="keyword">in</span> filenames:</span><br><span class="line">                        file_path = os.path.join(foldername, filename)</span><br><span class="line">                        rel_path = os.path.relpath(file_path, tmpdir)</span><br><span class="line">                        zip_out.write(file_path, rel_path)</span><br><span class="line"></span><br><span class="line">        <span class="built_in">return</span> True, None</span><br><span class="line">    except Exception as e:</span><br><span class="line">        <span class="built_in">return</span> False, str(e)</span><br><span class="line"></span><br><span class="line">def process_file(file_path, output_dir):</span><br><span class="line">    try:</span><br><span class="line">        filename = os.path.basename(file_path)</span><br><span class="line">        output_path = os.path.join(output_dir, filename)</span><br><span class="line">        success, error = remove_modify_verifier(file_path, output_path)</span><br><span class="line">        <span class="keyword">if</span> success:</span><br><span class="line">            <span class="built_in">return</span> (file_path, True, None)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">return</span> (file_path, False, error)</span><br><span class="line">    except Exception as e:</span><br><span class="line">        <span class="built_in">return</span> (file_path, False, str(e))</span><br><span class="line"></span><br><span class="line">def main():</span><br><span class="line">    parser = argparse.ArgumentParser(description=<span class="string">&#x27;将只读 PPTX/PPT 文件转换为可编辑的 PPTX 文件。&#x27;</span>)</span><br><span class="line">    parser.add_argument(<span class="string">&#x27;path&#x27;</span>, nargs=<span class="string">&#x27;?&#x27;</span>, <span class="built_in">help</span>=<span class="string">&#x27;输入的PPTX/PPT文件或文件夹路径&#x27;</span>)</span><br><span class="line">    args = parser.parse_args()</span><br><span class="line"></span><br><span class="line">    input_folder = <span class="string">&#x27;input&#x27;</span></span><br><span class="line">    output_folder = <span class="string">&#x27;output&#x27;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> os.path.isdir(input_folder):</span><br><span class="line">        input_paths = []</span><br><span class="line">        <span class="keyword">for</span> root_dir, _, files <span class="keyword">in</span> os.walk(input_folder):</span><br><span class="line">            <span class="keyword">for</span> file <span class="keyword">in</span> files:</span><br><span class="line">                <span class="keyword">if</span> file.lower().endswith((&#x27;.pptx&#x27;, &#x27;.ppt&#x27;)):</span><br><span class="line">                    input_paths.append(os.path.join(root_dir, file))</span><br><span class="line">    <span class="keyword">elif</span> args.path:</span><br><span class="line">        <span class="keyword">if</span> os.path.isdir(args.path):</span><br><span class="line">            input_paths = []</span><br><span class="line">            <span class="keyword">for</span> root_dir, _, files <span class="keyword">in</span> os.walk(args.path):</span><br><span class="line">                <span class="keyword">for</span> file <span class="keyword">in</span> files:</span><br><span class="line">                    <span class="keyword">if</span> file.lower().endswith((&#x27;.pptx&#x27;, &#x27;.ppt&#x27;)):</span><br><span class="line">                        input_paths.append(os.path.join(root_dir, file))</span><br><span class="line">        <span class="keyword">elif</span> os.path.isfile(args.path) and args.path.lower().endswith((&#x27;.pptx&#x27;, &#x27;.ppt&#x27;)):</span><br><span class="line">            input_paths = [args.path]</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;错误：指定的路径不是有效的PPTX/PPT文件或文件夹。&quot;</span>)</span><br><span class="line">            <span class="built_in">return</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;错误：当前目录下不存在 &#x27;input&#x27; 文件夹，且未提供输入路径。请指定输入文件或文件夹路径。&quot;</span>)</span><br><span class="line">        <span class="built_in">return</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> not input_paths:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;没有找到需要处理的PPTX/PPT文件。&quot;</span>)</span><br><span class="line">        <span class="built_in">return</span></span><br><span class="line"></span><br><span class="line">    os.makedirs(output_folder, exist_ok=True)</span><br><span class="line"></span><br><span class="line">    total = len(input_paths)</span><br><span class="line">    success_count = 0</span><br><span class="line">    fail_count = 0</span><br><span class="line">    fail_details = []</span><br><span class="line"></span><br><span class="line">    cpu_count = multiprocessing.cpu_count()</span><br><span class="line">    with ProcessPoolExecutor(max_workers=cpu_count) as executor:</span><br><span class="line">        future_to_file = &#123;executor.submit(process_file, file_path, output_folder): file_path <span class="keyword">for</span> file_path <span class="keyword">in</span> input_paths&#125;</span><br><span class="line">        <span class="keyword">for</span> future <span class="keyword">in</span> as_completed(future_to_file):</span><br><span class="line">            file_path = future_to_file[future]</span><br><span class="line">            try:</span><br><span class="line">                _, success, error = future.result()</span><br><span class="line">                <span class="keyword">if</span> success:</span><br><span class="line">                    success_count += 1</span><br><span class="line">                <span class="keyword">else</span>:</span><br><span class="line">                    fail_count += 1</span><br><span class="line">                    fail_details.append((file_path, error))</span><br><span class="line">            except Exception as e:</span><br><span class="line">                fail_count += 1</span><br><span class="line">                fail_details.append((file_path, str(e)))</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(f<span class="string">&quot;遍历 &#123;total&#125; 个文件，已成功 &#123;success_count&#125; 个文件，失败 &#123;fail_count&#125; 个文件。&quot;</span>)</span><br><span class="line">    <span class="keyword">if</span> fail_count &gt; 0:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;失败的文件及原因：&quot;</span>)</span><br><span class="line">        <span class="keyword">for</span> file, reason <span class="keyword">in</span> fail_details:</span><br><span class="line">            <span class="built_in">print</span>(f<span class="string">&quot;&#123;file&#125;: &#123;reason&#125;&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">复制一下，保存为比如说我保存：ppt_remove_readonly.py</span><br><span class="line"></span><br><span class="line">然后在同级目录下放一个input文件夹，里面放若干个你需要破解只读属性的pptx</span><br><span class="line"></span><br><span class="line">然后python运行这个脚本就行了。嗷对了，需要pip install lxml</span><br><span class="line"></span><br><span class="line">然后很快就会自动处理成可编辑的PPT了，输出到output文件夹中。</span><br><span class="line"></span><br><span class="line">然后你可以批量转换为pdf了</span><br></pre></td></tr></table></figure><p><img src="https://linux.do/uploads/default/original/4X/b/5/3/b53cd267f46b53f92b6fca81aeeead8157caab98.png" alt="4.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="常用技巧" scheme="http://hexo.banlan.nyc.mn/categories/%E5%B8%B8%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
    <category term="小技巧" scheme="http://hexo.banlan.nyc.mn/tags/%E5%B0%8F%E6%8A%80%E5%B7%A7/"/>
    
  </entry>
  
  <entry>
    <title>cloudflare托管域名开启5秒盾</title>
    <link href="http://hexo.banlan.nyc.mn/posts/5e54f448.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/5e54f448.html</id>
    <published>2024-10-19T06:03:31.000Z</published>
    <updated>2025-06-30T13:03:56.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h1 id="Cloudflare开启域名真人验证防止被DDoS攻击"><a href="#Cloudflare开启域名真人验证防止被DDoS攻击" class="headerlink" title="Cloudflare开启域名真人验证防止被DDoS攻击"></a>Cloudflare开启域名真人验证防止被DDoS攻击</h1><p><img src="https://linux.do/uploads/default/original/4X/3/1/7/31789e3aca8b6919733f98a9b5f9ebffe185efaf.png"></p><p>当cloudflare托管的域名遭受当网站受到 <a href="https://so.csdn.net/so/search?q=DDoS%20%E6%94%BB%E5%87%BB&spm=1001.2101.3001.7020">DDoS<br>攻击</a>时，可以配置开启真人验证，防止资产被攻击。</p><p>开启真人验证的方法：</p><p>进入要开启的域名，安全性 – 设置 – 安全级别，选择 I’m Under Attack!</p><p><img src="https://linux.do/uploads/default/original/4X/2/4/e/24eb3adfe1d111f0fffaf8c805ea25a1e93aed99.png"></p><p>此时此域名下的所有子域名都会被要求进行真人验证。</p><p>另外，如果是不想所有的子域名都进入到 Under Attack 模式，则可以在配置规则里创建自定义规则。</p><p><img src="https://linux.do/uploads/default/original/4X/5/b/c/5bc8e09e0dc6fe5ed98d8502f31c65c2ff7d7f0b.jpeg" alt="8.jpg"></p><p>添加规则名称，选择自定义筛选<a href="https://so.csdn.net/so/search?q=%E8%A1%A8%E8%BE%BE%E5%BC%8F&spm=1001.2101.3001.7020">表达式</a><br>例如某个子域名不想加安全验证<br><img src="https://linux.do/uploads/default/original/4X/1/4/b/14b2023904821d95bc68ab5391710627c5dc569b.jpeg" alt="9.jpg"><br><img src="https://linux.do/uploads/default/original/4X/4/5/1/4517127a9d6bf0dd58f678f94426641f91719dda.jpeg" alt="10.jpg"></p><p>单独某个子域名加安全验证就修改为I&#96;m Under Attack就行，选“主机名”“等于”“子域名”就行<br>配置完就可以立即生效了。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="网络知识" scheme="http://hexo.banlan.nyc.mn/categories/%E7%BD%91%E7%BB%9C%E7%9F%A5%E8%AF%86/"/>
    
    
    <category term="小技巧" scheme="http://hexo.banlan.nyc.mn/tags/%E5%B0%8F%E6%8A%80%E5%B7%A7/"/>
    
  </entry>
  
  <entry>
    <title>使用cloudflare搭建个人极简导航站</title>
    <link href="http://hexo.banlan.nyc.mn/posts/b22845dc.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/b22845dc.html</id>
    <published>2024-10-11T06:37:01.000Z</published>
    <updated>2025-06-30T12:57:44.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><h1 id="1-前提"><a href="#1-前提" class="headerlink" title="1.前提"></a>1.前提</h1><h3 id="1-一个cloudflare账号"><a href="#1-一个cloudflare账号" class="headerlink" title="(1).一个cloudflare账号"></a>(1).一个cloudflare账号</h3><h3 id="2-域名（非必须）"><a href="#2-域名（非必须）" class="headerlink" title="(2).域名（非必须）"></a>(2).域名（非必须）</h3><h1 id="2-具体搭建步骤"><a href="#2-具体搭建步骤" class="headerlink" title="2.具体搭建步骤"></a>2.具体搭建步骤</h1><h3 id="Github项目地址"><a href="#Github项目地址" class="headerlink" title="Github项目地址"></a>Github项目地址</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/sleepwood/CF-Worker-Dir</span><br></pre></td></tr></table></figure><h3 id="1-在cloudflare中新建一个worker项目"><a href="#1-在cloudflare中新建一个worker项目" class="headerlink" title="(1)在cloudflare中新建一个worker项目"></a>(1)在cloudflare中新建一个worker项目</h3><h3 id="2-选择“编辑代码”，将下面的代码复制，保存点击部署"><a href="#2-选择“编辑代码”，将下面的代码复制，保存点击部署" class="headerlink" title="(2)选择“编辑代码”，将下面的代码复制，保存点击部署"></a>(2)选择“编辑代码”，将下面的代码复制，保存点击部署</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> *  自定义网站配置 </span><br><span class="line"> */</span><br><span class="line">const config = &#123;</span><br><span class="line">  title: <span class="string">&quot;自定义导航&quot;</span>,                 //write your website title</span><br><span class="line">  subtitle: <span class="string">&quot;Cloudflare Workers Dir&quot;</span>, //write your website subtitle</span><br><span class="line">  logo_icon: <span class="string">&quot;sitemap&quot;</span>,               //select your logo by semantic-ui icon (you can get more msg <span class="keyword">in</span>:https://semantic-ui.com/elements/icon.html)</span><br><span class="line">  hitokoto: <span class="literal">true</span>,                     //use hitokoto or not</span><br><span class="line">  search:<span class="literal">true</span>,                        //enable search <span class="keyword">function</span></span><br><span class="line">  search_engine:[                     //choose search engine <span class="built_in">which</span> you use</span><br><span class="line">    &#123;</span><br><span class="line">      name:<span class="string">&quot;百 度&quot;</span>,</span><br><span class="line">      template:<span class="string">&quot;https://www.baidu.com/s?wd=<span class="variable">$s</span>&quot;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      name:<span class="string">&quot;谷 歌&quot;</span>,</span><br><span class="line">      template:<span class="string">&quot;https://www.google.com/search?q=<span class="variable">$s</span>&quot;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      name:<span class="string">&quot;必 应&quot;</span>,</span><br><span class="line">      template:<span class="string">&quot;https://www.bing.com/search?q=<span class="variable">$s</span>&quot;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      name:<span class="string">&quot;搜 狗&quot;</span>,</span><br><span class="line">      template:<span class="string">&quot;https://www.sogou.com/web?query=<span class="variable">$s</span>&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">  ],</span><br><span class="line">  selling_ads: <span class="literal">true</span>,                  //Selling your domain or not.(turning on may be helpful <span class="keyword">for</span> selling this domain by showing some ads.)</span><br><span class="line">  sell_info:&#123;</span><br><span class="line">    domain:<span class="string">&quot;example.com&quot;</span>,</span><br><span class="line">    price:500,                        //domain price</span><br><span class="line">    mon_unit:<span class="string">&quot;yen sign&quot;</span>,              //monetary unit </span><br><span class="line">    contact:[                         //how to contact you</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="built_in">type</span>:<span class="string">&quot;envelope&quot;</span>,               //contact <span class="built_in">type</span> (<span class="string">&quot;weixin&quot;</span>,<span class="string">&quot;qq&quot;</span>,<span class="string">&quot;telegram plane&quot;</span>,<span class="string">&quot;envelope&quot;</span> or <span class="string">&quot;phone&quot;</span>)</span><br><span class="line">        content:<span class="string">&quot;info@example.com&quot;</span></span><br><span class="line">      &#125;</span><br><span class="line">    ]                        </span><br><span class="line">  &#125;,</span><br><span class="line">  lists: [                            //Url list</span><br><span class="line">    &#123;</span><br><span class="line">      name:<span class="string">&quot;技术&quot;</span>,</span><br><span class="line">      icon:<span class="string">&quot;code&quot;</span>,</span><br><span class="line">      list:[</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://oschina.net/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;开源中国&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://v2ex.com&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;V2EX&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://csdn.net/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;CSDN技术社区&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://github.com/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;Github&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">      ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      name:<span class="string">&quot;学习&quot;</span>,</span><br><span class="line">      icon:<span class="string">&quot;graduation cap&quot;</span>,</span><br><span class="line">      list:[</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://w3school.com.cn/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;W3school在线教程&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://runoob.com/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;菜鸟教程&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://segmentfault.com/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;思否社区&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          url:<span class="string">&quot;https://jianshu.com/&quot;</span>,</span><br><span class="line">          name:<span class="string">&quot;简书&quot;</span>,</span><br><span class="line">          desc:<span class="string">&quot;程序员集散地&quot;</span></span><br><span class="line">        &#125;,</span><br><span class="line">      ]</span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br><span class="line">const el = (tag, attrs, content) =&gt; `&lt;<span class="variable">$&#123;tag&#125;</span> <span class="variable">$&#123;attrs.join(&quot; &quot;)&#125;</span>&gt;<span class="variable">$&#123;content&#125;</span>&lt;/<span class="variable">$&#123;tag&#125;</span>&gt;`;</span><br><span class="line"></span><br><span class="line">async <span class="keyword">function</span> handleRequest(request) &#123;</span><br><span class="line">  const init = &#123;</span><br><span class="line">    headers: &#123;</span><br><span class="line">      <span class="string">&#x27;content-type&#x27;</span>: <span class="string">&#x27;text/html;charset=UTF-8&#x27;</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">return</span> new Response(renderHTML(renderIndex(),config.selling_ads? renderSeller() :null), init);</span><br><span class="line">&#125;</span><br><span class="line">addEventListener(<span class="string">&#x27;fetch&#x27;</span>, event =&gt; &#123;</span><br><span class="line">  <span class="built_in">return</span> event.respondWith(handleRequest(event.request))</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">/*通过分析链接 实时获取favicon</span><br><span class="line">* @url 需要分析的Url地址</span><br><span class="line">*/</span><br><span class="line"><span class="keyword">function</span> getFavicon(url)&#123;</span><br><span class="line">  <span class="keyword">if</span>(url.match(/https&#123;0,1&#125;:\/\//))&#123;</span><br><span class="line">    //return <span class="string">&quot;https://ui-avatars.com/api/?bold=true&amp;size=36&amp;background=0D8ABC&amp;color=fff&amp;rounded=true&amp;name=&quot;</span> + url.split(<span class="string">&#x27;//&#x27;</span>)[1];</span><br><span class="line">    <span class="built_in">return</span> <span class="string">&quot;https://www.google.cn/s2/favicons?sz=64&amp;domain_url=&quot;</span> + url;</span><br><span class="line">  &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">    //return <span class="string">&quot;https://ui-avatars.com/api/?bold=true&amp;size=36&amp;background=0D8ABC&amp;color=fff&amp;rounded=true&amp;name=&quot;</span> + url;</span><br><span class="line">    <span class="built_in">return</span> <span class="string">&quot;https://www.google.cn/s2/favicons?sz=64&amp;domain_url=http://&quot;</span> + url;</span><br><span class="line">  &#125; </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** Render Functions</span><br><span class="line"> *  渲染模块函数</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">renderIndex</span></span>()&#123;</span><br><span class="line">  const footer = el(<span class="string">&#x27;footer&#x27;</span>,[],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;footer&quot;&#x27;</span>],<span class="string">&#x27;Powered by&#x27;</span> + el(<span class="string">&#x27;a&#x27;</span>,[<span class="string">&#x27;class=&quot;ui label&quot;&#x27;</span>,<span class="string">&#x27;href=&quot;https://github.com/sleepwood/cf-worker-dir&quot;&#x27;</span>,<span class="string">&#x27;target=&quot;_blank&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[<span class="string">&#x27;class=&quot;github icon&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>) + <span class="string">&#x27;Cf-Worker-Dir&#x27;</span>) + <span class="string">&#x27; &amp;copy; Base on &#x27;</span> + el(<span class="string">&#x27;a&#x27;</span>,[<span class="string">&#x27;class=&quot;ui label&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[<span class="string">&#x27;class=&quot;balance scale icon&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>) + <span class="string">&#x27;MIT License&#x27;</span>)));</span><br><span class="line">  <span class="built_in">return</span> renderHeader() + renderMain() + footer;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">renderHeader</span></span>()&#123;</span><br><span class="line">  const item = (template,name) =&gt; el(<span class="string">&#x27;a&#x27;</span>,[<span class="string">&#x27;class=&quot;item&quot;&#x27;</span>,`data-url=<span class="string">&quot;<span class="variable">$&#123;template&#125;</span>&quot;</span>`],name);</span><br><span class="line"></span><br><span class="line">  var nav = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui large secondary inverted menu&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;item&quot;&#x27;</span>],el(<span class="string">&#x27;p&#x27;</span>,[<span class="string">&#x27;id=&quot;hitokoto&quot;&#x27;</span>],<span class="string">&#x27;条条大路通罗马&#x27;</span>)))</span><br><span class="line">  var title = el(<span class="string">&#x27;h1&#x27;</span>,[<span class="string">&#x27;class=&quot;ui inverted header&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[`class=<span class="string">&quot;<span class="variable">$&#123;config.logo_icon&#125;</span> icon&quot;</span>`],<span class="string">&quot;&quot;</span>) + el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;content&quot;&#x27;</span>],config.title + el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;sub header&quot;&#x27;</span>],config.subtitle)));</span><br><span class="line">  var menu = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;id=&quot;sengine&quot;&#x27;</span>,<span class="string">&#x27;class=&quot;ui bottom attached tabular inverted secondary menu&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;header item&quot;&#x27;</span>],<span class="string">&#x27;&amp;nbsp;&#x27;</span>) + config.search_engine.map((link,key) =&gt;&#123;</span><br><span class="line">    if(key == <span class="number">0</span>)&#123;</span><br><span class="line">      return el(&#x27;a&#x27;,[&#x27;class=&quot;active item&quot;&#x27;,`data-url=&quot;<span class="variable">$&#123;link.template&#125;</span>&quot;`],link.name);</span><br><span class="line">    &#125;else&#123;</span><br><span class="line">      return item(link.template,link.name);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;).join(&quot;&quot;))</span><br><span class="line">  var input = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui left corner labeled right icon fluid large input&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui left corner label&quot;&#x27;</span>],el(<span class="string">&#x27;img&#x27;</span>,[<span class="string">&#x27;id=&quot;search-fav&quot;&#x27;</span>,<span class="string">&#x27;class=&quot;left floated avatar ui image&quot;&#x27;</span>,<span class="string">&#x27;src=&quot;https://www.baidu.com/favicon.ico&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>)) + el(<span class="string">&#x27;input&#x27;</span>,[<span class="string">&#x27;id=&quot;searchinput&quot;&#x27;</span>,<span class="string">&#x27;type=&quot;search&quot;&#x27;</span>,<span class="string">&#x27;placeholder=&quot;搜索你想要知道的……&quot;&#x27;</span>,<span class="string">&#x27;autocomplete=&quot;off&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>) + el(<span class="string">&#x27;i&#x27;</span>,[<span class="string">&#x27;class=&quot;inverted circular search link icon&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>));</span><br><span class="line">  <span class="built_in">return</span> el(<span class="string">&#x27;header&#x27;</span>,[],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;id=&quot;head&quot;&#x27;</span>,<span class="string">&#x27;class=&quot;ui inverted vertical masthead center aligned segment&quot;&#x27;</span>],(config.hitokoto ? el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;id=&quot;nav&quot;&#x27;</span>,<span class="string">&#x27;class=&quot;ui container&quot;&#x27;</span>],nav) : <span class="string">&quot;&quot;</span>) + el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;id=&quot;title&quot;&#x27;</span>,<span class="string">&#x27;class=&quot;ui text container&quot;&#x27;</span>],title + (config.search ? input + menu :<span class="string">&quot;&quot;</span>) + `<span class="variable">$&#123;config.selling_ads ? &#x27;&lt;div&gt;&lt;a id=&quot;menubtn&quot; class=&quot;red ui icon inverted button&quot;&gt;&lt;i class=&quot;heart icon&quot;&gt;&lt;/i&gt; 喜欢此域名 &lt;/a&gt;&lt;/div&gt;&#x27; : &#x27;&#x27;&#125;</span>`)))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">renderMain</span></span>() &#123;</span><br><span class="line">  var main = config.lists.map((item) =&gt; &#123;</span><br><span class="line">    const card = (url,name,desc)=&gt; el(&#x27;a&#x27;,[&#x27;class=&quot;card&quot;&#x27;,`href=<span class="variable">$&#123;url&#125;</span>`,&#x27;target=&quot;_blank&quot;&#x27;],el(&#x27;div&#x27;,[&#x27;class=&quot;content&quot;&#x27;],el(&#x27;img&#x27;,[&#x27;class=&quot;left floated avatar ui image&quot;&#x27;,`src=<span class="variable">$&#123;getFavicon(url)&#125;</span>`],&quot;&quot;) + el(&#x27;div&#x27;,[&#x27;class=&quot;header&quot;&#x27;],name) + el(&#x27;div&#x27;,[&#x27;class=&quot;meta&quot;&#x27;],desc)));</span><br><span class="line">    const divider = el(<span class="string">&#x27;h4&#x27;</span>,[<span class="string">&#x27;class=&quot;ui horizontal divider header&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[`class=<span class="string">&quot;<span class="variable">$&#123;item.icon&#125;</span> icon&quot;</span>`],<span class="string">&quot;&quot;</span>)+item.name);</span><br><span class="line"></span><br><span class="line">    var content = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui four stackable cards&quot;&#x27;</span>],item.list.map((link) =&gt;&#123;</span><br><span class="line">      return card(link.url,link.name,link.desc);</span><br><span class="line">    &#125;).join(&quot;&quot;));</span><br><span class="line"></span><br><span class="line">    <span class="built_in">return</span> el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui basic segment&quot;&#x27;</span>],divider + content);</span><br><span class="line">  &#125;).<span class="built_in">join</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line">  </span><br><span class="line">  <span class="built_in">return</span> el(<span class="string">&#x27;main&#x27;</span>,[],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui container&quot;&#x27;</span>],main));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">renderSeller</span></span>() &#123;</span><br><span class="line">  const item = (<span class="built_in">type</span>,content) =&gt; el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;item&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[`class=<span class="string">&quot;<span class="variable">$&#123;type&#125;</span> icon&quot;</span>`],<span class="string">&quot;&quot;</span>) + el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;content&quot;&#x27;</span>],content));</span><br><span class="line">  var title = el(<span class="string">&#x27;h1&#x27;</span>,[<span class="string">&#x27;class=&quot;ui yellow dividing header&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[<span class="string">&#x27;class=&quot;gem outline icon&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>) + el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;content&quot;&#x27;</span>],config.sell_info.domain + <span class="string">&#x27; 正在出售&#x27;</span>));</span><br><span class="line">  var action = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;actions&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui basic cancel inverted button&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[<span class="string">&#x27;class=&quot;reply icon&quot;&#x27;</span>],<span class="string">&quot;&quot;</span>) + <span class="string">&#x27;返回&#x27;</span>));</span><br><span class="line"></span><br><span class="line">  var contact = config.sell_info.contact.map((list) =&gt; &#123;</span><br><span class="line">    return item(list.type,list.content);</span><br><span class="line">  &#125;).join(&quot;&quot;);</span><br><span class="line">  var column = el(&#x27;div&#x27;,[&#x27;class=&quot;column&quot;&#x27;],el(&#x27;h3&#x27;,[&#x27;class=&quot;ui center aligned icon inverted header&quot;&#x27;],el(&#x27;i&#x27;,[&#x27;class=&quot;circular envelope open outline grey inverted icon&quot;&#x27;],&quot;&quot;) + &#x27;联系我&#x27;) + el(&#x27;div&#x27;,[&#x27;class=&quot;ui relaxed celled large list&quot;&#x27;],contact));</span><br><span class="line">  var price = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;column&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui large yellow statistic&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;value&quot;&#x27;</span>],el(<span class="string">&#x27;i&#x27;</span>,[`class=<span class="string">&quot;<span class="variable">$&#123;config.sell_info.mon_unit&#125;</span> icon&quot;</span>`],<span class="string">&quot;&quot;</span>) + config.sell_info.price)));</span><br><span class="line">  var content = el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;content&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui basic segment&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui two column stackable center aligned grid&quot;&#x27;</span>],el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;ui inverted vertical divider&quot;&#x27;</span>],<span class="string">&#x27;感兴趣？&#x27;</span>) + el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;class=&quot;middle aligned row&quot;&#x27;</span>],price + column))));</span><br><span class="line"></span><br><span class="line">  <span class="built_in">return</span> el(<span class="string">&#x27;div&#x27;</span>,[<span class="string">&#x27;id=&quot;seller&quot;&#x27;</span>,<span class="string">&#x27;class=&quot;ui basic modal&quot;&#x27;</span>],title + content + action);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> renderHTML(index,seller) &#123;</span><br><span class="line">  <span class="built_in">return</span> `&lt;!DOCTYPE html&gt;</span><br><span class="line">  &lt;html lang=<span class="string">&quot;en&quot;</span>&gt;</span><br><span class="line">  &lt;<span class="built_in">head</span>&gt;</span><br><span class="line">      &lt;meta charset=<span class="string">&quot;UTF-8&quot;</span>&gt;</span><br><span class="line">      &lt;meta name=<span class="string">&quot;viewport&quot;</span> content=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span><br><span class="line">      &lt;meta http-equiv=<span class="string">&quot;X-UA-Compatible&quot;</span> content=<span class="string">&quot;ie=edge&quot;</span>&gt;</span><br><span class="line">      &lt;title&gt;<span class="variable">$&#123;config.title&#125;</span> - <span class="variable">$&#123;config.subtitle&#125;</span>&lt;/title&gt;</span><br><span class="line">      &lt;<span class="built_in">link</span> href=<span class="string">&quot;https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.css&quot;</span> rel=<span class="string">&quot;stylesheet&quot;</span>&gt;</span><br><span class="line">      &lt;<span class="built_in">link</span> href=<span class="string">&quot;https://cdn.jsdelivr.net/gh/sleepwood/cf-worker-dir@0.1.1/style.css&quot;</span> rel=<span class="string">&quot;stylesheet&quot;</span>&gt;</span><br><span class="line">      &lt;script src=<span class="string">&quot;https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js&quot;</span>&gt;&lt;/script&gt;</span><br><span class="line">      &lt;script src=<span class="string">&quot;https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.js&quot;</span>&gt;&lt;/script&gt;</span><br><span class="line">  &lt;/head&gt;</span><br><span class="line">  &lt;body&gt;</span><br><span class="line">    <span class="variable">$&#123;index&#125;</span></span><br><span class="line">    <span class="variable">$&#123;config.selling_ads ? seller : &#x27;&#x27;&#125;</span></span><br><span class="line">    &lt;script src=<span class="string">&quot;https://v1.hitokoto.cn/?encode=js&amp;select=%23hitokoto&quot;</span> defer&gt;&lt;/script&gt;</span><br><span class="line">    &lt;script&gt;</span><br><span class="line">      $(<span class="string">&#x27;#sengine a&#x27;</span>).on(<span class="string">&#x27;click&#x27;</span>, <span class="keyword">function</span> (e) &#123;</span><br><span class="line">        $(<span class="string">&#x27;#sengine a.active&#x27;</span>).toggleClass(<span class="string">&#x27;active&#x27;</span>);</span><br><span class="line">        $(e.target).toggleClass(<span class="string">&#x27;active&#x27;</span>);</span><br><span class="line">        $(<span class="string">&#x27;#search-fav&#x27;</span>).attr(<span class="string">&#x27;src&#x27;</span>,$(e.target).data(<span class="string">&#x27;url&#x27;</span>).match(`+/https&#123;0,1&#125;:\/\/\S+\//+`)[0] + <span class="string">&#x27;/favicon.ico&#x27;</span>) ;</span><br><span class="line">      &#125;);</span><br><span class="line">      $(<span class="string">&#x27;.search&#x27;</span>).on(<span class="string">&#x27;click&#x27;</span>, <span class="keyword">function</span> (e) &#123;</span><br><span class="line">          var url = $(<span class="string">&#x27;#sengine a.active&#x27;</span>).data(<span class="string">&#x27;url&#x27;</span>);</span><br><span class="line">          url = url.replace(`+/\<span class="variable">$s</span>/+`,$(<span class="string">&#x27;#searchinput&#x27;</span>).val());</span><br><span class="line">          window.open(url);</span><br><span class="line">      &#125;);</span><br><span class="line">      /* 鼠标聚焦时，回车事件 */</span><br><span class="line">      $(<span class="string">&quot;#searchinput&quot;</span>).<span class="built_in">bind</span>(<span class="string">&quot;keypress&quot;</span>, <span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">          <span class="keyword">if</span> (event.keyCode == 13)&#123;</span><br><span class="line">          // 触发需要调用的方法</span><br><span class="line">          $(<span class="string">&quot;.search&quot;</span>).click();</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">      $(<span class="string">&#x27;#menubtn&#x27;</span>).on(<span class="string">&#x27;click&#x27;</span>, <span class="keyword">function</span> (e) &#123;</span><br><span class="line">          $(<span class="string">&#x27;#seller&#x27;</span>).modal(<span class="string">&#x27;show&#x27;</span>);</span><br><span class="line">      &#125;);</span><br><span class="line">    &lt;/script&gt;</span><br><span class="line">  &lt;/body&gt;</span><br><span class="line"></span><br><span class="line">  &lt;/html&gt;`</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="3-找到代码中的函数getFavicon，使用下面的代码进行替换，保证能够正常显示导航站里面的网站图标"><a href="#3-找到代码中的函数getFavicon，使用下面的代码进行替换，保证能够正常显示导航站里面的网站图标" class="headerlink" title="(3)找到代码中的函数getFavicon，使用下面的代码进行替换，保证能够正常显示导航站里面的网站图标"></a>(3)找到代码中的函数getFavicon，使用下面的代码进行替换，保证能够正常显示导航站里面的网站图标</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> getFavicon(url) &#123;</span><br><span class="line">  const domain = url.replace(/^https?:\/\//, <span class="string">&#x27;&#x27;</span>).<span class="built_in">split</span>(<span class="string">&#x27;/&#x27;</span>)[0];</span><br><span class="line">  <span class="built_in">return</span> `https://icons.duckduckgo.com/ip3/<span class="variable">$&#123;domain&#125;</span>.ico`;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="自定义设置"><a href="#自定义设置" class="headerlink" title="自定义设置"></a>自定义设置</h3><p>config里面自己改，有注释</p><h3 id="自定义域绑定（非必须）"><a href="#自定义域绑定（非必须）" class="headerlink" title="自定义域绑定（非必须）"></a>自定义域绑定（非必须）</h3>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    <category term="技术分享" scheme="http://hexo.banlan.nyc.mn/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    
    
    <category term="导航站" scheme="http://hexo.banlan.nyc.mn/tags/%E5%AF%BC%E8%88%AA%E7%AB%99/"/>
    
  </entry>
  
  <entry>
    <title>Hello-Hexo</title>
    <link href="http://hexo.banlan.nyc.mn/posts/59e5d8b8.html"/>
    <id>http://hexo.banlan.nyc.mn/posts/59e5d8b8.html</id>
    <published>2024-10-06T09:08:56.000Z</published>
    <updated>2025-06-30T12:50:00.000Z</updated>
    
    <content type="html"><![CDATA[<!-- <div class="video-container">[up主专用，视频内嵌代码贴在这]</div><style>.video-container {    position: relative;    width: 100%;    padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */}.video-container iframe {    position: absolute;    top: 0;    left: 0;    width: 100%;    height: 100%;}</style> --><hr><h1 id="Hello-Hexo"><a href="#Hello-Hexo" class="headerlink" title="Hello Hexo!"></a>Hello Hexo!</h1><hr><p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">&quot;My New Post&quot;</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="预览"><a href="#预览" class="headerlink" title="预览"></a>预览</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo cl;hexo s</span><br></pre></td></tr></table></figure><h3 id="推送"><a href="#推送" class="headerlink" title="推送"></a>推送</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo cl; hexo g; hexo d</span><br></pre></td></tr></table></figure><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;!-- &lt;div class=&quot;video-container&quot;&gt;
[up主专用，视频内嵌代码贴在这]
&lt;/div&gt;

&lt;style&gt;
.video-container {
    position: relative;
    width: 100%;
    padding</summary>
      
    
    
    
    
    <category term="Hexo" scheme="http://hexo.banlan.nyc.mn/tags/Hexo/"/>
    
  </entry>
  
</feed>
