<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>啊不都</title>
  
  <subtitle>大道至简，衍化至繁</subtitle>
  <link href="https://oplog.cn/atom.xml" rel="self"/>
  
  <link href="https://oplog.cn/"/>
  <updated>2024-12-31T15:48:40.096Z</updated>
  <id>https://oplog.cn/</id>
  
  <author>
    <name>啊不都</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>2024年终总结|轻舟已过万重山</title>
    <link href="https://oplog.cn/archives/2260.html"/>
    <id>https://oplog.cn/archives/2260.html</id>
    <published>2024-12-31T15:39:16.012Z</published>
    <updated>2024-12-31T15:48:40.096Z</updated>
    
    <content type="html"><![CDATA[<h2 id="关于学业">关于学业</h2><p>2024年的学业水平总体保持稳定，各科成绩都有还算不错的表现。作为一名高中生，我需要将大量时间和精力投入到课业学习中，这也意味着我不得不减少在博客运营和开源项目上的参与度。尽管如此，我仍然在课余时间保持对这些领域的关注和学习，希望在未来能够有更多机会深入参与这些富有创造性的工作。</p><h2 id="关于-Qexo">关于 Qexo</h2><p>2024年，Qexo 新增了以下功能：</p><ul><li>图床支持远程图片删除 - 3.1</li><li>支持手动图片上传 - 3.2</li><li>灯箱图片查看 - 3.3</li><li>新增多语言支持 - 3.4</li><li>完善 Docker 支持 - 3.5</li></ul><p>同时，我修复了大量 Bug，并对性能和安全方面进行了优化。考虑到时间有限，在新的一年里，我会将重点聚焦于提升系统的稳定性和兼容性上。</p><h2 id="关于生活">关于生活</h2><p>虽然2023年我的身体状况不佳，经历了一些健康方面的挑战和困扰，包括频繁的感冒、免疫力下降以及睡眠质量不稳定等问题。这些健康问题给我的日常生活带来了诸多不便，影响了我的学习效率和生活质量。在与家人和医生的共同努力下，我通过调整作息时间、改善饮食习惯和进行适度运动等方式来应对这些挑战。这段经历确实给我带来了一些困扰。</p><p>2024年我尝试了每周进行一定的运动，不仅锻炼了身体，也结交了一群志同道合的朋友。同时也养成了规律运动的良好习惯。不仅在繁忙的学习生活中让我保持活力，还让我学会了在竞技中保持冷静和策略性思考。</p><h2 id="关于目标">关于目标</h2><p>回顾2024年设定的目标，我完成了其中的大部分。特别是在学业方面，我达到了预期的成绩水平。在Qexo项目的开发上，虽然因为学业压力而放缓了节奏，但仍然按计划完成了主要功能的更新。健康习惯的养成也取得了明显的进步，尤其是在坚持运动这一方面。</p><h2 id="关于外出">关于外出</h2><ul><li>北京 - 这应当是我第二次游览首都。这次在一位朋友的带领下游览了清华大学校园，感受到了这所百年学府深厚的文化底蕴和浓郁的学术氛围。</li><li>南京 - 北京之后便是南京。这座六朝古都以其深厚的历史文化底蕴给我留下了难忘的印象。不得不说今年旅游的人流量异常庞大，各个景点都是人山人海，不得不佩服后疫情时代人们对旅游的热情。我主要参观了中山陵和总统府，这两处历史地标让我深入了解了中国近代史上的重要时期，对共和国的国父倍感敬佩。在游览过程中，我不仅感受到了南京作为古都的庄重与典雅，也体会到了这座城市在现代化进程中保持的文化传承。</li><li>安大略省 - 今年夏天我有幸参与了一个多伦多的项目，这次经历让我深入体验了加拿大安大略省的独特魅力。在为期两周的访问中，我不仅参观了多伦多标志性的CN塔这一世界级建筑奇观，还有幸游览了北美最壮观的自然景观之一 - 气势磅礴的尼亚加拉瀑布。瀑布湍急的水流和弥漫的水雾给人留下了难忘的印象，特别是在游船近距离观赏时，更能感受到大自然的震撼力量。这次旅行让我深入体验到了与中国截然不同的文化氛围和生活方式，也让我对这个以多元文化著称的国家产生了浓厚的兴趣。特别是在多伦多市区漫步时，能深切感受到这座城市独特的包容性和现代化气息，来自世界各地的移民和当地人和谐共处的景象给我留下了深刻的印象。城市的规划布局、公共设施的完善程度，以及居民友好开放的态度，都展现出一座国际化大都市的风范。不过不得不说相比国内的社会治安，这里确实存在一些问题，几天时间就&quot;有幸&quot;体会到了一次被黑人小哥零元购的体验（被要求打Uber😂），这让我对国内的安全环境有了新的认识。</li></ul><h2 id="关于未来">关于未来</h2><p>今年的生活让我深刻体会到了&quot;创造力&quot;的重要性。在日常学习和生活中，无论是与朝夕相处的同学交流，还是在旅途中邂逅的形形色色的人们，他们所展现出的独特思维方式和创新能力，都不断提醒着我自己在创造力方面的不足。通过观察和反思，我逐渐意识到，自从步入紧张的高中学业以来，原本活跃的创造思维似乎逐渐变得迟钝，那些曾经源源不断涌现的新想法和灵感也随之减少。这种创造力的衰退不仅体现在解决问题的方式上，也反映在对事物的思考深度和广度上。</p><p>或许我应该在未来的学习和生活中更加注重培养和保持创造力。这不仅意味着要在繁重的课业之余留出时间思考和创新，也包括主动寻找机会参与创意项目，与不同背景的人交流互动，以及尝试新的思维方式和解决问题的角度。通过有意识地锻炼和培养创造力，我希望能重新激发那份曾经充满想象力和创新精神的思维模式。</p><p>总的来说，2024年是一个充满挑战与成长的年份。尽管在学业和健康方面遇到了一些困难，但这些经历都让我变得更加坚韧和成熟。新的一年，希望大家能够越来越好吧！😇</p><p>弹指间， 轻舟已过万重山。</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了作者在2024年的个人发展和生活经历。学业上，尽管投入时间较多，成绩稳定，但因学业缘故，博客运营和开源项目的参与度有所减少。作者在Qexo项目上也有所进展，增加了新功能并优化了性能和安全。在生活方面，作者经历了健康挑战，但在家人和医生的帮助下，通过调整生活习惯和适度运动应对，并养成了规律运动的良好习惯。旅游方面，作者游览了北京、南京和安大略省，感受到了各地的文化底蕴和历史的庄重典雅。大部分2024年的目标已达成，如学业成绩、Qexo项目开发和健康习惯的养成。</summary>
    
    
    
    <category term="其他" scheme="https://oplog.cn/categories/%E5%85%B6%E4%BB%96/"/>
    
    
  </entry>
  
  <entry>
    <title>Icarus调教指北 - 我对主题的修改</title>
    <link href="https://oplog.cn/archives/8962.html"/>
    <id>https://oplog.cn/archives/8962.html</id>
    <published>2022-12-28T13:17:24.000Z</published>
    <updated>2026-03-05T14:15:23.638Z</updated>
    
    <content type="html"><![CDATA[<p>本博客主题基于 <a href="https://github.com/imaegoo/hexo-theme-icarus">imaegoo/hexo-theme-icarus</a> 二次修改，本文章的内容理论上支持4.x以后的官方分支以及 imaegoo 的分支，如果遇到问题请自行调整</p><h2 id="基于原始分支的修改">基于原始分支的修改</h2><h3 id="添加预加载">添加预加载</h3><p><code>themes/icarus/layout/common/scripts.jsx</code>中的 <code>&lt;/Fragment&gt;</code> 前添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&#123;cdn(</span>&#x27;<span class="attr">instant.page</span>&#x27;, &#x27;<span class="attr">5.1.1</span>&#x27;, &#x27;<span class="attr">instantpage.min.js</span>&#x27;)&#125; <span class="attr">type</span>=<span class="string">&quot;module&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="目录固定">目录固定</h3><p><code>themes/icarus/source/js/main.js</code> 中的 <code>if ($toc.length &gt; 0)</code> 后添加</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$toc.<span class="title function_">addClass</span>(<span class="string">&#x27;column-right is-sticky&#x27;</span>);   <span class="comment">// 如果目录在左侧则改为 column-left</span></span><br></pre></td></tr></table></figure><p>为了防止目录固定之后无法点击到较下方的项目，需要允许目录滚动</p><p>在 <code>themes/icarus/include/style/widget.styl</code> 添加</p><figure class="highlight scss"><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 class="selector-id">#toc</span>  <span class="comment">//目录可滚动</span></span><br><span class="line">    <span class="attribute">max-height</span>: <span class="built_in">calc</span>(<span class="number">100vh</span> - <span class="number">22px</span>)</span><br><span class="line">    overflow-y: scroll</span><br></pre></td></tr></table></figure><h3 id="右侧边栏吸底">右侧边栏吸底</h3><p>此处参考 imaegoo 的左侧边栏吸底，可添加在 <code>themes/icarus/source/js/main.js</code> 末尾；如果右侧边栏有后加载内容（如友链、最近评论）则应加在完成该操作之后</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//右侧边栏吸底(无文章目录时生效)</span></span><br><span class="line"><span class="keyword">var</span> columnRight = $(<span class="string">&#x27;.column-right&#x27;</span>)[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fixRightColumnTop</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// if SBP return</span></span><br><span class="line">    <span class="keyword">if</span> ($(<span class="variable language_">window</span>).<span class="title function_">width</span>() &lt; <span class="number">769</span>) &#123;</span><br><span class="line">        columnRight.<span class="property">style</span>.<span class="property">top</span> = <span class="literal">null</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (columnRight) &#123;</span><br><span class="line">            columnRight.<span class="property">style</span>.<span class="property">top</span> = $(<span class="variable language_">window</span>).<span class="title function_">height</span>() - columnRight.<span class="property">scrollHeight</span> - <span class="number">10</span> + <span class="string">&#x27;px&#x27;</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">                columnRight = $(<span class="string">&#x27;.column-right&#x27;</span>)[<span class="number">0</span>];</span><br><span class="line">                <span class="title function_">fixRightColumnTop</span>();</span><br><span class="line">            &#125;, <span class="number">500</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (!($(<span class="string">&#x27;#toc&#x27;</span>).<span class="property">length</span> &gt; <span class="number">0</span>)) &#123;  <span class="comment">// 无目录</span></span><br><span class="line">    <span class="title function_">fixRightColumnTop</span>();</span><br><span class="line">    $(<span class="variable language_">window</span>).<span class="title function_">resize</span>(fixRightColumnTop);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="H标签美化">H标签美化</h3><p>添加在 <code>themes/icarus/source/css/default.styl</code></p><figure class="highlight scss"><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.content</span> &gt; <span class="selector-tag">h1</span> </span><br><span class="line">    <span class="attribute">padding</span>: <span class="number">0px</span> <span class="number">13px</span>;</span><br><span class="line">    <span class="attribute">border-left</span>: <span class="number">8px</span> solid <span class="number">#ed515191</span></span><br><span class="line">.content &gt; h2 </span><br><span class="line">    padding:<span class="number">0px</span> <span class="number">12px</span>;</span><br><span class="line">    <span class="attribute">border-left</span>: <span class="number">7px</span> solid <span class="number">#BF51ED91</span></span><br><span class="line">.content &gt; h3 </span><br><span class="line">    padding:<span class="number">0px</span> <span class="number">11px</span>;</span><br><span class="line">    <span class="attribute">border-left</span>: <span class="number">6px</span> solid <span class="number">#6495ed91</span></span><br><span class="line">.content &gt; h4 </span><br><span class="line">    padding:<span class="number">0px</span> <span class="number">10px</span>;</span><br><span class="line">    <span class="attribute">border-left</span>: <span class="number">5px</span> solid <span class="number">#e2aa2b91</span></span><br><span class="line">.content &gt; h5 </span><br><span class="line">    padding:<span class="number">0</span> <span class="number">19px</span>;</span><br><span class="line">    <span class="attribute">border-left</span>: <span class="number">4px</span> solid <span class="number">#64c1c191</span></span><br></pre></td></tr></table></figure><h3 id="图片懒加载">图片懒加载</h3><p>安装并配置 <code>hexo-image-lazyload</code>插件</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">npm install hexo-lazyload-image --save</span></span><br></pre></td></tr></table></figure><figure class="highlight yaml"><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"><span class="attr">lazyload:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">onlypost:</span> <span class="literal">false</span> <span class="comment"># optional</span></span><br><span class="line">  <span class="attr">loadingImg:</span> <span class="comment"># optional eg ./images/loading.gif</span></span><br><span class="line">  <span class="attr">isSPA:</span> <span class="literal">false</span> <span class="comment"># optional</span></span><br><span class="line">  <span class="attr">preloadRatio:</span> <span class="number">3</span> <span class="comment"># optional, default is 1</span></span><br></pre></td></tr></table></figure><p><code>themes/icarus/source/js/main.js</code> 添加代码以修复 <code>lightGallery</code> 兼容</p><figure class="highlight js"><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="comment">// 懒加载修复</span></span><br><span class="line">    $(<span class="variable language_">document</span>).<span class="title function_">find</span>(<span class="string">&#x27;img[data-original]&#x27;</span>).<span class="title function_">each</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        $(<span class="variable language_">this</span>).<span class="title function_">parent</span>().<span class="title function_">attr</span>(<span class="string">&quot;href&quot;</span>, $(<span class="variable language_">this</span>).<span class="title function_">attr</span>(<span class="string">&quot;data-original&quot;</span>));</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure><h3 id="添加置顶文章标签">添加置顶文章标签</h3><p>安装 <code>hexo-generator-index-pin-top</code> 然后为你需要置顶的文章添加 <code>top</code> 字段作为置顶权重</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-index-pin-top --save</span><br></pre></td></tr></table></figure><p><code>themes/icarus/layout/common/article.jsx</code> 中 <code>&lt;div class=&quot;level-left&quot;&gt;</code> 下方添加</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;index &amp;&amp; page.<span class="property">top</span> ? <span class="language-xml"><span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;level-item stick-top&quot;</span>&gt;</span> 置顶 <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span> : <span class="literal">null</span>&#125;</span><br></pre></td></tr></table></figure><p>CSS 添加在 <code>themes/icarus/source/css/default.styl</code></p><figure class="highlight scss"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 置顶标签 */</span></span><br><span class="line"><span class="selector-class">.stick-top</span> &#123;</span><br><span class="line">    <span class="attribute">background-color</span>: <span class="built_in">rgba</span>(<span class="number">64</span>, <span class="number">158</span>, <span class="number">255</span>, <span class="number">0.13</span>);</span><br><span class="line">    <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="built_in">rgba</span>(<span class="number">64</span>, <span class="number">158</span>, <span class="number">255</span>, <span class="number">0.5</span>);</span><br><span class="line">    <span class="attribute">border-radius</span>: <span class="number">2px</span>;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#409eff</span>;</span><br><span class="line">    <span class="attribute">display</span>: inline-block;</span><br><span class="line">    <span class="attribute">padding</span>: <span class="number">0</span> <span class="number">0.5em</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">0.75em</span>;</span><br><span class="line">    <span class="attribute">background-color</span>: <span class="number">#f2f6fc</span>;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>如果你需要黑夜模式的 CSS ，请添加在<code>themes/icarus/source/css/night.styl</code></p><figure class="highlight scss"><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"><span class="comment">/* 黑夜模式置顶标签 */</span></span><br><span class="line"><span class="selector-class">.stick-top</span> &#123;</span><br><span class="line">    <span class="attribute">border</span>: none;</span><br><span class="line">    <span class="attribute">border-radius</span>: <span class="number">2px</span>;</span><br><span class="line">    <span class="attribute">color</span>: dark-font-color;</span><br><span class="line">    <span class="attribute">display</span>: inline-block;</span><br><span class="line">    <span class="attribute">padding</span>: <span class="number">0</span> <span class="number">0.5em</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">0.75em</span>;</span><br><span class="line">    <span class="attribute">background-color</span>: dark-primary-color-hover;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="添加-Qexo-友链侧边栏">添加 Qexo 友链侧边栏</h3><p><code>themes/icarus/include/schema/common/widgets.json</code> 中 <code>items.oneOf</code> 添加</p><figure class="highlight json"><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 class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;$ref&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/widget/qexo_friends.json&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><code>themes/icarus/include/schema/widget/qexo_friends.json</code></p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;$schema&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://json-schema.org/draft-07/schema#&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;$id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/widget/qexo_friends.json&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Qexo friends links widget configurations&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;object&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;string&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;const&quot;</span><span class="punctuation">:</span> <span class="string">&quot;qexo_friends&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;required&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;type&quot;</span><span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><code>themes/icarus/layout/widget/qexo_friends.jsx</code> 注意此处修改 <code>https://yoursite.com</code> 为你的 Qexo 部署地址</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; <span class="variable constant_">URL</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;url&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; <span class="title class_">Component</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;inferno&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; cacheComponent &#125; = <span class="built_in">require</span>(<span class="string">&#x27;hexo-component-inferno/lib/util/cache&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">QexoLinks</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> js = <span class="string">`loadSideBarFriends(&#x27;qexo-sidebar-friends&#x27;, &#x27;https://yoursite.com&#x27;);`</span>;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card widget&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card-content&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;menu&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">h3</span> <span class="attr">class</span>=<span class="string">&quot;menu-label&quot;</span>&gt;</span>友情链接<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">ul</span> <span class="attr">class</span>=<span class="string">&quot;menu-list qexo-sidebar-friends&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">script</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;</span> <span class="attr">__html:</span> <span class="attr">js</span> &#125;&#125;&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">a</span> <span class="attr">class</span>=<span class="string">&quot;link-more button is-light is-small size-small&quot;</span> <span class="attr">href</span>=<span class="string">&quot;/links/&quot;</span>&gt;</span>查看更多<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></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"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="title class_">QexoLinks</span>;</span><br></pre></td></tr></table></figure><p><code>themes/icarus/source/js/sidebar-friends.js</code></p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">loadSideBarFriends</span>(<span class="params">id, url</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> uri = url + <span class="string">&quot;/pub/friends/&quot;</span>;</span><br><span class="line">    <span class="keyword">var</span> loadStyle = <span class="string">&#x27;&lt;div class=&quot;qexo_loading&quot;&gt;&lt;div class=&quot;qexo_part&quot;&gt;&lt;div style=&quot;display: flex; justify-content: center&quot;&gt;&lt;div class=&quot;qexo_loader&quot;&gt;&lt;div class=&quot;qexo_inner one&quot;&gt;&lt;/div&gt;&lt;div class=&quot;qexo_inner two&quot;&gt;&lt;/div&gt;&lt;div class=&quot;qexo_inner three&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center; display: block&quot;&gt;友链加载中...&lt;/p&gt;&lt;/div&gt;&#x27;</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>;i&lt;<span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id).<span class="property">length</span>;i++)&#123;</span><br><span class="line">        <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[i].<span class="property">innerHTML</span> = loadStyle;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[<span class="number">1</span>]</span><br><span class="line">    <span class="keyword">var</span> ajax;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// Firefox, Opera 8.0+, Safari</span></span><br><span class="line">        ajax = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">    &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">        <span class="comment">// Internet Explorer</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            ajax = <span class="keyword">new</span> <span class="title class_">ActiveXObject</span>(<span class="string">&quot;Msxml2.XMLHTTP&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                ajax = <span class="keyword">new</span> <span class="title class_">ActiveXObject</span>(<span class="string">&quot;Microsoft.XMLHTTP&quot;</span>);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">                <span class="title function_">alert</span>(<span class="string">&quot;糟糕,你的浏览器不能上传文件!&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    ajax.<span class="title function_">open</span>(<span class="string">&quot;get&quot;</span>, uri, <span class="literal">true</span>);</span><br><span class="line">    ajax.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>);</span><br><span class="line">    ajax.<span class="property">onreadystatechange</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ajax.<span class="property">readyState</span> == <span class="number">4</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ajax.<span class="property">status</span> == <span class="number">200</span>) &#123;</span><br><span class="line">                <span class="keyword">var</span> res = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(ajax.<span class="property">response</span>);</span><br><span class="line">                <span class="keyword">if</span> (res[<span class="string">&quot;status&quot;</span>]) &#123;</span><br><span class="line">                    <span class="keyword">var</span> friends = res[<span class="string">&quot;data&quot;</span>];</span><br><span class="line">                    <span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>;i&lt;<span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id).<span class="property">length</span>;i++)&#123;</span><br><span class="line">                        <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[i].<span class="property">innerHTML</span> = <span class="string">&#x27;&lt;ul class=&quot;menu-list&quot;&gt;&#x27;</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; friends.<span class="property">length</span>; i++) &#123;</span><br><span class="line">                        <span class="keyword">for</span>(<span class="keyword">let</span> j=<span class="number">0</span>;j&lt;<span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id).<span class="property">length</span>;j++)&#123;</span><br><span class="line">                            <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[j].<span class="property">innerHTML</span> += <span class="string">&#x27;&lt;li&gt;&lt;a class=&quot;level is-mobile is-mobile&quot; href=&quot;&#x27;</span>+friends[i][<span class="string">&quot;url&quot;</span>]+<span class="string">&#x27;&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span class=&quot;level-left&quot;&gt;&lt;span class=&quot;level-item&quot;&gt;&#x27;</span>+friends[i][<span class="string">&quot;name&quot;</span>]+<span class="string">&#x27;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;level-right&quot;&gt;&lt;span class=&quot;level-item tag&quot;&gt;&#x27;</span>+friends[i][<span class="string">&quot;url&quot;</span>].<span class="title function_">split</span>(<span class="string">&#x27;/&#x27;</span>)[<span class="number">2</span>]+<span class="string">&#x27;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#x27;</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">log</span>(res[<span class="string">&quot;data&quot;</span>][<span class="string">&quot;msg&quot;</span>]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;友链获取失败! 网络错误&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    ajax.<span class="title function_">send</span>(<span class="literal">null</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>themes/icarus/layout/common/head.jsx</code> 中 <code>&lt;/head&gt;</code> 前添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;/js/sidebar-friends.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="添加-Qexo-友链申请页面">添加 Qexo 友链申请页面</h3><p>创建一个页面，其中填写</p><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line">&#123;% raw %&#125;</span><br><span class="line"><span class="tag">&lt;<span class="name">article</span> <span class="attr">class</span>=<span class="string">&quot;message is-info&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;message-header&quot;</span>&gt;</span></span><br><span class="line">        申请友链</span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;message-body&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;form-ask-friend&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>名称<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;您的站点名&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-name&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-signature&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>链接<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;url&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;您网站首页的链接&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-link&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-link&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;help &quot;</span>&gt;</span>请确保站点可访问！<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>图标<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;url&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;您的网站图标(尽量为正圆形)&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-icon&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-image&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>描述<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;请用一句话介绍您的站点&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-des&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-info&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;checkbox&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-check&quot;</span>/&gt;</span> 我提交的不是无意义信息</span><br><span class="line">                    <span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field is-grouped&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">button</span> <span class="attr">class</span>=<span class="string">&quot;button is-info&quot;</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;askFriend(event)&quot;</span>&gt;</span>申请友链<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">article</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://recaptcha.net/recaptcha/api.js?render=你的reCpatchaV3密钥&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="keyword">function</span> <span class="title function_">TestUrl</span>(<span class="params">url</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> <span class="title class_">Expression</span>=<span class="regexp">/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&amp;=]*)?/</span>;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> objExp=<span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="title class_">Expression</span>);</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span>(objExp.<span class="title function_">test</span>(url) != <span class="literal">true</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span> <span class="literal">false</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">return</span> <span class="literal">true</span>;</span></span><br><span class="line"><span class="language-javascript">&#125;</span></span><br><span class="line"><span class="language-javascript"><span class="keyword">function</span> <span class="title function_">askFriend</span> (<span class="params">event</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> check = $(<span class="string">&quot;#friend-check&quot;</span>).<span class="title function_">is</span>(<span class="string">&quot;:checked&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> name = $(<span class="string">&quot;#friend-name&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> url = $(<span class="string">&quot;#friend-link&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> image = $(<span class="string">&quot;#friend-icon&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> des = $(<span class="string">&quot;#friend-des&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span>(!check)&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;请勾选\&quot;我提交的不是无意义信息\&quot;&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span>(!(name&amp;&amp;url&amp;&amp;image&amp;&amp;des))&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;信息填写不完整! &quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span> (!(<span class="title class_">TestUrl</span>(url)))&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;URL格式错误! 需要包含HTTP协议头! &quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span> (!(<span class="title class_">TestUrl</span>(image)))&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;图片URL格式错误! 需要包含HTTP协议头! &quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    event.<span class="property">target</span>.<span class="property">classList</span>.<span class="title function_">add</span>(<span class="string">&#x27;is-loading&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">    grecaptcha.<span class="title function_">ready</span>(<span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">          grecaptcha.<span class="title function_">execute</span>(<span class="string">&#x27;你的reCpatchaV3密钥&#x27;</span>, &#123;<span class="attr">action</span>: <span class="string">&#x27;submit&#x27;</span>&#125;).<span class="title function_">then</span>(<span class="keyword">function</span>(<span class="params">token</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">              $.<span class="title function_">ajax</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">type</span>: <span class="string">&#x27;get&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">cache</span>: <span class="literal">false</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">url</span>: url,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">dataType</span>: <span class="string">&quot;jsonp&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">async</span>: <span class="literal">false</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">processData</span>: <span class="literal">false</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="comment">//timeout:10000, </span></span></span><br><span class="line"><span class="language-javascript">                <span class="attr">complete</span>: <span class="keyword">function</span> (<span class="params">data</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">                    <span class="keyword">if</span>(data.<span class="property">status</span>==<span class="number">200</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">                    $.<span class="title function_">ajax</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">type</span>: <span class="string">&#x27;POST&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">dataType</span>: <span class="string">&quot;json&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;name&quot;</span>: name,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;url&quot;</span>: url,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;image&quot;</span>: image,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;description&quot;</span>: des,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;verify&quot;</span>: token,</span></span><br><span class="line"><span class="language-javascript">                        &#125;,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">url</span>: <span class="string">&#x27;https://你的Qexo部署站点/pub/ask_friend/&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">success</span>: <span class="keyword">function</span> (<span class="params">data</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">                            <span class="title function_">alert</span>(data.<span class="property">msg</span>);</span></span><br><span class="line"><span class="language-javascript">                        &#125;</span></span><br><span class="line"><span class="language-javascript">                    &#125;);&#125;</span></span><br><span class="line"><span class="language-javascript">                    <span class="keyword">else</span>&#123;</span></span><br><span class="line"><span class="language-javascript">                        <span class="title function_">alert</span>(<span class="string">&quot;URL无法连通!&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">                    &#125;</span></span><br><span class="line"><span class="language-javascript">                    event.<span class="property">target</span>.<span class="property">classList</span>.<span class="title function_">remove</span>(<span class="string">&#x27;is-loading&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">                &#125;</span></span><br><span class="line"><span class="language-javascript">          &#125;);</span></span><br><span class="line"><span class="language-javascript">        &#125;);</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript">&#125;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">&#123;% endraw %&#125;</span><br></pre></td></tr></table></figure><p>会自动验证站点可连通性并提交到 Qexo 后台。注意需要依照提示配置好 reCaptcha V3 和你的 Qexo 站点链接</p><h3 id="接入-Qexo-页面访问统计">接入 Qexo 页面访问统计</h3><p><code>themes/icarus/source/js/statistic.js</code></p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">loadStatistic</span>(<span class="params">e</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> t = e + <span class="string">&quot;/pub/statistic/&quot;</span>;</span><br><span class="line">  </span><br><span class="line">    <span class="keyword">function</span> <span class="title function_">qexoInner</span>(<span class="params">a,b</span>) &#123;<span class="keyword">if</span> (<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(a)) <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(a).<span class="property">innerHTML</span> = b;&#125;</span><br><span class="line">  </span><br><span class="line">    <span class="keyword">function</span> <span class="title function_">qexoFailed</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> j = [<span class="string">&quot;qexo-site-uv&quot;</span>,<span class="string">&quot;qexo-site-pv&quot;</span>,<span class="string">&quot;qexo-page-pv&quot;</span>]</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; j.<span class="property">length</span>; i++) <span class="title function_">qexoInner</span>(j[i],<span class="string">&quot;请求失败&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  </span><br><span class="line">    <span class="title function_">fetch</span>(t, &#123;</span><br><span class="line">        <span class="attr">referrerPolicy</span>: <span class="string">&quot;no-referrer-when-downgrade&quot;</span></span><br><span class="line">    &#125;).<span class="title function_">then</span>(<span class="keyword">function</span> (<span class="params">res</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (res.<span class="property">ok</span>) &#123;</span><br><span class="line">            res.<span class="title function_">json</span>().<span class="title function_">then</span>(<span class="keyword">function</span> (<span class="params">e</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (e.<span class="property">status</span>) &#123;</span><br><span class="line">                    <span class="title function_">qexoInner</span>(<span class="string">&quot;qexo-site-uv&quot;</span>, e.<span class="property">site_uv</span>);</span><br><span class="line">                    <span class="title function_">qexoInner</span>(<span class="string">&quot;qexo-site-pv&quot;</span>, e.<span class="property">site_pv</span>);</span><br><span class="line">                    <span class="title function_">qexoInner</span>(<span class="string">&quot;qexo-page-pv&quot;</span>, e.<span class="property">page_pv</span>);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">log</span>(e.<span class="property">error</span>);</span><br><span class="line">                    <span class="title function_">qexoFailed</span>()</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="title function_">qexoFailed</span>()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;, <span class="keyword">function</span> (<span class="params">ex</span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;站点统计失败! 网络错误&#x27;</span>)</span><br><span class="line">        <span class="title function_">qexoFailed</span>()</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>themes/icarus/layout/common/footer.jsx</code> 你需要的位置添加</p><figure class="highlight html"><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="tag">&lt;<span class="name">span</span> <span class="attr">id</span>=<span class="string">&quot;busuanzi_container_site_uv&quot;</span> <span class="attr">style</span>=<span class="string">&quot;display: inline;&quot;</span>&gt;</span>共<span class="tag">&lt;<span class="name">span</span> <span class="attr">id</span>=<span class="string">&quot;qexo-site-uv&quot;</span>&gt;</span> Loading <span class="tag">&lt;/<span class="name">span</span>&gt;</span>个访客<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;</span> <span class="attr">__html:</span> &#x27;&lt;<span class="attr">script</span> <span class="attr">src</span>=<span class="string">&quot;/js/statistic.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"><span class="title function_">loadStatistic</span>(<span class="string">&quot;https://my.oplog.cn&quot;</span>)</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span>&#x27;&#125;&#125; /&gt;</span><br></pre></td></tr></table></figure><p><code>themes/icarus/layout/common/article.jsx</code> 中 <code>&#123;/* Visitor counter */&#125;</code> 下方三行改为</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;!index ? <span class="language-xml"><span class="tag">&lt;<span class="name">span</span> <span class="attr">id</span>=<span class="string">&#123;url_for(page.link</span> || <span class="attr">page.path</span>)&#125; <span class="attr">class</span>=<span class="string">&quot;level-item leancloud_visitors&quot;</span> <span class="attr">data-flag-title</span>=<span class="string">&#123;page.title&#125;</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;__html:</span> &#x27;&lt;<span class="attr">i</span> <span class="attr">class</span>=<span class="string">&quot;far fa-eye&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span>&#x27; + _p(&#x27;plugin.visit_count&#x27;, &#x27;  <span class="tag">&lt;<span class="name">span</span> <span class="attr">id</span>=<span class="string">&quot;qexo-page-pv&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fa fa-spinner fa-spin&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span>&#x27;)&#125;&#125;&gt;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span> : <span class="literal">null</span>&#125;</span><br></pre></td></tr></table></figure><h3 id="添加-Qexo-说说侧边栏">添加 Qexo 说说侧边栏</h3><p><code>themes/icarus/include/schema/common/widgets.json</code> 中 <code>items.oneOf</code> 添加</p><figure class="highlight json"><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 class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;$ref&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/widget/qexo_talks.json&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><code>themes/icarus/include/schema/widget/qexo_talks.json</code></p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;$schema&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://json-schema.org/draft-07/schema#&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;$id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/widget/qexo_talks.json&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Qexo talks widget configurations&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;object&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;string&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;const&quot;</span><span class="punctuation">:</span> <span class="string">&quot;qexo_talks&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;required&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;type&quot;</span><span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><code>themes/icarus/layout/widget/qexo_talks.jsx</code> 注意此处修改 <code>https://yoursite.com</code> 为你的 Qexo 部署地址</p><figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; <span class="variable constant_">URL</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;url&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; <span class="title class_">Component</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;inferno&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; cacheComponent &#125; = <span class="built_in">require</span>(<span class="string">&#x27;hexo-component-inferno/lib/util/cache&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">QexoTalks</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> js = <span class="string">`loadSideBarTalks(&#x27;qexo-sidebar-talks&#x27;, &#x27;https://yoursite.com&#x27;, 5);`</span>;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card widget&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card-content&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;menu&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">h3</span> <span class="attr">class</span>=<span class="string">&quot;menu-label&quot;</span>&gt;</span>最近说说<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">ul</span> <span class="attr">class</span>=<span class="string">&quot;menu-list qexo-sidebar-talks&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">script</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;</span> <span class="attr">__html:</span> <span class="attr">js</span> &#125;&#125;&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">a</span> <span class="attr">class</span>=<span class="string">&quot;link-more button is-light is-small size-small&quot;</span> <span class="attr">href</span>=<span class="string">&quot;/talks/&quot;</span>&gt;</span>查看更多<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></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"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="title class_">QexoTalks</span>;</span><br></pre></td></tr></table></figure><p><code>themes/icarus/source/js/sidebar-friends.js</code></p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">loadSideBarTalks</span>(<span class="params">id, url, limit</span>) &#123; <span class="comment">//id=class name</span></span><br><span class="line">    <span class="keyword">var</span> uri = url + <span class="string">&quot;/pub/talks/?page=1&amp;limit=&quot;</span> + limit;</span><br><span class="line">    <span class="keyword">var</span> loadStyle = <span class="string">&#x27;&lt;div class=&quot;qexo_loading&quot;&gt;&lt;div class=&quot;qexo_part&quot;&gt;&lt;div style=&quot;display: flex; justify-content: center&quot;&gt;&lt;div class=&quot;qexo_loader&quot;&gt;&lt;div class=&quot;qexo_inner one&quot;&gt;&lt;/div&gt;&lt;div class=&quot;qexo_inner two&quot;&gt;&lt;/div&gt;&lt;div class=&quot;qexo_inner three&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center; display: block&quot;&gt;说说加载中...&lt;/p&gt;&lt;/div&gt;&#x27;</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id).<span class="property">length</span>; i++) &#123;</span><br><span class="line">        <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[i].<span class="property">innerHTML</span> = loadStyle;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[<span class="number">1</span>]</span><br><span class="line">    <span class="keyword">var</span> ajax;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// Firefox, Opera 8.0+, Safari</span></span><br><span class="line">        ajax = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">    &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">        <span class="comment">// Internet Explorer</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            ajax = <span class="keyword">new</span> <span class="title class_">ActiveXObject</span>(<span class="string">&quot;Msxml2.XMLHTTP&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                ajax = <span class="keyword">new</span> <span class="title class_">ActiveXObject</span>(<span class="string">&quot;Microsoft.XMLHTTP&quot;</span>);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">                <span class="title function_">alert</span>(<span class="string">&quot;糟糕,你的浏览器不能上传文件!&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    ajax.<span class="title function_">open</span>(<span class="string">&quot;get&quot;</span>, uri, <span class="literal">true</span>);</span><br><span class="line">    ajax.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>);</span><br><span class="line">    ajax.<span class="property">onreadystatechange</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ajax.<span class="property">readyState</span> == <span class="number">4</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ajax.<span class="property">status</span> == <span class="number">200</span>) &#123;</span><br><span class="line">                <span class="keyword">var</span> res = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(ajax.<span class="property">response</span>);</span><br><span class="line">                <span class="keyword">if</span> (res[<span class="string">&quot;status&quot;</span>]) &#123;</span><br><span class="line">                    <span class="keyword">var</span> talks = res[<span class="string">&quot;data&quot;</span>];</span><br><span class="line">                    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id).<span class="property">length</span>; i++) &#123;</span><br><span class="line">                        <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[i].<span class="property">innerHTML</span> = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; talks.<span class="property">length</span>; i++) &#123;</span><br><span class="line">                        <span class="keyword">var</span> item = talks[i];</span><br><span class="line">                        <span class="keyword">var</span> date = <span class="keyword">new</span> <span class="title class_">Date</span>(item.<span class="property">time</span> * <span class="number">1000</span>);</span><br><span class="line">                        <span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="number">0</span>; j &lt; <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id).<span class="property">length</span>; j++) &#123;</span><br><span class="line">                            <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(id)[j].<span class="property">innerHTML</span> +=</span><br><span class="line">                                <span class="string">&#x27;&lt;article class=&quot;media&quot;&gt;&lt;div class=&quot;media-content&quot;&gt;&#x27;</span> +</span><br><span class="line">                                <span class="string">&#x27;&lt;p class=&quot;title&quot;&gt;&lt;a href=&quot;#&#x27;</span> + item.<span class="property">id</span> + <span class="string">&#x27;&quot;&gt;&#x27;</span> + <span class="title function_">changeContent</span>(item.<span class="property">content</span>) + <span class="string">&#x27;&lt;/a&gt;&lt;/p&gt;&#x27;</span> +</span><br><span class="line">                                <span class="string">&#x27;&lt;p class=&quot;date&quot;&gt;&#x27;</span> + item.<span class="property">tags</span>.<span class="title function_">join</span>() + <span class="string">&#x27; / &#x27;</span> + date.<span class="title function_">getFullYear</span>() + <span class="string">&quot;-&quot;</span> +</span><br><span class="line">                                (date.<span class="title function_">getMonth</span>() &lt; <span class="number">9</span> ? <span class="number">0</span> : <span class="string">&quot;&quot;</span>) + (date.<span class="title function_">getMonth</span>() + <span class="number">1</span>) + <span class="string">&quot;-&quot;</span> + date.<span class="title function_">getDate</span>() + <span class="string">&#x27;&lt;/p&gt;&#x27;</span> +</span><br><span class="line">                                <span class="string">&#x27;&lt;/div&gt;&lt;/article&gt;&#x27;</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">log</span>(res[<span class="string">&quot;data&quot;</span>][<span class="string">&quot;msg&quot;</span>]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;友链获取失败! 网络错误&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    ajax.<span class="title function_">send</span>(<span class="literal">null</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 从 butterfly 主题借鉴</span></span><br><span class="line"><span class="comment">// https://github.com/jerryc127/hexo-theme-butterfly/blob/dev/layout/includes/third-party/newest-comments/twikoo-comment.pug</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">changeContent</span>(<span class="params">content</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (content === <span class="string">&#x27;&#x27;</span>) <span class="keyword">return</span> content;</span><br><span class="line">    content = content.<span class="title function_">replace</span>(<span class="regexp">/&lt;[^&gt;]+&gt;/g</span>, <span class="string">&#x27;&#x27;</span>); <span class="comment">// remove html tag</span></span><br><span class="line">    <span class="keyword">if</span> (content.<span class="property">length</span> &gt; <span class="number">150</span>) &#123;</span><br><span class="line">        content = content.<span class="title function_">substring</span>(<span class="number">0</span>, <span class="number">150</span>) + <span class="string">&#x27;...&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> content;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="基于-Imaegoo-分支的修改">基于 Imaegoo 分支的修改</h2><h3 id="跟随系统切换黑夜模式">跟随系统切换黑夜模式</h3><p><code>themes/icarus/source/js/imaegoo/night.js</code> 中将 <code>isNight &amp;&amp; applyNight(isNight);</code> 注释并在后方添加，请注意本方案较温和，仅在首次访问或访问时进行了模式更改时生效</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ifSysIsNight = <span class="variable language_">window</span>.<span class="title function_">matchMedia</span>(<span class="string">&#x27;(prefers-color-scheme: dark)&#x27;</span>);</span><br><span class="line"><span class="keyword">if</span> (isNight === <span class="literal">null</span>)&#123;</span><br><span class="line">    isNight = ifSysIsNight.<span class="property">matches</span> ? <span class="literal">true</span> : <span class="literal">false</span>;</span><br><span class="line">    <span class="title function_">applyNight</span>(isNight);</span><br><span class="line">    <span class="variable language_">localStorage</span>.<span class="title function_">setItem</span>(<span class="string">&#x27;night&#x27;</span>, isNight);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">    isNight &amp;&amp; <span class="title function_">applyNight</span>(isNight);</span><br><span class="line">&#125;</span><br><span class="line">ifSysIsNight.<span class="property">onchange</span> = <span class="keyword">function</span> (<span class="params">evt</span>) &#123;</span><br><span class="line">    isNight = evt.<span class="property">matches</span> ? <span class="literal">true</span> : <span class="literal">false</span>;</span><br><span class="line">    <span class="title function_">applyNight</span>(isNight);</span><br><span class="line">    <span class="variable language_">localStorage</span>.<span class="title function_">setItem</span>(<span class="string">&#x27;night&#x27;</span>, isNight);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="最后">最后</h2><p>本篇文章修改较为仓促，可能存在疏漏，可以在评论区指出</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何修改一个名为imaegoo/hexo-theme-icarus的博客主题，使其支持目录固定和可滚动、右侧边栏吸底等功能。其中包括添加代码和修改CSS样式等步骤。作者提供了详细的代码和说明，帮助读者完成这些修改。文章还提到了需要自行调整的问题，以及该修改适用的Hexo版本范围。</summary>
    
    
    
    <category term="技术教程" scheme="https://oplog.cn/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/"/>
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="Hexo" scheme="https://oplog.cn/tags/Hexo/"/>
    
    <category term="Icaus" scheme="https://oplog.cn/tags/Icaus/"/>
    
    <category term="Qexo" scheme="https://oplog.cn/tags/Qexo/"/>
    
    <category term="自定义" scheme="https://oplog.cn/tags/%E8%87%AA%E5%AE%9A%E4%B9%89/"/>
    
    <category term="博客" scheme="https://oplog.cn/tags/%E5%8D%9A%E5%AE%A2/"/>
    
    <category term="代码" scheme="https://oplog.cn/tags/%E4%BB%A3%E7%A0%81/"/>
    
    <category term="分享" scheme="https://oplog.cn/tags/%E5%88%86%E4%BA%AB/"/>
    
  </entry>
  
  <entry>
    <title>在代码中重启Django程序</title>
    <link href="https://oplog.cn/archives/31002.html"/>
    <id>https://oplog.cn/archives/31002.html</id>
    <published>2022-12-24T07:31:48.000Z</published>
    <updated>2022-12-24T07:51:23.000Z</updated>
    
    <content type="html"><![CDATA[<p>最近在 Qexo 的编写过程中，遇到了一个问题：</p><p>如何在完成更新后让程序自动重启？</p><p>这个问题困扰了我一段时间，起初使用的是 Django 自带的 AutoReloader，但效果并不佳，经常没有完成文件的完全替换就自动重启，从而导致更新失败。在参考了部分大佬的文章之后，总结出了一个不错的方法。</p><h2 id="关闭自动重载">关闭自动重载</h2><p>既然我们要把程序的重启完全掌握在自己手中，那么必须要提前关闭好程序的自动重载功能，这一点十分简单，只需要稍微修改启动命令即可</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 manage.py runserver --noreload</span><br></pre></td></tr></table></figure><p>只需要加上<code>--noreload</code>参数即可禁用 Django 的 AutoReloader</p><h2 id="添加重载代码">添加重载代码</h2><h3 id="结论">结论</h3><p>先说结论，如果在程序中你需要重载，则需要强制退出子程序并返回“3”作为退出代码，即</p><figure class="highlight python"><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="keyword">import</span> os</span><br><span class="line">os._exit(<span class="number">3</span>)</span><br></pre></td></tr></table></figure><h3 id="这是如何实现的？">这是如何实现的？</h3><p>经过一番搜索之后，我并没有找到哪个大佬给出了完整的方案（也有可能是我搜索能力较弱），于是在结合了<a href="https://zhuanlan.zhihu.com/p/158063245">Django源码分析</a>对于 Reloader 的分析给出了这个解决方案</p><p>我们观察<code>django.utils.autoreload</code>中有关重启的代码，经过筛选后得到：</p><figure class="highlight python"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">restart_with_reloader</span>():</span><br><span class="line">    new_environ = &#123;**os.environ, DJANGO_AUTORELOAD_ENV: <span class="string">&#x27;true&#x27;</span>&#125;</span><br><span class="line">    args = get_child_arguments()</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        p = subprocess.run(args, env=new_environ, close_fds=<span class="literal">False</span>)</span><br><span class="line">        <span class="keyword">if</span> p.returncode != <span class="number">3</span>:</span><br><span class="line">            <span class="keyword">return</span> p.returncode</span><br></pre></td></tr></table></figure><p>发现  Django 的运行逻辑并不是直接使用主进程，而是创建了一个子进程来执行程序代码，而由原本的进程来实现守护</p><p>我们需要重启子线程，就需要让子进程结束，我们观察到如果退出代码不为“3”则结束程序，为“3”则继续运行，重新执行循环来创建子进程，这就是我们需要的</p><p>进程自杀的代码为：</p><figure class="highlight python"><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="keyword">import</span> sys</span><br><span class="line">sys.exit(<span class="number">3</span>)  <span class="comment"># 3为退出代码</span></span><br></pre></td></tr></table></figure><p>但是很遗憾，这个代码中 sys 库会先抛出一个错误，而这个错误会被 Django 捕获而无法退出，所以我们需要一个更加严厉的退出方法</p><figure class="highlight python"><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="keyword">import</span> os</span><br><span class="line">os._exit(<span class="number">3</span>)</span><br></pre></td></tr></table></figure><p>经过尝试，这个代码完美地符合了我们的要求，主程序遇到“3”作为退出代码后重新创建了一个新的进程，完结撒花</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了作者在编写 Qexo 项目过程中遇到的问题：如何在更新完成后让程序自动重启。作者通过关闭程序的自动重载功能来实现手动控制，然后通过代码实现子进程的退出和重新创建来达到重启程序的目的。作者总结出的解决方法可以在 Python 环境中使用。</summary>
    
    
    
    <category term="编程代码" scheme="https://oplog.cn/categories/%E7%BC%96%E7%A8%8B%E4%BB%A3%E7%A0%81/"/>
    
    
    <category term="django" scheme="https://oplog.cn/tags/django/"/>
    
    <category term="源码分析" scheme="https://oplog.cn/tags/%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/"/>
    
  </entry>
  
  <entry>
    <title>为Hexo博客添加友链系统</title>
    <link href="https://oplog.cn/archives/28219.html"/>
    <id>https://oplog.cn/archives/28219.html</id>
    <published>2022-07-06T11:51:08.000Z</published>
    <updated>2022-07-08T13:14:15.000Z</updated>
    
    <content type="html"><![CDATA[<p>这个教程将帮助你在几分钟内利用 Qexo 为博客接入友链系统</p><p><img src="https://s2.loli.net/2024/07/19/NKhuBMOeTqlHYc7.png" alt=""></p><h2 id="须知">须知</h2><p>友链功能要求 Qexo &gt;= 1.5.0 且用户浏览器必须支持文件上传</p><h2 id="添加友链">添加友链</h2><ol><li>在 Qexo 侧边栏找到 <strong>友链</strong> 点击进入</li><li>点击右上角 <strong>新增友链</strong> 输入站点名称、链接等数据 其中链接及图片链接<strong>必须包含http协议头</strong></li><li>点击 <strong>确定</strong> 按键保存友链数据</li></ol><h2 id="接入博客">接入博客</h2><ol><li>在根目录打开命令行 输入命令<strong>创建页面</strong></li></ol><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new page links</span><br></pre></td></tr></table></figure><ol start="2"><li>打开 <strong>source/links/index.md</strong> 修改页面配置</li><li>在页面内引入 Qexo-Friends 将其中的 <strong>${SITE}</strong> 改为你的 Qexo 链接 例如 <strong><a href="https://admin.mysite.com">https://admin.mysite.com</a></strong></li></ol><figure class="highlight html"><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="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;qexo-friends&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">&quot;stylesheet&quot;</span> <span class="attr">href</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/qexo-static@1.1.3/hexo/friends/friends.css&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/qexo-static@1.1.3/hexo/friends/friends.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"><span class="title function_">loadQexoFriends</span>(<span class="string">&quot;qexo-friends&quot;</span>, <span class="string">&quot;$&#123;SITE&#125;&quot;</span>)</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ol start="4"><li>将博客推送至你的 Github 仓库</li></ol><h2 id="主题适配">主题适配</h2><p>我和其他开发者为部分主题提供了进一步的适配，如果你使用的是相同主题，可以尝试配置</p><h3 id="Icarus">Icarus</h3><p>侧边栏: <code>layout\widget\qexo_friends.jsx</code></p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; <span class="variable constant_">URL</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;url&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; <span class="title class_">Component</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;inferno&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; cacheComponent &#125; = <span class="built_in">require</span>(<span class="string">&#x27;hexo-component-inferno/lib/util/cache&#x27;</span>);</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">QexoLinks</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> js = <span class="string">`loadSideBarFriends(&#x27;qexo-sidebar-friends&#x27;, &#x27;https://Qexo域名&#x27;);`</span>;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card widget&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card-content&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;menu&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">h3</span> <span class="attr">class</span>=<span class="string">&quot;menu-label&quot;</span>&gt;</span>友情链接<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">ul</span> <span class="attr">class</span>=<span class="string">&quot;menu-list qexo-sidebar-friends&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">script</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;</span> <span class="attr">__html:</span> <span class="attr">js</span> &#125;&#125;&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">a</span> <span class="attr">class</span>=<span class="string">&quot;link-more button is-light is-small size-small&quot;</span> <span class="attr">href</span>=<span class="string">&quot;/links/&quot;</span>&gt;</span>查看更多<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></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"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="title class_">QexoLinks</span>;</span><br></pre></td></tr></table></figure><p>友链申请页面:</p><p><img src="https://s2.loli.net/2024/07/19/s3YPnv4bjpKSRuW.png" alt=""></p><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">article</span> <span class="attr">class</span>=<span class="string">&quot;message is-info&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;message-header&quot;</span>&gt;</span></span><br><span class="line">        申请友链</span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;message-body&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;form-ask-friend&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>名称<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;您的站点名&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-name&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-signature&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>链接<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;url&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;您网站首页的链接&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-link&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-link&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;help &quot;</span>&gt;</span>请确保站点可访问！<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>图标<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;url&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;您的网站图标(尽量为正圆形)&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-icon&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-image&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>描述<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control has-icons-left&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;input&quot;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;请用一句话介绍您的站点&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-des&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;icon is-small is-left&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fas fa-info&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">&quot;checkbox&quot;</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">id</span>=<span class="string">&quot;friend-check&quot;</span>/&gt;</span> 我提交的不是无意义信息</span><br><span class="line">                    <span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;field is-grouped&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;control&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">button</span> <span class="attr">class</span>=<span class="string">&quot;button is-info&quot;</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;askFriend(event)&quot;</span>&gt;</span>申请友链<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">article</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://recaptcha.net/recaptcha/api.js?render=reCaptcha密钥&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="keyword">function</span> <span class="title function_">TestUrl</span>(<span class="params">url</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> <span class="title class_">Expression</span>=<span class="regexp">/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&amp;=]*)?/</span>;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> objExp=<span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="title class_">Expression</span>);</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span>(objExp.<span class="title function_">test</span>(url) != <span class="literal">true</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span> <span class="literal">false</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">return</span> <span class="literal">true</span>;</span></span><br><span class="line"><span class="language-javascript">&#125;</span></span><br><span class="line"><span class="language-javascript"><span class="keyword">function</span> <span class="title function_">askFriend</span> (<span class="params">event</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> check = $(<span class="string">&quot;#friend-check&quot;</span>).<span class="title function_">is</span>(<span class="string">&quot;:checked&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> name = $(<span class="string">&quot;#friend-name&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> url = $(<span class="string">&quot;#friend-link&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> image = $(<span class="string">&quot;#friend-icon&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> des = $(<span class="string">&quot;#friend-des&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span>(!check)&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;请勾选\&quot;我提交的不是无意义信息\&quot;&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span>(!(name&amp;&amp;url&amp;&amp;image&amp;&amp;des))&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;信息填写不完整! &quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span> (!(<span class="title class_">TestUrl</span>(url)))&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;URL格式错误! 需要包含HTTP协议头! &quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">if</span> (!(<span class="title class_">TestUrl</span>(image)))&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&quot;图片URL格式错误! 需要包含HTTP协议头! &quot;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    event.<span class="property">target</span>.<span class="property">classList</span>.<span class="title function_">add</span>(<span class="string">&#x27;is-loading&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">    grecaptcha.<span class="title function_">ready</span>(<span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">          grecaptcha.<span class="title function_">execute</span>(<span class="string">&#x27;reCaptcha密钥&#x27;</span>, &#123;<span class="attr">action</span>: <span class="string">&#x27;submit&#x27;</span>&#125;).<span class="title function_">then</span>(<span class="keyword">function</span>(<span class="params">token</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">              $.<span class="title function_">ajax</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">type</span>: <span class="string">&#x27;get&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">cache</span>: <span class="literal">false</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">url</span>: url,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">dataType</span>: <span class="string">&quot;jsonp&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">async</span>: <span class="literal">false</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">processData</span>: <span class="literal">false</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="comment">//timeout:10000, </span></span></span><br><span class="line"><span class="language-javascript">                <span class="attr">complete</span>: <span class="keyword">function</span> (<span class="params">data</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">                    <span class="keyword">if</span>(data.<span class="property">status</span>==<span class="number">200</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">                    $.<span class="title function_">ajax</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">type</span>: <span class="string">&#x27;POST&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">dataType</span>: <span class="string">&quot;json&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;name&quot;</span>: name,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;url&quot;</span>: url,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;image&quot;</span>: image,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;description&quot;</span>: des,</span></span><br><span class="line"><span class="language-javascript">                            <span class="string">&quot;verify&quot;</span>: token,</span></span><br><span class="line"><span class="language-javascript">                        &#125;,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">url</span>: <span class="string">&#x27;https://QEXO域名/pub/ask_friend/&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">                        <span class="attr">success</span>: <span class="keyword">function</span> (<span class="params">data</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">                            <span class="title function_">alert</span>(data.<span class="property">msg</span>);</span></span><br><span class="line"><span class="language-javascript">                        &#125;</span></span><br><span class="line"><span class="language-javascript">                    &#125;);&#125;</span></span><br><span class="line"><span class="language-javascript">                    <span class="keyword">else</span>&#123;</span></span><br><span class="line"><span class="language-javascript">                        <span class="title function_">alert</span>(<span class="string">&quot;URL无法连通!&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">                    &#125;</span></span><br><span class="line"><span class="language-javascript">                    event.<span class="property">target</span>.<span class="property">classList</span>.<span class="title function_">remove</span>(<span class="string">&#x27;is-loading&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">                &#125;</span></span><br><span class="line"><span class="language-javascript">          &#125;);</span></span><br><span class="line"><span class="language-javascript">        &#125;);</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript">&#125;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>其他主题可参考 <a href="https://github.com/Qexo/Qexo-Friends">Qexo/Qexo-Friends: 针对各Hexo-Theme的友链适配</a></p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何利用 Qexo 为博客接入友链系统。首先需要满足 Qexo &gt;= 1.5.0 和用户浏览器支持文件上传的要求，然后在 Qexo 侧边栏中添加友链并保存，在博客根目录打开命令行后修改页面配置，再将博客推送至 GitHub 仓库。文章还提供了部分主题的友链适配方法及友链申请页面的代码示例。</summary>
    
    
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="hexo" scheme="https://oplog.cn/tags/hexo/"/>
    
    <category term="qexo" scheme="https://oplog.cn/tags/qexo/"/>
    
    <category term="友情链接" scheme="https://oplog.cn/tags/%E5%8F%8B%E6%83%85%E9%93%BE%E6%8E%A5/"/>
    
  </entry>
  
  <entry>
    <title>Qexo - 全新Hexo在线管理器</title>
    <link href="https://oplog.cn/archives/59651.html"/>
    <id>https://oplog.cn/archives/59651.html</id>
    <published>2021-11-21T14:52:00.000Z</published>
    <updated>2024-07-19T14:12:19.867Z</updated>
    
    <content type="html"><![CDATA[<p><strong>Qexo</strong> 是一个快速、强大、美观的在线 <strong>Hexo 编辑器</strong>。使用 GPL3.0 <strong>开源</strong>协议。支持包括且不限于在 <strong>Vercel</strong> 等平台部署，为您的静态博客添加<strong>动态</strong>的元素<br><img src="https://s2.loli.net/2024/07/19/r1XJPHnYANKbcRl.png" alt=""></p><p>该文章可能不会随版本更新而更新，教程请移步 <a href="https://oplog.cn/qexo">Qexo文档</a></p><h2 id="特色功能">特色功能</h2><ul><li><p><strong>文章管理~全新界面</strong></p><ul><li>2.0版本的 Qexo 重新设计了文章编辑页面，您可以更优雅地进行文章编辑</li><li>支持多种图床上传，上传尽在弹指之间</li></ul></li><li><p><strong>缓存功能~速度至上</strong></p><ul><li>支持将文章、页面、配置索引一键缓存至数据库，保证您的高速访问</li><li>Webhook 全自动清除缓存，时刻保持数据最新</li></ul></li><li><p><strong>麻雀虽小~五脏俱全</strong></p><ul><li>模块化架构</li><li>支持多种 Hexo 托管商 Github、Gitlab、本地</li><li>多种图床协议支持 Github、S3、FTP、远程API</li><li>Markdown 语法 + 多种编辑界面，所见即所得</li><li>通知中心 通知栏 + 红点标记</li><li>多形式推送 Bark、Telegram、Pushdeer、Wechat…</li><li>reCaptcha 防止垃圾信息侵害</li><li>友情链接 前端申请，一键接入</li><li>自动更新 简单方便，保持最新</li><li>自定字段 / 站点统计 / 页面管理 / 配置编辑</li><li>评论通知 / 图片上传 / 标识生成 / API 拓展</li></ul></li></ul><h2 id="快速开始">快速开始</h2><p>Github 开源仓库：<a href="https://github.com/am-abudu/Qexo">https://github.com/am-abudu/Qexo</a><br>Wiki：<a href="https://oplog.cn/qexo">https://oplog.cn/qexo</a></p><h3 id="无服务器部署">无服务器部署</h3><p>本程序支持本地部署或 Vercel+Mysql/PlanetScale，请查看 <a href="https://oplog.cn/qexo/">文档</a> 以了解更多</p><h3 id="常见问题">常见问题</h3><h4 id="什么是-API-密钥">什么是 API 密钥</h4><p>在您完成初始化之后可在设置界面修改/创建 API 密钥，用于 Webhook 中的身份验证。若留空系统会随机生成一个 API 密钥</p><h4 id="为什么我新建的文章没有显示-Qexo-如何保证文件最新">为什么我新建的文章没有显示 | Qexo 如何保证文件最新</h4><p>Qexo 为了加快访问速度引进了缓存机制，你可以在设置清除缓存 &amp; 设置 Webhook自动清除缓存</p><h4 id="Webhook-是什么">Webhook 是什么</h4><p>Qexo 中的 Webhook 指 /api/webhook 用于自动化操作，目前可用于自动清除缓存</p><h4 id="安装后出现-504-Time-out">安装后出现 504 Time out</h4><ol><li>您的数据库没有正确配置或没有允许所有 IP 白名单访问，可在 MongoDB 控制台进行修改，修改完成后<strong>一定要重新部署</strong></li><li>删除并重建数据库，注意区域<strong>一定要选择 AWS / N. Virginia (us-east-1)</strong></li></ol><h4 id="安装-更新后出现-5xx-错误">安装/更新后出现 5xx 错误</h4><p>Qexo 每个 Release 都经过 Dev 分支的测试，一般情况下不会出现较大问题，如果你遇到了500等错误，请尝试以下步骤</p><ol><li>检查数据库配置</li><li>清除浏览器缓存 / 程序缓存</li><li>在 <code>/settings.html</code> 页面检查 Hexo 服务商配置并点击保存</li><li>在 <code>/advanced.html</code> 中点击“修复”按钮</li><li>若无法登录请使用API: <code>/pub/fix?token=(Your API Key)</code></li><li>保留数据库配置的环境变量并重新部署</li><li>重新部署整个程序</li><li>尝试 Dev 分支</li></ol><h4 id="AssertionError-“xxx-object-…-its-id-attribute-is-set-to-None-”">AssertionError(“xxx object … its id attribute is set to None.”)</h4><p>请检查你是否曾使用过0.01或0.1版本，这两个版本有严重问题，请重新创建数据库并部署</p><h4 id="如何创建子目录下的文章">如何创建子目录下的文章</h4><p>在文章名一栏填写 dir/filename 例如您希望创建 source/_posts/about/me.md 则需要输入 about/me</p><h4 id="KeyError-‘XXX’">KeyError: ‘XXX’</h4><p>表示并没有获取到 “XXX” 这个环境变量，请根据表格添加后 Redeploy</p><table><thead><tr><th>名称</th><th>意义</th><th>示例</th></tr></thead><tbody><tr><td>DOMAINS</td><td>你所允许通信的安全域名 注意双引号而且是英文半角</td><td>[“.vercel.app”, “127.0.0.1”, “.yoursite.com”]</td></tr><tr><td>MONGODB_HOST</td><td>MongoDB 数据库连接地址</td><td>mongodb+srv://cluster0.xxxx.mongodb.net</td></tr><tr><td>MONGODB_PORT</td><td>MongoDB 数据库通信端口 默认应填写 27017</td><td>27017</td></tr><tr><td>MONGODB_USER</td><td>MongoDB 数据库用户名</td><td>abudu</td></tr><tr><td>MONGODB_DB</td><td>MongoDB 数据库名</td><td>Cluster0</td></tr><tr><td>MONGODB_PASS</td><td>MongoDB 数据库密码</td><td>JWo0xxxxxxxx</td></tr></tbody></table><h4 id="Github-配置校验错误">Github 配置校验错误</h4><p>如果配置中遇到问题，可以访问 <a href="https://hexoplusplus.cronfly.workers.dev/?step=start">HPP校验助手</a> 自检配置，若确认无误，可检查仓库内是否有已经发布的文章</p><p>注意：Github 仓库一定为您 Hexo <strong>自动化部署</strong>所在的仓库</p><h4 id="Vercel-用量问题">Vercel 用量问题</h4><p>Vercel 的无服务器函数用量对于 Qexo 来说是充裕的，但这依然抵挡不住有心之人的攻击行为，所以要保护好自己后台地址，不过好在 Vercel 不会随意扣费，所以在资源用完之后并不会产生费用，若依然不放心可以考虑部署在自己的服务器上 <a href="https://github.com/am-abudu/Qexo/wiki/%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%83%A8%E7%BD%B2">#服务器部署#</a></p><h4 id="在线更新失败了">在线更新失败了</h4><p>检查高级设置中的 VERCEL_TOKEN 和 PROJECT_ID 是否正确为 Qexo 的部署项目</p><h4 id="其他问题">其他问题</h4><p>如果还有问题，可以发 <a href="https://github.com/am-abudu/Qexo/issues">issue</a> 或加入 <a href="https://jq.qq.com/?_wv=1027&amp;k=rAcnhzqK">HexoPlusPlus交流群</a> 询问</p><h3 id="如何更新">如何更新</h3><h4 id="一键更新">一键更新</h4><ul><li>在 Settings 页完成在线更新相关设置 -&gt; 远程分支可为master(较稳定)/dev(测试版)</li><li>刷新页面 点击“同步更新”</li></ul><h4 id="手动更新">手动更新</h4><ul><li>创建 Pull Request 并拉取 Qexo 主分支源码</li></ul><h2 id="鸣谢">鸣谢</h2><p>Qexo 的诞生离不开这些项目的付出</p><ul><li><a href="https://ace.c9.io/">Ace</a></li><li><a href="https://github.com/creativetimofficial/argon-dashboard-django">Argon-Dashboard-Django</a></li><li><a href="https://getbootstrap.com/">Bootstrap</a></li><li><a href="https://github.com/mouse0270/bootstrap-notify">Bootstrap-Notify</a></li><li><a href="https://github.com/django/django">Django</a></li><li><a href="https://github.com/nesdis/djongo">Djongo</a></li><li><a href="https://github.com/Vanessa219/vditor">Vditor</a></li><li><a href="https://github.com/HexoPlusPlus/HexoPlusPlus">HexoPlusPlus</a></li><li><a href="https://jquery.com/">jQuery</a></li><li><a href="https://github.com/ardnt/vercel-python-wsgi">Vercel-Python-WSGI</a></li><li>…</li></ul>]]></content>
    
    
    <summary type="html">这篇文章介绍了在线 Hexo 编辑器 Qexo，它使用GPL3.0开源协议。Qexo支持在Vercel等平台部署，为静态博客添加动态元素。Qexo具有多种特色功能，例如支持多种图床上传、缓存功能、支持多种Hexo托管商、多种图床协议支持、通知中心等。同时，文章还介绍了如何在Vercel上进行无服务器部署。文章最后还回答了一些常见问题，例如如何保持文件最新、为什么新建的文章没有显示等。</summary>
    
    
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="Hexo" scheme="https://oplog.cn/tags/Hexo/"/>
    
    <category term="Qexo" scheme="https://oplog.cn/tags/Qexo/"/>
    
  </entry>
  
  <entry>
    <title>使用梦牛网为网站接入Cloudflare并自选IP</title>
    <link href="https://oplog.cn/archives/11593.html"/>
    <id>https://oplog.cn/archives/11593.html</id>
    <published>2021-05-19T14:12:20.000Z</published>
    <updated>2022-08-13T04:09:41.000Z</updated>
    
    <content type="html"><![CDATA[<article class="message is-success"><div class="message-body">本文于2022-6-14重新编辑</div></article><article class="message is-danger"><div class="message-body"><p>经博主测试，该方案已失效，请使用SaaS或Page Funtion反代进行自选节点，若需要梦牛邀请码依然可以向我发送邮件</p></div></article><p><em>由于邀请码有限，需要邀请码的朋友可以abudulin@foxmail.com联系我</em></p><p><strong>自选IP并不是官方认可的操作，存在封禁风险，用前三思</strong></p><p>Cloudflare是一家美国的CDN提供商，非常良心的提供免费的<strong>CDN</strong>，但是由于一些不可抗拒因素，国内的访问速度奇慢，于是乎就有了自选IP的玩法，但是近期笨牛网停止服务，所以梦牛网似乎成为了更好的选择</p><h2 id="使用梦牛网接入域名">使用梦牛网接入域名</h2><h3 id="注册梦牛网">注册梦牛网</h3><p>打开<a href="https://mnn.tw/">梦牛网官网mnn.tw</a>，点击登录 -&gt; 立即注册  输入信息和邀请码完成注册</p><h3 id="添加Cloudflare账户">添加Cloudflare账户</h3><p>打开<a href="https://mnn.tw/panel/user/index">管理面板</a>，在左侧导航栏选择Cloudflare管理-&gt;绑定账户进行账户绑定</p><h3 id="添加域名">添加域名</h3><p>打开Cloudflare管理-&gt;添加域名-&gt;Cname/IP接入，输入域名信息后点击立即提交即可</p><h2 id="设置解析">设置解析</h2><p>打开Cloudflare管理-&gt;域名列表，这里就能看到你刚刚添加的域名了，接着点击这个域名，进入管理面板 点击解析，添加你要解析的记录，在DNS管理商解析到Cloudflare给出的CNAME即可</p><h2 id="节点推荐">节点推荐</h2><article class="message is-warning"><div class="message-body"><p>自选IP并不是官方认可的操作，存在封禁风险，用前三思</p></div></article><p><strong>注意：国外线路请务必解析到cloudflare给你的CNAME节点，防止SSL翻车</strong></p><article class="message is-info"><div class="message-header"><p>百度云加速合作节点</p></div><div class="message-body"><p>162.159.208.4-162.159.208.103</p><p>162.159.209.4-162.159.209.103</p><p>162.159.210.4-162.159.210.103</p><p>162.159.211.4-162.159.211.103</p></div></article><p>你可以参考我之前发表的博文<a href="https://oplog.cn/archives/45814.html">Cloudflare自选节点 - 推荐&amp;现成答案</a> 进行自选IP，也可以自行寻找IP</p><h2 id="其他问题">其他问题</h2><ul><li><strong>我的自选节点后SSL失效了</strong></li></ul><p>国外线路请务必解析到cloudflare给你的CNAME节点，不然有几率翻车，重新解析后尝试关闭SSL后重新开启</p><ul><li><strong>Error 1016 Origin DNS error</strong></li></ul><p>回源配置有问题。访问者只能找到 Cloudflare，但是 Cloudflare 找不到IP所对应的网站。请确保回源IP配置正确。</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何使用梦牛网接入Cloudflare的CDN，以及如何自选IP节点来提高国内访问速度。文章中提醒自选IP存在封禁风险，需要谨慎使用，同时还推荐了百度云加速合作节点。需要注意的是要将国外线路解析到Cloudflare给出的CNAME节点，以防止SSL翻车。</summary>
    
    
    
    <category term="实用技巧" scheme="https://oplog.cn/categories/%E5%AE%9E%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
  </entry>
  
  <entry>
    <title>Euserv免费服务器配置IPv4环境+体验</title>
    <link href="https://oplog.cn/archives/1112.html"/>
    <id>https://oplog.cn/archives/1112.html</id>
    <published>2021-04-27T14:25:23.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<p>EUserv 是一家德国主机商，提供专用服务器托管，虚拟专用服务器，云服务，网站托管和域注册服务，还提供了IPv6 Only的免费VPS服务</p><h2 id="VPS配置">VPS配置</h2><ul><li>CPU：1 Core @ 1 GHz</li><li>内存：1 GB</li><li>硬盘：10 GB HDD</li><li>带宽：1 Gbit</li><li>IP    ：1 IPv6</li></ul><h2 id="配置IPv4环境">配置IPv4环境</h2><h3 id="重装系统">重装系统</h3><p>这里建议重装为Debian10系统，方便进行下一步的操作<img src="https://cdn.oplog.cn/img/20210427220735.png" alt=""></p><h3 id="配置DNS64">配置DNS64</h3><p>在配置Warp之前建议先配置DNS64环境，否则进行远程文件获取时可能出现意外</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">nano /etc/resolv.conf</span><br></pre></td></tr></table></figure><p>删除所有nameserver开头的行，改为</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">nameserver 2001:67c:2b0::4</span><br><span class="line">nameserver 2001:67c:2b0::6</span><br></pre></td></tr></table></figure><p>接着你可能需要重启你的VPS更新配置</p><h3 id="配置Cloudflare-Warp">配置Cloudflare Warp</h3><p>在之前的文章中已经讲过<a href="https://oplog.cn/archives/311.html">为IPv4 Only的腾讯云轻量配置IPv6支持</a>这次仅仅是把WGCF的配置从IPv4改为IPv6即可，并没有什么难度</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></pre></td><td class="code"><pre><span class="line"># 更新环境.安装依赖</span><br><span class="line">apt update</span><br><span class="line">apt install curl sudo lsb-release -y</span><br><span class="line"># 安装wireguard</span><br><span class="line">echo &quot;deb http://deb.debian.org/debian $(lsb_release -sc)-backports main&quot;  sudo tee /etc/apt/sources.list.d/backports.list</span><br><span class="line">sudo apt update</span><br><span class="line">sudo apt install net-tools iproute2 openresolv dnsutils -y</span><br><span class="line">sudo apt install wireguard-tools --no-install-recommends</span><br><span class="line">sudo apt install wireguard</span><br><span class="line"># 安装内核</span><br><span class="line">curl -fsSL git.io/wireguard-go.sh  sudo bash</span><br><span class="line"># 安装WGCF</span><br><span class="line">curl -fsSL git.io/wgcf.sh  sudo bash</span><br></pre></td></tr></table></figure><p>接着就到了关键的WGCF配置环节 先注册一下Warp的账户</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">./wgcf register</span><br></pre></td></tr></table></figure><p>若出现这样的界面直接回车即可<a href="https://cdn.oplog.cn/img/20210403230823.png"><img src="https://cdn.oplog.cn/img/20210403230823.png" alt="打破次元壁，腾讯云轻量配置Warp实现IPv6访问插图5" title="打破次元壁，腾讯云轻量配置Warp实现IPv6访问插图5"></a>   然后输入<code>./wgcf generate</code>，检查目录下是否出现名为wgcf-profile.conf的文件，内容大概这样</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></pre></td><td class="code"><pre><span class="line">[Interface]</span><br><span class="line">PrivateKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span><br><span class="line">Address = 172.16.0.2/32</span><br><span class="line">Address = fd01:5ca1:ab1e:8a15:6634:bea7:4f74:47d9/128</span><br><span class="line">DNS = 1.1.1.1</span><br><span class="line">MTU = 1280</span><br><span class="line">[Peer]</span><br><span class="line">PublicKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span><br><span class="line">AllowedIPs = 0.0.0.0/0</span><br><span class="line">AllowedIPs = ::/0</span><br><span class="line">Endpoint = engage.cloudflareclient.com:2408</span><br></pre></td></tr></table></figure><p>输入<code>nano wgcf-profile.conf</code> 修改配置，删除第十行<code>AllowedIPs = ::/0</code> ，第五行DNS改为<code>DNS = 2606:4700:4700::1111</code> ，第十一行为<code>Endpoint = [2606:4700:d0::a29f:c001]:2408</code> ，Ctrl+X保存   接着输入如下代码，运行WGCF并设置开机自启动</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></pre></td><td class="code"><pre><span class="line">sudo cp wgcf-profile.conf /etc/wireguard/wgcf.conf</span><br><span class="line">sudo systemctl start wg-quick@wgcf</span><br><span class="line">sudo systemctl enable wg-quick@wgcf</span><br><span class="line">echo &#x27;precedence  ::ffff:0:0/96   100&#x27;  sudo tee -a /etc/gai.conf</span><br></pre></td></tr></table></figure><h3 id="测试连接">测试连接</h3><p>SSH输入<code>ping baidu.com -4</code> ，若连接正常即为配置成功 <img src="https://cdn.oplog.cn/img/20210427222131.png" alt=""></p><h2 id="体验">体验</h2><p>简单跑了下bench.sh和Lemonbench，大家可以参考一下，可以看出速度还是非常快的 <img src="https://cdn.oplog.cn/img/20210401213214.png" alt=""> LemonBench完整测试报告：<a href="https://paste.ubuntu.com/p/N3gtCFDDYg/">https://paste.ubuntu.com/p/N3gtCFDDYg/</a> <img src="https://cdn.oplog.cn/img/20210427222410.png" alt=""></p><h2 id="参考">参考</h2><p><a href="https://blog.cyfan.top/p/d788bdf3.html">Euserv正确打开优化方式 陈YFの博客(￣▽￣)&quot; (cyfan.top)</a> <a href="https://luotianyi.vc/5252.html">【WGCF】连接CF WARP为服务器添加IPv4/IPv6网络 – Luminous’ Home (luotianyi.vc)</a></p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何在EUserv上配置CloudFlare Warp服务，为服务器添加IPv4/IPv6网络。需要重装为Debian10系统，配置DNS64环境，安装Wireguard，并注册和生成WGCF配置文件。然后修改配置文件和设置开机自启动，最后测试连接和体验。作者还提供了一些参考链接和测试报告。</summary>
    
    
    
    <category term="实用技巧" scheme="https://oplog.cn/categories/%E5%AE%9E%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    <category term="VPS评测" scheme="https://oplog.cn/categories/VPS%E8%AF%84%E6%B5%8B/"/>
    
    <category term="主机评测" scheme="https://oplog.cn/categories/%E4%B8%BB%E6%9C%BA%E8%AF%84%E6%B5%8B/"/>
    
    
  </entry>
  
  <entry>
    <title>如何写一篇VPS测评</title>
    <link href="https://oplog.cn/archives/13783.html"/>
    <id>https://oplog.cn/archives/13783.html</id>
    <published>2021-04-18T14:31:34.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<p>很多博主都想写类似VPS测评的文章，可是苦于没有教程或是快速测试的脚本，这里博主做出对自己理解的总结</p><h2 id="脚本">脚本</h2><h3 id="网络测试">网络测试</h3><p>一台好的VPS，首先需要优秀的网络</p><ol><li><p><strong>Superbench</strong>脚本</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">wget -qO- git.io/superbench.sh  bash</span><br></pre></td></tr></table></figure></li><li><p><strong><a href="http://Bench.sh">Bench.sh</a></strong>脚本</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">wget -qO- bench.sh  bash</span><br></pre></td></tr></table></figure></li><li><p><strong><strong>回程测试脚本</strong></strong></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">wget -qO- git.io/besttrace  bash</span><br></pre></td></tr></table></figure></li><li><p><strong>SuperSpeed</strong>三网测速脚本</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 &lt;(curl -Lso- https://git.io/superspeed)</span><br></pre></td></tr></table></figure></li><li><p><strong>ZBench</strong>增强脚本</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">wget -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/ZBench/master/ZBench-CN.sh &amp;&amp; bash ZBench-CN.sh</span><br></pre></td></tr></table></figure></li><li><p><strong>BestTrace</strong>路由脚本</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">wget https://cdn.ipip.net/17mon/besttrace4linux.zip &amp;&amp; unzip besttrace4linux.zip &amp;&amp; chmod +x ./besttrace</span><br></pre></td></tr></table></figure></li></ol><h3 id="综合测试脚本">综合测试脚本</h3><p>往往一台好的Linux服务器还需要良好的服务器性能基础，于是乎诞生了很多服务器性能测试脚本</p><ol><li><p><strong>LemonBench</strong>脚本</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">wget -qO- http://ilemonra.in/LemonBenchIntl  bash -s fast</span><br></pre></td></tr></table></figure></li><li><p><strong>UnixBench</strong>脚本</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">wget --no-check-certificate https://github.com/teddysun/across/raw/master/unixbench.sh &amp;&amp; sh unixbench.sh</span><br></pre></td></tr></table></figure></li><li><p><strong>VpsTest</strong>合集脚本</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">wget vpstest.cn/it &amp;&amp; sh it</span><br></pre></td></tr></table></figure></li></ol><h2 id="写作">写作</h2><p>在认识了这么多测试脚本之后，终于到了至关重要的写作环节，常见的测评流程如下： <img src="https://cdn.oplog.cn/img/20210418222736.png" alt=""> 如果链接没有AFF会更佳受大众喜爱</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何进行VPS网络测试的方法，包括Superbench脚本、Bench.sh脚本、回程测试脚本、SuperSpeed三网测速脚本以及ZBench增强脚本。这些脚本可帮助博主或用户快速测试VPS的网络性能。作者指出，一个优秀的VPS应该拥有稳定、快速的网络。</summary>
    
    
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    <category term="实用技巧" scheme="https://oplog.cn/categories/%E5%AE%9E%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    <category term="VPS评测" scheme="https://oplog.cn/categories/VPS%E8%AF%84%E6%B5%8B/"/>
    
    
  </entry>
  
  <entry>
    <title>【快讯】国外知名CDN Cloudflare疑拦截部分自选IP节点</title>
    <link href="https://oplog.cn/archives/12586.html"/>
    <id>https://oplog.cn/archives/12586.html</id>
    <published>2021-03-15T14:23:00.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<h1>背景</h1><p>有消息称，国外知名CDN Cloudflare今日疑似拦截自选IP，众所周知，由于一些不可抗因素，Cloudflare在中国大陆访问速度极慢，于是有了一种称为“自选IP”的使用方法，简单概括即为利用Cloudflare的漏洞强制指向负载较低，距大陆较近的IP进行访问的提速，这种行为已经触及到了Cloudflare的利益，于是Cloudflare很可能进行相关漏洞的修复</p><h1>内容</h1><p>经网友发现，使用“优选IP”的部分IP段已经被Cloudflare所拦截，拦截后页面上会提示1043Error的字样，届时网站无法访问<br><img src="https://7.dusays.com/2021/03/15/bae4a394c476e.png" alt=""><br>在国内知名论坛类似的话题一时间也是层出不穷，这也说明了这个问题并非少数，基本可以确认是Cloudflare官方所为<br><img src="https://7.dusays.com/2021/03/15/2942e0964ae23.png" alt=""></p><h1>如何避免？</h1><p>目前看来只有172.64.228.*这个CDN网段段有拦截，不排除是Cloudflare方面小规模测试，以后可能会推广，所以建议各位切换回官方CNAME或DNS使用，防止被拦截影响网站访问及SEO<img src="https://cdn.jsdelivr.net/gh/2x-ercha/twikoo-magic@master/image/bilibili2233/%5B2233%E5%A8%98_%E5%96%9D%E6%B0%B4%5D.png" alt=""></p>]]></content>
    
    
    <summary type="html">这篇文章介绍了Cloudflare可能拦截自选IP的情况。自选IP是一种利用Cloudflare漏洞强制指向速度更快的IP进行访问的方法。然而，这种行为已影响到了Cloudflare的利益，因此Cloudflare可能会对漏洞进行修复。网友发现部分使用“优选IP”的IP段已被拦截，这就导致网站无法访问。建议使用官方CNAME或DNS以避免影响。</summary>
    
    
    
    <category term="新闻资讯" scheme="https://oplog.cn/categories/%E6%96%B0%E9%97%BB%E8%B5%84%E8%AE%AF/"/>
    
    
    <category term="cdn" scheme="https://oplog.cn/tags/cdn/"/>
    
    <category term="cloudflare" scheme="https://oplog.cn/tags/cloudflare/"/>
    
    <category term="免费cdn" scheme="https://oplog.cn/tags/%E5%85%8D%E8%B4%B9cdn/"/>
    
  </entry>
  
  <entry>
    <title>Cloudflare自定义IP节点</title>
    <link href="https://oplog.cn/archives/18409.html"/>
    <id>https://oplog.cn/archives/18409.html</id>
    <published>2020-12-15T14:23:00.000Z</published>
    <updated>2026-03-05T14:15:23.638Z</updated>
    
    <content type="html"><![CDATA[<p><font color="red">经博主测试，该方案已失效，请使用SaaS或Page Funtion反代进行自选节点</font></p><p>Cloudflare是一家美国的CDN提供商，非常良心的提供免费的CDN，但是由于一些不可抗拒因素，国内的访问速度奇慢，所以我们需要用一些特殊的手段来自定义访问节点来提高速度</p><h2 id="使用Cloudflare-Partner接入">使用Cloudflare Partner接入</h2><p>用官方的Cloudflare是没办法CNAME接入的，要升级到biz版本（每月200刀）才能提供，这对于小站长实在是太贵了。。而且没达到我们白嫖的目的，所以我们要用Cloudflare Partner来CNAME接入</p><h2 id="注册-接入笨牛网">注册/接入笨牛网</h2><p>Cloudflare Partner的提供商有很多，这里就以笨牛网为例<br>打开笨牛网官网<a href="http://cdn.bnxb.com">cdn.bnxb.com</a>，点击登录/注册，输入你的cloudflare账户，点击域名管理<br><img src="https://ae01.alicdn.com/kf/He2902bc0e21a48dcb2bd6a6b17f66f6fl.jpg" alt=""><br>这时你会看到你已经官方接入的域名<br><img src="https://gitee.com/code-abudu/blogimage/raw/master/img/20200603131225.png" alt=""><br>点击域名进入管理界面，点击域名资料 - 变更接入 - 接入本站CNAME<br><img src="https://ae01.alicdn.com/kf/H3f0089dc078c4058b0516c44068fe1b2L.jpg" alt=""></p><h2 id="解析设置">解析设置</h2><p>将你的域名NS重新设置回DNS管理商（如DNSPOD，华为云DNS）<br>接着在笨牛网管理界面菜单点击上方的域名解析，添加你要解析的记录，在DNS管理商解析到cloudflare的ip即可<br><img src="https://shop.io.mi-img.com/app/shop/img?id=shop_5ded7a0f8bfb39548091ebda7c496c55.png" alt=""></p><h2 id="节点推荐">节点推荐</h2><p>如果你不想折腾节点，<a href="http://xn--CNAMEcf-hc5k28vstedw8czoyc.oplog.cn">可以直接CNAME到cf.oplog.cn</a>，使用博主选好的节点<br>注意：国外线路请务必解析到cloudflare给你的CNAME节点，防止SSL翻车<br>百度云加速合作节点：<br>162.159.208.4-162.159.208.103<br>162.159.209.4-162.159.209.103<br>162.159.210.4-162.159.210.103<br>162.159.211.4-162.159.211.103<br>电信推荐使用上面的百度云加速节点或者104.22.3.117<br>移动节点推荐使用走香港百度云加速节点198.41.214.162<br>联通可以走104.20.157.0或者上面的百度云加速节点</p><h2 id="其他问题">其他问题</h2><ul><li>我的自选节点后SSL失效了<br>国外线路请务必解析到cloudflare给你的CNAME节点，不然有几率翻车，重新解析后尝试关闭SSL后重新开启</li><li>Error 1016 Origin DNS error<br>回源配置有问题。访问者只能找到 Cloudflare，但是 Cloudflare 找不到IP所对应的网站。请确保回源IP配置正确。</li></ul>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何通过Cloudflare Partner来自定义访问节点并提高速度。文章指出，使用官方的Cloudflare接入是需要升级到biz版本才可提供CNAME接入的，而代替方法是使用Cloudflare Partner。文章以笨牛网为例介绍了如何注册、接入，并进行解析设置。此外，作者推荐了一些节点，并介绍了几种常见问题的解决方法。</summary>
    
    
    
    <category term="技术教程" scheme="https://oplog.cn/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="cdn" scheme="https://oplog.cn/tags/cdn/"/>
    
    <category term="cloudflare" scheme="https://oplog.cn/tags/cloudflare/"/>
    
    <category term="免费cdn" scheme="https://oplog.cn/tags/%E5%85%8D%E8%B4%B9cdn/"/>
    
    <category term="免费" scheme="https://oplog.cn/tags/%E5%85%8D%E8%B4%B9/"/>
    
  </entry>
  
  <entry>
    <title>继Google后知名CDN Cloudflare中国区域出现解析故障</title>
    <link href="https://oplog.cn/archives/1622.html"/>
    <id>https://oplog.cn/archives/1622.html</id>
    <published>2020-12-15T13:52:00.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<p><font color="red">更新：于20201215北京时间22:15，博主测试已经正常</font></p><blockquote><p>几十分钟前，在中国内地访问DNS托管于Cloudflare的网站开始出现解析失败，提示“此网站无法提供安全连接”。<br>包括 Cloudflare 官网在内的网站无法通过中国内地网络直接访问。大部分IP被解析到了位于中国内地的IP上，所有的解析均没有成功。<br>目前，还不清楚这是否为单一的技术故障。截止发稿时，部分地区的解析已经恢复正常，CF未就此发布状态异常警告。<br>——转自VPS信号旗</p></blockquote><h2 id="影响范围">影响范围</h2><p>据悉，此次故障主要影响的是由Cloudflare官方接入或第三方DNS接入的域名，会被强制解析至国内节点导致无法访问<br><img src="https://www.helloimg.com/images/2020/12/15/202012152157580c9c4391a48cdd97.png" alt=""></p><h2 id="官方反应">官方反应</h2><p>对此，官方的反应是<br><img src="https://www.helloimg.com/images/2020/12/15/20201215215146a3ec7e63c555beb6.png" alt=""><br>(翻译：已识别-问题已确定，正在实施修复)<br>也有群友询问了Cloudflare相关客服人员，得到的答复如下<br><img src="https://www.helloimg.com/images/2020/12/15/20201215220544171a3e6a972c9481.png" alt=""><br><img src="https://www.helloimg.com/images/2020/12/15/20201215220701f53c98fdefbe835d.png" alt=""><br>期待Cloudflare方面进一步解决…</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了中国内地访问DNS托管于Cloudflare的网站出现解析失败的情况，并提示“此网站无法提供安全连接”。目前还不清楚这是否为单一的技术故障。有些地区的解析已经恢复正常，Cloudflare官方已经识别了问题并正在实施修复。此次故障主要影响的是由Cloudflare官方接入或第三方DNS接入的域名，会被强制解析至国内节点导致无法访问。</summary>
    
    
    
    <category term="新闻资讯" scheme="https://oplog.cn/categories/%E6%96%B0%E9%97%BB%E8%B5%84%E8%AE%AF/"/>
    
    
    <category term="cdn" scheme="https://oplog.cn/tags/cdn/"/>
    
    <category term="cloudflare" scheme="https://oplog.cn/tags/cloudflare/"/>
    
    <category term="免费cdn" scheme="https://oplog.cn/tags/%E5%85%8D%E8%B4%B9cdn/"/>
    
  </entry>
  
  <entry>
    <title>Cloudflare自选节点 - 推荐&amp;现成答案</title>
    <link href="https://oplog.cn/archives/45814.html"/>
    <id>https://oplog.cn/archives/45814.html</id>
    <published>2020-12-09T22:48:15.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<p>Cloudflare自选节点一直是一个世纪难题，对于这个问题，大佬们纷纷给出了答案，例如扫段工具，API等等，这里做出总结</p><h2 id="有什么问题">有什么问题</h2><ol><li>自己A记录填写的CloudFlare IP并不是永久可用，保不齐哪天你填写的CloudFlare IP被GFW给屏蔽了，那你的网站就歇菜了。</li><li>自己A记录填写的CloudFlare IP并不是能持续稳定，即使是CloufFlare，服务器也有被攻击的时候，这时你的网站打开速度就会很慢，有时可能会出现打不开的情况。</li><li>自己A记录填写的CloudFlare IP并不是对所有人访问速度都快，这一点建站的小伙伴要尤为注意，也许你ping这个Cloudflare IP延迟很低，但是你的站点并不是你一个人访问，你需要的是让国内外每个访问者都能高速访问你的网站。</li><li>普通站长很难去找到CloudFLare对不同运营商（移动、联通、电信）访问速度快的IP。</li></ol><h2 id="使用Github-Action动态自选IP">使用Github Action动态自选IP</h2><p>对于这个问题，<a href="https://hostmonit.com/" title="HostMinit">HostMonit</a>大佬给出了答案，这里引用他的一段话</p><blockquote><p>遇到问题那么就要解决掉，为了解决这些问题，站长不惜重金买了几台国内不同运营商的高带宽高流量VDS，并花了两天时间写了一套程序，在每台VDS上都部署一套程序，用来获取相应运营商连接目前已知的1786880个CloudFlare IP中速度最快的IP，并以接口形式提供出来。之后又花了半天时间写了一个脚本，脚本主要功能是调取接口将连接各运营商速度快的CloudFare IP自动解析到DNS域名服务商处。经过一个多月的使用测试，明显感觉到网站的访问速度和稳定性有所提升。</p></blockquote><p>作者原文：<a href="https://hostmonit.com/cloudflare-select-ip-plus/" title="https://hostmonit.com/cloudflare-select-ip-plus/">https://hostmonit.com/cloudflare-select-ip-plus/</a> <strong>好处</strong>：动态自选节点，可以最大程度优化速度 <strong>弊端</strong>：免费API速度较慢、部署相对麻烦等</p><h2 id="一键脚本扫段">一键脚本扫段</h2><p>脚本下载：<a href="https://wwa.lanzous.com/idg1Kj87nsf" title="https://wwa.lanzous.com/idg1Kj87nsf">https://wwa.lanzous.com/idg1Kj87nsf</a> 具体使用方法见 <strong>使用说明.txt</strong> 即可 <strong>好处</strong>：运行简单，轻松使用，速度可靠 <strong>弊端</strong>：1.静态IP需要经常扫段，否则难以保证速度; 2.难以凑齐三网设备</p><h2 id="关于我">关于我</h2><p>cf.oplog.cn是我的Cloudflare IP方案，已经使用Github Action动态自选IP，如果觉得麻烦也可以CNAME到我这里</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何解决Cloudflare自选节点的难题，包括其存在的问题以及两种解决方案：使用Github Action动态自选IP和一键脚本扫段。前者通过花钱买VDS和写程序实现自动获取和解析连接速度最快的IP，并提供API接口；后者则是通过使用脚本扫段来获取IP，速度可靠但需要经常扫段。作者提供了自己的Cloudflare IP方案cf.oplog.cn，也给出了一些使用方法和注意事项。</summary>
    
    
    
    <category term="实用技巧" scheme="https://oplog.cn/categories/%E5%AE%9E%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
  </entry>
  
  <entry>
    <title>知名静态网站托管Fast.io即将停止免费服务</title>
    <link href="https://oplog.cn/archives/17169.html"/>
    <id>https://oplog.cn/archives/17169.html</id>
    <published>2020-10-14T05:11:51.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="起因">起因</h2><p><a href="http://fast.io" title="Fast.io">Fast.io</a>长期提供免费的静态托管服务，而且由于使用Cloudflare Enterprise访问速度很快，深受网友的喜爱，但是今日博主收到了一封来自Fast.io团队的邮件说明对方即将停止该服务</p><h2 id="邮件内容">邮件内容</h2><p><img src="https://cdn.oplog.cn/img/20201014130334.png" alt="英文版邮件" title="英文版邮件"> <em>英文原文</em> <img src="https://cdn.oplog.cn/img/20201014130444.png" alt="中文（来自谷歌翻译）" title="中文（来自谷歌翻译）"> <em>中文（来自谷歌翻译）</em></p><h2 id="关于迁移">关于迁移</h2><p>关于邮件，Fast.io没有指出确切的原因，博主猜测可能是有部分用户滥用等，至于迁移，可以考虑换到免费的<a href="https://www.vercel.com" title="https://www.vercel.com">vercel.com</a>或者<a href="https://coding.net" title="Coding Pages">Coding Pages</a>、<a href="https://github.com" title="Github Pages">Github Pages</a>其中Vercel有全球Anycast节点，Coding有新加坡及香港节点，较为高速，而Github的国内速度较慢，大家自己选择一下</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了Fast.io即将停止提供免费的静态托管服务的原因，并附上了其团队发送的声明邮件。虽然Fast.io并未明确指出原因，但是有部分用户滥用可能是其中一个因素。文章还提供了一些备选方案，如换到其他免费的静态托管服务如vercel.com、Coding Pages或Github Pages等。Vercel和Coding Pages有较快的访问速度，而Github Pages在国内的速度较慢，读者可以自行选择。</summary>
    
    
    
    <category term="新闻消息" scheme="https://oplog.cn/categories/%E6%96%B0%E9%97%BB%E6%B6%88%E6%81%AF/"/>
    
    
  </entry>
  
  <entry>
    <title>全新无后端评论系统 —— Twikoo</title>
    <link href="https://oplog.cn/archives/65477.html"/>
    <id>https://oplog.cn/archives/65477.html</id>
    <published>2020-09-24T11:49:58.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="简介">简介</h2><p><a href="http://twikoo.js.org" title="Twikoo">Twikoo</a>是一个全新的支持纯静态博客引擎（包括Hexo、Hugo）的无后端评论系统</p><h2 id="快速上手">快速上手</h2><h3 id="环境初始化">环境初始化</h3><p>Twikoo 使用云开发作为评论后台，每个云开发用户均长期享受1个免费的标准型基础版1资源套餐。如果您已经拥有了一个免费版云开发环境，在环境配置符合要求的情况下，Twikoo 理论可以与其他项目共用一个环境。 1.<a href="https://curl.qcloud.com/KnnJtUom" title="注册云开发CloudBase">注册云开发CloudBase</a> 2.进入<a href="https://console.cloud.tencent.com/tcb/" title="云开发控制台">云开发控制台</a>，新建环境，请按个人需要配置环境</p><blockquote><p><strong>提示</strong> 推荐选择计费方式包年包月，套餐版本基础班 1 如果提示“选择部署应用”，请选择“不创建环境”</p></blockquote><p>3.进入环境-登录授权，启用“匿名登录” 4.进入环境-安全配置，将网站域名添加到“WEB安全域名” 5.复制环境Id备用</p><h3 id="环境部署">环境部署</h3><blockquote><p>注意 请确保您已经安装了 Node.js 请将命令、代码中“您的环境id”替换为您自己的环境id 请不要使用 Windows 自带的记事本编辑 envId.txt，否则会部署失败，后续会修复该问题</p></blockquote><p>1.克隆本仓库</p><figure class="highlight shell"><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 clone https://github.com/imaegoo/twikoo.git</span><br><span class="line">cd twikoo</span><br></pre></td></tr></table></figure><blockquote><p>如果您没有安装 Git，也可以从 <a href="https://github.com/imaegoo/twikoo/releases" title="Release">Release</a> 页面下载最新的 Source code</p></blockquote><p>2.安装依赖项</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install # 或 yarn install</span><br></pre></td></tr></table></figure><p>3.设置环境id</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">echo 您的环境id &gt; envId.txt</span><br></pre></td></tr></table></figure><p>4.授权云开发环境</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run login # 或 yarn run login</span><br></pre></td></tr></table></figure><p>5.自动部署</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run deploy # 或 yarn deploy</span><br></pre></td></tr></table></figure><blockquote><p>更新 Twikoo 版本时，请再次执行此命令更新现有的云函数</p></blockquote><h3 id="使用">使用</h3><h4 id="通过-CDN-引入">通过 CDN 引入</h4><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></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;twikoo&quot;&gt;&lt;/div&gt;</span><br><span class="line">&lt;script src=&quot;https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js&quot;&gt;&lt;/script&gt;</span><br><span class="line">&lt;script&gt;twikoo.init(&#123; envId: &#x27;您的环境id&#x27; &#125;)&lt;/script&gt;</span><br></pre></td></tr></table></figure><h4 id="通过-NPM-引入">通过 NPM 引入</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install twikoo # 或 yarn add twikoo</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">&lt;div id=&quot;twikoo&quot;&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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="keyword">import</span> twikoo <span class="keyword">from</span> <span class="string">&#x27;twikoo&#x27;</span> <span class="comment">// 或 const twikoo = require(&#x27;twikoo&#x27;)</span></span><br><span class="line">twikoo.<span class="title function_">init</span>(&#123; <span class="attr">envId</span>: <span class="string">&#x27;您的环境id&#x27;</span> &#125;)</span><br></pre></td></tr></table></figure><p><strong>摘自_<a href="https://twikoo.js.org/quick-start.html" title="Twikoo中文文档">Twikoo中文文档</a>_</strong></p><h2 id="评论测试">评论测试</h2><p>twikoo.init({ envId: ‘blog-comment-6gd38we84e441790’, el: ‘#tcomment’ })</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了一个新的评论系统Twikoo，它支持纯静态博客引擎(Hexo, Hugo)且无需后台，使用云开发作为评论后台。在使用该系统前需要初始化环境(Twikoo)，需要注册云开发(CloudBase)，新建适合个人需求的环境并启用匿名登录和安全配置。还需要克隆本仓库并安装依赖项。</summary>
    
    
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    
  </entry>
  
  <entry>
    <title>解决Wordpress在设置伪静态和HTTPS后出现重定向过多</title>
    <link href="https://oplog.cn/archives/59138.html"/>
    <id>https://oplog.cn/archives/59138.html</id>
    <published>2020-08-28T13:49:22.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="问题引入">问题引入</h2><p>今天在迁移博客至新主机时，由于是Nginx转Apache，需要重新配置伪静态，在配置完成伪静态和SSL后却发现文章页出现重定向过多（无限302）的问题，在网上找了很多资料最终发现是Wordpress的问题，这里做为记录</p><h2 id="如何解决？">如何解决？</h2><p>解决方法有很多，大家可以参考<a href="https://www.chinaz.com/web/2012/0327/242582.shtml" title="https://www.chinaz.com/web/2012/0327/242582.shtml">https://www.chinaz.com/web/2012/0327/242582.shtml</a> 这里就写我使用的，也是最方便的一种，不用修改Wordpress原生代码，在更新后依然可用</p><h2 id="解决方法">解决方法</h2><p>方法很简单，下载<a href="http://wordpress.org/extend/plugins/permalink-fix-disable-canonical-redirects-pack/" title="Permalink Fix &amp; Disable Canonical Redirects Pack">Permalink Fix &amp; Disable Canonical Redirects Pack</a>安装上就成功了，但是问题在于你没有办法直接在Wordpress应用商店里下载插件，因为这个插件实在是太老了，你必须下载插件包手动上传 <a href="https://downloads.wordpress.org/plugin/permalink-fix-disable-canonical-redirects-pack.1.0.5.zip" title="Wordpress官网下载">Wordpress官网下载</a>下载完之后将文件夹放置在./wp-content/plugins目录，在后台启用插件即可</p><h2 id="完成截图">完成截图</h2><p><img src="https://wx2.sbimg.cn/2020/08/28/6LMIe.png" alt=""> 也是非常简单，希望大家能够Ctrl+D收藏一下本站，感谢</p>]]></content>
    
    
    <summary type="html">这篇文章介绍了作者在将博客迁移到新主机时遇到的重定向问题，经过查找发现是Wordpress的问题。作者提供了解决方法之一，即下载并使用Permalink Fix插件，这种方法不需要修改Wordpress原生代码，且在更新后依然可用。</summary>
    
    
    
    <category term="实用技巧" scheme="https://oplog.cn/categories/%E5%AE%9E%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
    
    
  </entry>
  
  <entry>
    <title>关于实现Hexo多端撰写博文的一些思路</title>
    <link href="https://oplog.cn/archives/8251.html"/>
    <id>https://oplog.cn/archives/8251.html</id>
    <published>2020-05-18T22:48:00.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<p>Hexo是一个轻量级的博客框架，但是你就会发现，写博文真是一个令人头痛的事情：不能在多个设备撰写博文，一旦换设备就会极其麻烦，这里就跟大家讲讲我对于这个问题的一些心得。</p><h1>实现原理</h1><p>在上一篇文章我们讲到可以通过Github Actions 自动部署 Hexo 脚本，这篇文章就是基于自动部署实现的，如果你不了解可以看一下那篇文章<a href="https://www.abudu.top/archives/15.html">传送门</a> 既然将博客源代码托管到了Github，就意味着可以使用工具访问这个仓库，进而撰写博文，很巧，我就找到了一个这样的工具：<a href="http://markdown.xiaoshujiang.com">小书匠Markdown编辑器</a></p><h1>实现过程</h1><h2 id="创建Token">创建Token</h2><p>首先要新建一个Github的Token用于连接小书匠和Github，这里就放一张之前的图吧：<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229172348.png" alt=""></p><h2 id="连接小书匠">连接小书匠</h2><p>点击小书匠编辑器左上角的标志，点击绑定，在数据储存里绑定你之前存放源代码的仓库：<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200304193557.png" alt=""></p><h2 id="修改模板">修改模板</h2><p>退出绑定，点击第二个模板，将模板修改成你Hexo的文章模板<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200304194026.png" alt=""></p><h2 id="新建文章">新建文章</h2><p>修改完就可以退出来愉快的写文章了，点击新建，写完文章Ctrl+S保存，记得保存在你的文章目录下哦，Action检测到会自动部署</p><h1>一些题外话</h1><p>不知道百度站长平台是干什么吃的，我十几篇文章都提交上去了，索引量一直还是0，有没有人知道什么回事评论区解答一下<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200304194509.png" alt=""><br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200304194601.png" alt=""></p>]]></content>
    
    
    <summary type="html">这篇文章介绍了使用小书匠Markdown编辑器和Github Actions自动部署Hexo博客源代码的步骤，解决了博客在不同设备上撰写的问题，只需要创建Github Token、绑定储存仓库和修改Hexo文章模板，即可在小书匠编辑器上愉快撰写博文，自动部署到仓库中。作者还提到了自己提交到百度站长平台索引量一直为0的问题。</summary>
    
    
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    
  </entry>
  
  <entry>
    <title>Hexo 自动部署</title>
    <link href="https://oplog.cn/archives/24998.html"/>
    <id>https://oplog.cn/archives/24998.html</id>
    <published>2020-05-18T22:38:00.000Z</published>
    <updated>2022-06-23T13:43:32.000Z</updated>
    
    <content type="html"><![CDATA[<p>对于静态博客来说，Hexo是一款很受欢迎的博客生成器。其拥有数百的主题和插件，方便我们部署和自定义博客内容。然而，很多生成器都有一个跟明显的缺点，当网站的文章越来越多时，生成所需要的时间也越来越久。如果电脑效能差的话，部署时间则会更加的久。 为了解决这个问题，采用自动化部署是一个绝佳的选择。现如今提供自动化部署的平台越来越多。像Travis CI，Github Actions。我们只需要把Hexo的目录推送到GitHub去，相关平台监测到对应的Repositories发佈变化，就会自动去执行编译，并把编译好的内容发布到博客Repositories去。</p><h1>获取Coding Token</h1><p>项目设置 --&gt; 开发者选项 --&gt; 项目令牌<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229171901.png" alt=""><br>权限要给全</p><h1>获取Github Token</h1><p>Personal settings --&gt; Developer settings --&gt; Personal access tokens<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229172348.png" alt=""><br>权限给repo，public repo，token要存好，不然没了只能重新获取</p><h1>创建Actions</h1><p>建立一个私有仓库，上传Hexo源代码<br>在Hexo目录的仓库，点击Actions<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229165620.png" alt=""><br>然后点击Set up a workflow yourself<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229165621.png" alt=""><br>输入以下代码</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></pre></td><td class="code"><pre><span class="line">name: 自动部署 Hexo</span><br><span class="line"></span><br><span class="line">on:</span><br><span class="line">  push:</span><br><span class="line">    branches:</span><br><span class="line">      - master</span><br><span class="line"></span><br><span class="line">jobs:</span><br><span class="line">  build:</span><br><span class="line">    runs-on: ubuntu-latest</span><br><span class="line">    strategy:</span><br><span class="line">      matrix:</span><br><span class="line">        node-version: [10.x]</span><br><span class="line"></span><br><span class="line">    steps:</span><br><span class="line">      - name: 开始运行</span><br><span class="line">        uses: actions/checkout@v1</span><br><span class="line"></span><br><span class="line">      - name: 设置 Node.js $&#123;&#123; matrix.node-version &#125;&#125;</span><br><span class="line">        uses: actions/setup-node@v1</span><br><span class="line">        with:</span><br><span class="line">          node-version: $&#123;&#123; matrix.node-version &#125;&#125;</span><br><span class="line"></span><br><span class="line">      - name: 安装 Hexo CI</span><br><span class="line">        run: </span><br><span class="line">          export TZ=&#x27;Asia/Shanghai&#x27;</span><br><span class="line">          npm install hexo-cli -g</span><br><span class="line"></span><br><span class="line">      - name: 缓存</span><br><span class="line">        uses: actions/cache@v1</span><br><span class="line">        id: cache-dependencies</span><br><span class="line">        with:</span><br><span class="line">          path: node_modules</span><br><span class="line">          key: $&#123;&#123;runner.OS&#125;&#125;-$&#123;&#123;hashFiles(&#x27;**/package-lock.json&#x27;)&#125;&#125;</span><br><span class="line"></span><br><span class="line">      - name: 安装插件</span><br><span class="line">        if: steps.cache-dependencies.outputs.cache-hit != &#x27;true&#x27;</span><br><span class="line">        run: </span><br><span class="line">          npm install</span><br><span class="line"></span><br><span class="line">      - name: 部署博客</span><br><span class="line">        run: </span><br><span class="line">          hexo clean &amp;&amp; hexo g &amp;&amp; hexo douban &amp;&amp; gulp</span><br><span class="line">          cd ./public</span><br><span class="line">          git init</span><br><span class="line">          git config user.name &quot;$&#123;&#123;secrets.GIT_NAME&#125;&#125;&quot;</span><br><span class="line">          git config user.email &quot;$&#123;&#123;secrets.GIT_EMAIL&#125;&#125;&quot;</span><br><span class="line">          git add .</span><br><span class="line">          git commit -m &quot;Update&quot;</span><br><span class="line">          git push --force --quiet &quot;https://$&#123;&#123;secrets.GH_TOKEN&#125;&#125;@$&#123;&#123;secrets.GH_REF&#125;&#125;&quot; master:master</span><br><span class="line">          git push --force --quiet &quot;https://$&#123;&#123;secrets.CD_TOKEN&#125;&#125;@$&#123;&#123;secrets.CD_REF&#125;&#125;&quot; master:master</span><br></pre></td></tr></table></figure><p>点击Start commit<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229165954.png" alt=""></p><h1>设置Secrets</h1><p>为了保护重要的资料，需要把这些资料设置到Secrets里，然后通过$引用。<br>在Settings --&gt; Secrets<br><img src="https://cdn.jsdelivr.net/gh/am-abudu/cdn/images/20200229170358.png" alt=""><br>这里需要设置6个Secrets</p><table><thead><tr><th>名称</th><th>内容</th></tr></thead><tbody><tr><td>CD_REF</td><td>要提交到的Coding仓库地址</td></tr><tr><td>CD_TOKEN</td><td>Coding Token 格式为 用户名:密匙</td></tr><tr><td>GH_REF</td><td>要提交到的 Github 仓库地址</td></tr><tr><td>GH_TOKEN</td><td>Github Token</td></tr><tr><td>GIT_EMAIL</td><td>Git用户邮箱</td></tr><tr><td>GIT_NAME</td><td>Git用户名</td></tr></tbody></table><h1>运行</h1><p>随便修改一个东西，比如提交一篇文章，就可以看到变化了</p><h1>鸣谢</h1><p>1.<a href="http://jerryc.me/posts/74006f42/">通过travis-ci或者GitHub Actions自动化部署GitHub Pages和Coding Pages</a><br>2.<a href="https://eallion.com/github-actions-hexo-ci/">Github Actions 自动部署 Hexo 脚本</a></p>]]></content>
    
    
    <summary type="html">这篇文章介绍了如何解决使用Hexo生成过多内容时所遇到的部署时间变长的问题，即采用自动化部署。作者介绍了自动化部署的优点以及一些现有的平台（如Travis CI，Github Actions）。然后详细介绍了如何使用Github Actions进行自动化部署，在Github设置Token和Actions，以及运行一个自动化部署Hexo的workflow。</summary>
    
    
    
    <category term="建站教程" scheme="https://oplog.cn/categories/%E5%BB%BA%E7%AB%99%E6%95%99%E7%A8%8B/"/>
    
    
  </entry>
  
</feed>
