<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:a="http://www.w3.org/2005/Atom" xmlns:c="http://purl.org/rss/1.0/modules/content/"><channel><title>CC的部落格</title><link>https://blog.ccknbc.cc/</link><description>CC康纳百川</description><language>zh-CN</language><copyright>All rights reserved 2026, CC康纳百川</copyright><lastBuildDate>Mon, 04 May 2026 10:02:26 GMT</lastBuildDate><generator>Hexo</generator><image><url>https://cdn.jsdmirror.com/gh/ccknbc-backup/cdn/logo/CC.png</url><title>CC的部落格</title><link>https://blog.ccknbc.cc/</link></image><a:link href="https://blog.ccknbc.cc/rss.xml" rel="self" type="application/rss+xml"/><item><title>Hexo浏览器定向推送文章更新</title><link>https://blog.ccknbc.cc/posts/hexo-webpushr-notification/</link><description><![CDATA[<font style="color:rgb(38, 38, 38);">这一次，CC的部落格可以根据读者订阅主题定向推送了，并且实现了NPM插件化</font>]]></description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%8D%9A%E5%AE%A2/">博客</category><category domain="https://blog.ccknbc.cc/tags/%E5%8D%9A%E5%AE%A2/">博客</category><category domain="https://blog.ccknbc.cc/tags/%E5%B7%A5%E5%85%B7/">工具</category><pubDate>Fri, 10 Jul 2026 01:27:42 GMT</pubDate><c:encoded><![CDATA[<p>查看本文<a href="https://www.yuque.com/ccknbc/blog/37/"><strong>语雀</strong></a>版本【首发】，自动同步更新至<a href="https://blog.ccknbc.cc/posts/hexo-webpushr-notification/"><strong>CC的部落格</strong></a>！</p><p>两年前，我刚开始使用<code>Hexo</code>的时候，写了一篇文章<a href="https://blog.ccknbc.cc/posts/implementation-of-simple-browser-update-push/">简单浏览器更新推送的实现</a>，最近登录<a href="https://www.webpushr.com/">webpushr</a>控制台，发现其支持按话题<code>topic</code>指定推送了，而原来的插件一直没有更新，且对个人的写作习惯不是很友好，所以对原插件进行了修改，并发布到了<code>NPM</code></p><p>欢迎大家前往<a href="/sub">订阅页面</a>选择合适的订阅方式，关于邮件订阅，现已支持分类订阅</p><h2 id="安装">安装<a class="fa-solid fa-hashtag" href="#安装"></a></h2><p>推荐使用 <code>npm</code> 以插件形式安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i hexo-webpushr-notification</span><br></pre></td></tr></table></figure><h3 id="自定义修改">自定义修改<a class="fa-solid fa-hashtag" href="#自定义修改"></a></h3><p>当然你也可以自定义修改<a href="https://github.com/Rock-Candy-Tea/hexo-webpushr-notification/blob/main/webpushr.js">webpushr.js</a>文件后，再安装相关需要依赖，然后将文件放到<code>Hexo/scripts/</code>目录下即可正常运行，CC本人亦是如此</p><p>对于 0.2.0 以上版本，您只需要在 Hexo 所在目录安装 axios 即可，这样测试相较于安装 GitHub 更方便（以及欢迎 PR ）</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i axios</span><br></pre></td></tr></table></figure><h2 id="使用">使用<a class="fa-solid fa-hashtag" href="#使用"></a></h2><p>在你的 Hexo 根目录配置文件 <code>_config.yml</code>中添加如下内容，可按需配置，建议前往 <a href="https://github.com/Rock-Candy-Tea/hexo-webpushr-notification#readme">README</a> 查看最新配置</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="attr">webpushr:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">webpushrKey:</span> <span class="string">&quot;webpushrKey&quot;</span></span><br><span class="line">  <span class="attr">webpushrAuthToken:</span> <span class="string">&quot;webpushrAuthToken&quot;</span></span><br><span class="line">  <span class="comment"># 出于安全考虑，建议将上述两个重要参数添加至系统全局环境变量，并删除或注释掉此处配置</span></span><br><span class="line">  <span class="comment"># 否则可在网页端向访问者或订阅用户发送推送 https://www.webpushr.com/api-playground</span></span><br><span class="line">  <span class="comment"># 例如GitHub Actions环境变量配置，参数名不变，密钥名自定义，可参考如下</span></span><br><span class="line">  <span class="comment"># env:</span></span><br><span class="line">  <span class="comment">#     webpushrKey: $&#123;&#123; secrets.WEBPUSHR_KEY &#125;&#125;</span></span><br><span class="line">  <span class="comment">#     webpushrAuthToken: $&#123;&#123; secrets.WEBPUSHR_AUTH_TOKEN &#125;&#125;</span></span><br><span class="line">  <span class="comment"># 如果您的仓库私有，则无需担心此问题</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">trackingCode:</span> <span class="string">&quot;trackingCode&quot;</span></span><br><span class="line">  <span class="attr">icon:</span> <span class="string">&quot;https://.../192.png&quot;</span> <span class="comment"># 必须为 HTTPS 以及 192*192 png图片</span></span><br><span class="line">  <span class="comment"># auto_hide: false # 默认为 1，代表true，即自动隐藏</span></span><br><span class="line">  <span class="comment"># sort: &quot;date&quot; # 默认为updated，即只要最新文章更改了更新时间即推送新文章，改为date即文章第一次发布时间</span></span><br><span class="line">  <span class="comment"># delay: &quot;0&quot; # 延时推送，考虑到CDN缓存更新，默认定时为在 hexo d 10分钟后推送，单位为分钟（最短延时为5分钟，设置 0 则会立即推送）</span></span><br><span class="line">  <span class="comment"># expire: &quot;15d&quot; # 推送过期时长，默认值为7天，格式如下：&#x27;5m&#x27;代表5分钟,&#x27;5h&#x27;代表5小时, &#x27;5d&#x27;代表5天.</span></span><br><span class="line">  <span class="comment"># image: # 默认为文章封面，Front-matter 属性为&#x27;cover&#x27;(butterfly主题友好选项)，如果您没有定义默认封面或此属性，请在这里设置默认image</span></span><br><span class="line">  <span class="attr">action_buttons:</span> <span class="comment"># 如果你需要额外自定义按钮 可按照如下格式：</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">title:</span> <span class="string">阅读全文</span> <span class="comment"># 当 title 未配置时 默认值为 “前往查看”</span></span><br><span class="line">      <span class="comment"># url:  # 当 url 未配置时 默认值为 最新文章链接</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">title:</span> <span class="string">订阅页面</span></span><br><span class="line">      <span class="attr">url:</span> <span class="string">https://blog.ccknbc.cc/sub/</span></span><br><span class="line">    <span class="comment"># 当 action_buttons 未定义时也默认保留了一个“前往查看”按钮，除非设置为 false</span></span><br><span class="line">    <span class="comment"># action_buttons: false # 当设为 false 则不显示额外的按钮，因为隐藏按钮即为当前文章链接</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 以下配置为按订阅主题推送给不同订阅用户，请按照数组形式，一一对应，具体位置请看使用文档</span></span><br><span class="line">  <span class="attr">categories:</span> [<span class="string">工作</span>, <span class="string">博客</span>, <span class="string">工具</span>, <span class="string">生活</span>, <span class="string">音乐</span>, <span class="string">学习</span>]</span><br><span class="line">  <span class="attr">segment:</span> [<span class="string">&quot;484223&quot;</span>, <span class="string">&quot;484224&quot;</span>, <span class="string">&quot;484225&quot;</span>, <span class="string">&quot;484226&quot;</span>, <span class="string">&quot;484227&quot;</span>, <span class="string">&quot;484229&quot;</span>]</span><br><span class="line">  <span class="attr">endpoint:</span> <span class="string">segment</span> <span class="comment"># 可选配置 all / segment / sid</span></span><br><span class="line">  <span class="comment"># 默认为 segment，即根据不同主题推送细分，同时配置上述选项</span></span><br><span class="line">  <span class="comment"># 例如 all，即推送至所有用户；针对本地测试，建议只推送给单个用户即自己，同时设置下方的 sid 值</span></span><br><span class="line">  <span class="comment"># 您也可以将segment 设置为 all-users 对应的ID，同样也可以实现推送至所有用户</span></span><br><span class="line">  <span class="attr">sid:</span> <span class="string">&quot;119810055&quot;</span> <span class="comment"># 单个用户ID 可在控制台查看 https://app.webpushr.com/subscribers</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 此外，在文章 Front-Matter 处</span></span><br><span class="line">  <span class="comment"># 可覆盖 auto_hide 和 expire 配置，针对需要特别提醒文章可以设置不自动隐藏及过期时间延长等操作</span></span><br><span class="line">  <span class="comment"># 以及可指定schedule参数（例如：schedule: 2022-10-01 00:00:00），定时推送</span></span><br><span class="line">  <span class="comment"># 当文章头设置 webpushr: false 时，可关闭本篇文章推送，此参数主要防止久远文章更改更新时间后自动推送</span></span><br></pre></td></tr></table></figure><ol><li>前往 webpushr 控制台获取如下参数，注册的时候可能会遇到一点困难，中国大陆用户需要科学上网来加载验证服务）</li><li>关于注册及一些具体内容，可以看之前的文章 <a href="https://blog.ccknbc.cc/posts/implementation-of-simple-browser-update-push/">简单浏览器更新推送的实现</a></li><li>依次点击 <code>Integration</code> &gt; <code>REST API Keys</code>，即可看到你的<code>webpushrKey</code> 及 <code>webpushrAuthToken</code></li><li>依次点击 <code>Setup</code> &gt; <code>TrackingCode</code>，可以看到如下代码</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- start webpushr tracking code --&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript">(<span class="keyword">function</span>(<span class="params">w,d, s, id</span>) &#123;<span class="keyword">if</span>(<span class="title function_">typeof</span>(w.<span class="property">webpushr</span>)!==<span class="string">&#x27;undefined&#x27;</span>) <span class="keyword">return</span>;w.<span class="property">webpushr</span>=w.<span class="property">webpushr</span>||<span class="keyword">function</span>(<span class="params"></span>)&#123;(w.<span class="property">webpushr</span>.<span class="property">q</span>=w.<span class="property">webpushr</span>.<span class="property">q</span>||[]).<span class="title function_">push</span>(<span class="variable language_">arguments</span>)&#125;;<span class="keyword">var</span> js, fjs = d.<span class="title function_">getElementsByTagName</span>(s)[<span class="number">0</span>];js = d.<span class="title function_">createElement</span>(s); js.<span class="property">id</span> = id;js.<span class="property">async</span>=<span class="number">1</span>;js.<span class="property">src</span> = <span class="string">&quot;https://cdn.webpushr.com/app.min.js&quot;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                                 fjs.<span class="property">parentNode</span>.<span class="title function_">appendChild</span>(js);&#125;(<span class="variable language_">window</span>,<span class="variable language_">document</span>, <span class="string">&#x27;script&#x27;</span>, <span class="string">&#x27;webpushr-jssdk&#x27;</span>));</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="title function_">webpushr</span>(<span class="string">&#x27;setup&#x27;</span>,&#123;<span class="string">&#x27;key&#x27;</span>:<span class="string">&#x27;BKOlpbdgvBCWXqXI6PtsUzobY7TLV9gwJU8bzMktrwfrSERg_xnLvbjpdw8x2GmFmi1ZcLTz0ni6OnX5MAwoM58&#x27;</span> &#125;);</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line">  &lt;!-- end webpushr tracking code --&gt;</span><br></pre></td></tr></table></figure><p>最后一行<code>BKOlpbdgvBCWXqXI6PtsUzobY7TLV9gwJU8bzMktrwfrSERg_xnLvbjpdw8x2GmFmi1ZcLTz0ni6OnX5MAwoM58</code> 就是你的 <code>trackingCode</code></p><p><strong>注意</strong>：因权限问题，本地测试时(<code>hexo s</code>)可能不会显示弹窗，但如果你配置了小铃铛，小铃铛会显示</p><h2 id="额外配置">额外配置<a class="fa-solid fa-hashtag" href="#额外配置"></a></h2><p>因官方sw脚本注册后，我们无法注册自己的sw脚本，但官方提供了配置，方便我们使用sw的缓存，拦截请求等功能</p><p>首先在配置项中添加 <code>sw_self: true </code>配置，开启自行注册sw（默认用户不用添加或者设为 <code>false</code>）</p><figure class="highlight yaml"><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="attr">webpushr:</span></span><br><span class="line">  <span class="attr">sw_self:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>另外，你还需要在你的脚本文件（例如<code>sw.js</code>）中引入</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">importScripts</span>(<span class="string">&#x27;https://cdn.webpushr.com/sw-server.min.js&#x27;</span>);</span><br></pre></td></tr></table></figure><p>完成这些你就可以自行注册你的<code>sw</code>脚本了，如果你需要了解如何编写或注册<code>service worker</code>脚本，可以参考以下文章或项目</p><p><a href="https://kmar.top/posts/73014407/">hexo-swpp</a></p><p><a href="https://blog.cyfan.top/p/c0af86bb.html">Service Worker</a></p><p><a href="https://clientworker.js.org/">clientworker</a></p><p><a href="https://github.com/GoogleChrome/workbox">Workbox</a></p><h2 id="自定义">自定义<a class="fa-solid fa-hashtag" href="#自定义"></a></h2><p>个人建议将控制台右上角小铃铛🔔里全部配置一遍以获得更好的效果</p><p>你需要自定义一些参数才可以使用根据不同主题，按照订阅者订阅话题推送功能（目前根据个人需求是这个设置，默认行为为当未匹配到对应分类时不推送文章，而不是向所有用户推送文章，当然你也可以配置目标为所有用户）</p><p>在控制台，点击<code>Setup</code>&gt;<code>Opt-In Prompt</code> ，向下滑动打开<code>Enable Topics</code>（小铃铛样式无此选项，因此推荐您使用前两种样式），并新增几个主题，对应你想推送的文章分类即可</p><p>然后点击<code>Users</code>&gt;<code>Segments</code> ，即可获取对应的<code>segment</code>关系，依次填入配置项即可</p><h2 id="工作原理">工作原理<a class="fa-solid fa-hashtag" href="#工作原理"></a></h2><p>当你运行<code>hexo generate</code>插件会在<code>public</code> 目录生成 <code>newPost.json</code> 这样一个文件. <code>newPost.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;title&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Hexo浏览器定向推送文章更新&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;updated&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2023-04-22T20:25:00+08:00&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;message&quot;</span><span class="punctuation">:</span> <span class="string">&quot;这一次，CC的部落格可以根据读者订阅主题定向推送了，并且实现了NPM插件化&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;target_url&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://blog.ccknbc.cc/posts/hexo-webpushr-notification/&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;image&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/d2a947d48815ed24936a919873b97841_w1366_h768_s31.png&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;categories&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;博客&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;schedule&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2023-06-13T15:16:41.187Z&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;expire&quot;</span><span class="punctuation">:</span> <span class="string">&quot;7d&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;auto_hide&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>而他的来源就是我们在文章开头<code>Front-Matter</code>自定义的那些属性，而本插件针对<code>Butterfly</code>主题做了针对性修改，您也可以在您的模板文件目录下修改文章模板文件(<code>Hexo/scaffolds/post.md</code>)，主要针对性参数如下</p><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><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">date:</span> </span><br><span class="line"><span class="attr">updated:</span> </span><br><span class="line"><span class="attr">schedule:</span> <span class="string">对应配置项中定时推送时间</span></span><br><span class="line"><span class="attr">auto_hide:</span> <span class="string">对应配置项中是否自动隐藏</span></span><br><span class="line"><span class="attr">expire:</span> <span class="string">对应配置项中过期时间</span></span><br><span class="line"><span class="attr">categories:</span> <span class="string">文章分类</span></span><br><span class="line"><span class="attr">description:</span> <span class="string">对应配置项中message，即文章描述</span></span><br><span class="line"><span class="attr">cover:</span> <span class="string">对应配置项中image，默认选取文章封面</span></span><br></pre></td></tr></table></figure><p>如果你的主题不是采用默认的<code>date</code> <code>updated</code> 参数，记得补充，因为这是判断最新文章的依据</p><p>如果你习惯了使用截断的方式，也无需配置<code>description</code>继续使用，示例如下，注意<code>&lt;!-- more --&gt;</code></p><figure class="highlight markdown"><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></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: Hexo使用Web Push Notification 浏览器通知推送</span><br><span class="line">tags:</span><br><span class="line"><span class="bullet">  -</span> hexo</span><br><span class="line"><span class="bullet">  -</span> 服务器推送技术</span><br><span class="line"><span class="bullet">  -</span> push notifications</span><br><span class="line">categories:</span><br><span class="line"><span class="bullet">  -</span> 开发</span><br><span class="line">comments: true</span><br><span class="line">abbrlink: 98ae9e55</span><br><span class="line"><span class="section">date: 2020-02-26 10:00:00</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line">Web Push Notification 是怎么工作的？个人博客为什么要使用它？如何使用它？</span><br><span class="line"></span><br><span class="line">&lt;!-- more --&gt;</span><br></pre></td></tr></table></figure><p>当执行 <code>hexo deploy</code>命令时，插件会比较在线版本和本地版本<code>newPost.json</code>中最新文章更新时间是否一致，如果不同，则插件将推送最新文章更新通知（默认为十分钟后推送）</p><p><strong>注意</strong>：如果您是第一次使用本地测试应该看到</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">INFO  无文章更新 或 为首次推送更新</span><br></pre></td></tr></table></figure><p>这是正常现象，因为此时你的网站还没有<code>newPost.json</code>这个文件，后续有更新时将正常推送，你可以先推送一次，再修改更新时间测试一次，当然建议测试目标选择自己，即sid选项配置</p><p>当然如果您在使用过程中有什么问题或遇到了Bug也欢迎随时在评论区或<a href="https://github.com/Rock-Candy-Tea/hexo-webpushr-notification/issues">issues</a>反馈，当然因为本人是菜鸡，所以有大佬PR最好了</p><h2 id="推送效果">推送效果<a class="fa-solid fa-hashtag" href="#推送效果"></a></h2><p>因为我是通知自动隐藏后才截图，所以大致效果如下所示</p><p><img src="https://cdn.nlark.com/yuque/0/2022/png/8391407/1664951686275-f37cb76d-34f6-40ed-94c6-9bed130d0605.png" alt="" loading="lazy"></p><h2 id="后续计划">后续计划<a class="fa-solid fa-hashtag" href="#后续计划"></a></h2><ul class="contains-task-list"><li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"> 兼容自定义<code>Service Work</code>的功能，因为<code>webpushr-sw.js</code>优先注册的原因，只能有一个 <code>sw</code>注册，无法注册自己编写脚本。</li><li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"> 支持参数更多的可自定义，启用或关闭。例如不延时，立即发送；不显示按钮（因为默认就是跳转到文章）等</li><li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"> 目前的判断逻辑，虽然可以根据更新时间来判断，但如果很久之前的文章翻新，只要更新时间最新，也会触发推送，主要针对 updated 方式，还没想到好的解决办法，目前就是确认需要推送才更改更新时间咯</li><li class="task-list-item"><input class="task-list-item-checkbox" disabled="" type="checkbox"> 优化代码，减少代码量</li></ul>]]></c:encoded></item><item><title>基于小波变换的图像去噪技术研究</title><link>https://blog.ccknbc.cc/posts/research-on-image-denoising-technology-based-on-wavelet-transform/</link><description>基于小波变换的图像去噪技术研究</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%AD%A6%E4%B9%A0/">学习</category><category domain="https://blog.ccknbc.cc/tags/%E5%AD%A6%E4%B9%A0/">学习</category><pubDate>Fri, 10 Jul 2026 01:27:42 GMT</pubDate><c:encoded><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/18"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/research-on-image-denoising-technology-based-on-wavelet-transform"><strong>CC的部落格</strong></a></p><p><font style="color:#333333;"><div class="note warning simple"><p>这篇文章占个坑，目前不会公开，因为成为了毕业论文</p></div></font></p>]]></c:encoded></item><item><title>提问的智慧</title><link>https://blog.ccknbc.cc/posts/how-to-ask-questions-the-smart-way/</link><description>Copyleft 2001 by D.H.Grand(nOBODY/Ginux), 2010 by Gasolin, 2015 by Ryan Wu，本中文指南是基于原文 3.10 版以及 2010 年由 Gasolin 所翻译版本的最新翻译</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%AD%A6%E4%B9%A0/">学习</category><category domain="https://blog.ccknbc.cc/tags/%E5%AD%A6%E4%B9%A0/">学习</category><pubDate>Fri, 10 Jul 2026 01:27:42 GMT</pubDate><c:encoded><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/17/"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/how-to-ask-questions-the-smart-way/"><strong>CC的部落格</strong></a></p><h2 id="提问的智慧">提问的智慧<a class="fa-solid fa-hashtag" href="#提问的智慧"></a></h2><p>How To Ask Questions The Smart Way</p><p>Copyright © 2001, 2006, 2014 Eric S. Raymond, Rick Moen</p><p>本指南英文版版权为 Eric S. Raymond, Rick Moen 所有。</p><p>原文网址：<a href="http://www.catb.org/~esr/faqs/smart-questions.html">http://www.catb.org/~esr/faqs/smart-questions.html</a></p><p>Copyleft 2001 by D.H.Grand(nOBODY/Ginux), 2010 by Gasolin, 2015 by Ryan Wu</p><p>本中文指南是基于原文 3.10 版以及 2010 年由 Gasolin 所翻译版本的最新翻译；</p><p>协助指出翻译问题，请发 Issue，或直接发 Pull Request 给我。</p><p>本文另有繁體中文版（若在本站查看，可使用右下角简繁转换按钮）。</p><h2 id="原文版本历史"><a href="https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/history.md">原文版本历史</a><a class="fa-solid fa-hashtag" href="#原文版本历史"></a></h2><h2 id="目录">目录<a class="fa-solid fa-hashtag" href="#目录"></a></h2><ul><li><a href="#%E5%A3%B0%E6%98%8E">声明</a></li><li><a href="#%E7%AE%80%E4%BB%8B">简介</a></li><li><a href="#%E5%9C%A8%E6%8F%90%E9%97%AE%E4%B9%8B%E5%89%8D">在提问之前</a></li><li><a href="#%E5%BD%93%E4%BD%A0%E6%8F%90%E9%97%AE%E6%97%B6">当你提问时</a><ul><li><a href="#%E6%85%8E%E9%80%89%E6%8F%90%E9%97%AE%E7%9A%84%E8%AE%BA%E5%9D%9B">慎选提问的论坛</a></li><li><a href="#stack-overflow">Stack Overflow</a></li><li><a href="#%E7%BD%91%E7%AB%99%E5%92%8C-irc-%E8%AE%BA%E5%9D%9B">网站和 IRC 论坛</a></li><li><a href="#%E7%AC%AC%E4%BA%8C%E6%AD%A5%E4%BD%BF%E7%94%A8%E9%A1%B9%E7%9B%AE%E9%82%AE%E4%BB%B6%E5%88%97%E8%A1%A8">第二步，使用项目邮件列表</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E6%9C%89%E6%84%8F%E4%B9%89%E4%B8%94%E6%8F%8F%E8%BF%B0%E6%98%8E%E7%A1%AE%E7%9A%84%E6%A0%87%E9%A2%98">使用有意义且描述明确的标题</a></li><li><a href="#%E4%BD%BF%E9%97%AE%E9%A2%98%E5%AE%B9%E6%98%93%E5%9B%9E%E5%A4%8D">使问题容易回复</a></li><li><a href="#%E7%94%A8%E6%B8%85%E6%99%B0%E3%80%81%E6%AD%A3%E7%A1%AE%E3%80%81%E7%B2%BE%E5%87%86%E4%B8%94%E8%AF%AD%E6%B3%95%E6%AD%A3%E7%A1%AE%E7%9A%84%E8%AF%AD%E5%8F%A5">用清晰、正确、精准且语法正确的语句</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E6%98%93%E4%BA%8E%E8%AF%BB%E5%8F%96%E4%B8%94%E6%A0%87%E5%87%86%E7%9A%84%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E5%8F%91%E9%80%81%E9%97%AE%E9%A2%98">使用易于读取且标准的文件格式发送问题</a></li><li><a href="#%E7%B2%BE%E7%A1%AE%E5%9C%B0%E6%8F%8F%E8%BF%B0%E9%97%AE%E9%A2%98%E5%B9%B6%E8%A8%80%E4%B9%8B%E6%9C%89%E7%89%A9">精确地描述问题并言之有物</a></li><li><a href="#%E8%AF%9D%E4%B8%8D%E5%9C%A8%E5%A4%9A%E8%80%8C%E5%9C%A8%E7%B2%BE">话不在多而在精</a></li><li><a href="#%E5%88%AB%E5%8A%A8%E8%BE%84%E5%A3%B0%E7%A7%B0%E6%89%BE%E5%88%B0-bug">别动辄声称找到 Bug</a></li><li><a href="#%E4%BD%8E%E5%A3%B0%E4%B8%8B%E6%B0%94%E4%B8%8D%E8%83%BD%E4%BB%A3%E6%9B%BF%E4%BD%A0%E7%9A%84%E5%8A%9F%E8%AF%BE">低声下气不能代替你的功课</a></li><li><a href="#%E6%8F%8F%E8%BF%B0%E9%97%AE%E9%A2%98%E7%97%87%E7%8A%B6%E8%80%8C%E9%9D%9E%E4%BD%A0%E7%9A%84%E7%8C%9C%E6%B5%8B">描述问题症状而非你的猜测</a></li><li><a href="#%E6%8C%89%E5%8F%91%E7%94%9F%E6%97%B6%E9%97%B4%E5%85%88%E5%90%8E%E5%88%97%E5%87%BA%E9%97%AE%E9%A2%98%E7%97%87%E7%8A%B6">按发生时间先后列出问题症状</a></li><li><a href="#%E6%8F%8F%E8%BF%B0%E7%9B%AE%E6%A0%87%E8%80%8C%E4%B8%8D%E6%98%AF%E8%BF%87%E7%A8%8B">描述目标而不是过程</a></li><li><a href="#%E5%88%AB%E8%A6%81%E6%B1%82%E4%BD%BF%E7%94%A8%E7%A7%81%E4%BA%BA%E7%94%B5%E9%82%AE%E5%9B%9E%E5%A4%8D">别要求使用私人电邮回复</a></li><li><a href="#%E6%B8%85%E6%A5%9A%E6%98%8E%E7%A1%AE%E7%9A%84%E8%A1%A8%E8%BE%BE%E4%BD%A0%E7%9A%84%E9%97%AE%E9%A2%98%E4%BB%A5%E5%8F%8A%E9%9C%80%E6%B1%82">清楚明确的表达你的问题以及需求</a></li><li><a href="#%E8%AF%A2%E9%97%AE%E6%9C%89%E5%85%B3%E4%BB%A3%E7%A0%81%E7%9A%84%E9%97%AE%E9%A2%98%E6%97%B6">询问有关代码的问题时</a></li><li><a href="#%E5%88%AB%E6%8A%8A%E8%87%AA%E5%B7%B1%E5%AE%B6%E5%BA%AD%E4%BD%9C%E4%B8%9A%E7%9A%84%E9%97%AE%E9%A2%98%E8%B4%B4%E4%B8%8A%E6%9D%A5">别把自己家庭作业的问题贴上来</a></li><li><a href="#%E5%8E%BB%E6%8E%89%E6%97%A0%E6%84%8F%E4%B9%89%E7%9A%84%E6%8F%90%E9%97%AE%E5%8F%A5">去掉无意义的提问句</a></li><li><a href="#%E5%8D%B3%E4%BD%BF%E4%BD%A0%E5%BE%88%E6%80%A5%E4%B9%9F%E4%B8%8D%E8%A6%81%E5%9C%A8%E6%A0%87%E9%A2%98%E5%86%99%E7%B4%A7%E6%80%A5">即使你很急也不要在标题写紧急</a></li><li><a href="#%E7%A4%BC%E5%A4%9A%E4%BA%BA%E4%B8%8D%E6%80%AA%E8%80%8C%E4%B8%94%E6%9C%89%E6%97%B6%E8%BF%98%E5%BE%88%E6%9C%89%E5%B8%AE%E5%8A%A9">礼多人不怪，而且有时还很有帮助</a></li><li><a href="#%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E5%90%8E%E5%8A%A0%E4%B8%AA%E7%AE%80%E7%9F%AD%E7%9A%84%E8%A1%A5%E5%85%85%E8%AF%B4%E6%98%8E">问题解决后，加个简短的补充说明</a></li></ul></li><li><a href="#%E5%A6%82%E4%BD%95%E8%A7%A3%E8%AF%BB%E7%AD%94%E6%A1%88">如何解读答案</a><ul><li><a href="#rtfm-%E5%92%8C-stfw%E5%A6%82%E4%BD%95%E7%9F%A5%E9%81%93%E4%BD%A0%E5%B7%B2%E5%AE%8C%E5%85%A8%E6%90%9E%E7%A0%B8%E4%BA%86">RTFM 和 STFW：如何知道你已完全搞砸了</a></li><li><a href="#%E5%A6%82%E6%9E%9C%E8%BF%98%E6%98%AF%E6%90%9E%E4%B8%8D%E6%87%82">如果还是搞不懂</a></li><li><a href="#%E5%A4%84%E7%90%86%E6%97%A0%E7%A4%BC%E7%9A%84%E5%9B%9E%E5%BA%94">处理无礼的回应</a></li></ul></li><li><a href="#%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E6%89%AE%E6%BC%94%E5%A4%B1%E8%B4%A5%E8%80%85">如何避免扮演失败者</a></li><li><a href="#%E4%B8%8D%E8%AF%A5%E9%97%AE%E7%9A%84%E9%97%AE%E9%A2%98">不该问的问题</a></li><li><a href="#%E5%A5%BD%E9%97%AE%E9%A2%98%E4%B8%8E%E8%A0%A2%E9%97%AE%E9%A2%98">好问题与蠢问题</a></li><li><a href="#%E5%A6%82%E6%9E%9C%E5%BE%97%E4%B8%8D%E5%88%B0%E5%9B%9E%E7%AD%94">如果得不到回答</a></li><li><a href="#%E5%A6%82%E4%BD%95%E6%9B%B4%E5%A5%BD%E5%9C%B0%E5%9B%9E%E7%AD%94%E9%97%AE%E9%A2%98">如何更好地回答问题</a></li><li><a href="#%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90">相关资源</a></li><li><a href="#%E9%B8%A3%E8%B0%A2">鸣谢</a></li></ul><h2 id="声明">声明<a class="fa-solid fa-hashtag" href="#声明"></a></h2><p>许多项目在他们的使用协助/说明网页中链接了本指南，这么做很好，我们也鼓励大家都这么做。但如果你是负责管理这个项目网页的人，请在超链接附近的显著位置上注明：</p><p>本指南不提供此项目的实际支持服务！</p><p>我们已经深刻领教到少了上述声明所带来的痛苦。因为少了这点声明，我们不停地被一些白痴纠缠。这些白痴认为既然我们发布了这本指南，那么我们就有责任解决世上所有的技术问题。</p><p>如果你是因为需要某些协助而正在阅读这本指南，并且最后离开是因为发现从本指南作者们身上得不到直接的协助，那么你就是我们所说的那些白痴之一。别问我们问题，我们只会忽略你。我们在这本指南中是教你如何从那些真正懂得你所遇到软件或硬件问题的人取得协助，而 99% 的情况下那不会是我们。除非你确定本指南的作者之一刚好是你所遇到的问题领域的专家，否则请不要打扰我们，这样大家都会开心一点。</p><h2 id="简介">简介<a class="fa-solid fa-hashtag" href="#简介"></a></h2><p>在黑客的世界里，当你拋出一个技术问题时，最终是否能得到有用的回答，往往取决于你所提问和追问的方式。本指南将教你如何正确的提问以获得你满意的答案。</p><p>不只是黑客，现在开源（Open Source）软件已经相当盛行，你常常也可以由其他有经验的使用者身上得到好答案，这是件好事；使用者比起黑客来，往往对那些新手常遇到的问题更宽容一些。然而，将有经验的使用者视为黑客，并采用本指南所提的方法与他们沟通，同样也是能从他们身上得到满意回答的最有效方式。</p><p>首先你应该明白，黑客们喜爱有挑战性的问题，或者能激发他们思维的好问题。如果我们并非如此，那我们也不会成为你想询问的对象。如果你给了我们一个值得反复咀嚼玩味的好问题，我们自会对你感激不尽。好问题是激励，是厚礼。好问题可以提高我们的理解力，而且通常会暴露我们以前从没意识到或者思考过的问题。对黑客而言，&quot;好问题！&quot;是诚挚的大力称赞。</p><p>尽管如此，黑客们有着蔑视或傲慢面对简单问题的坏名声，这有时让我们看起来对新手、无知者似乎较有敌意，但其实不是那样的。</p><p>我们不讳言我们对那些不愿思考、或者在发问前不做他们该做的事的人的蔑视。那些人是时间杀手 —— 他们只想索取，从不付出，消耗我们可用在更有趣的问题或更值得回答的人身上的时间。我们称这样的人为 失败者（撸瑟） （由于历史原因，我们有时把它拼作 lusers）。</p><p>我们意识到许多人只是想使用我们写的软件，他们对学习技术细节没有兴趣。对大多数人而言，电脑只是种工具，是种达到目的的手段而已。他们有自己的生活并且有更要紧的事要做。我们了解这点，也从不指望每个人都对这些让我们着迷的技术问题感兴趣。尽管如此，我们回答问题的风格是指向那些真正对此有兴趣并愿意主动参与解决问题的人，这一点不会变，也不该变。如果连这都变了，我们就是在降低做自己最擅长的事情上的效率。</p><p>我们（在很大程度上）是自愿的，从繁忙的生活中抽出时间来解答疑惑，而且时常被提问淹没。所以我们无情的滤掉一些话题，特别是拋弃那些看起来像失败者的家伙，以便更高效的利用时间来回答赢家（winner）的问题。</p><p>如果你厌恶我们的态度，高高在上，或过于傲慢，不妨也设身处地想想。我们并没有要求你向我们屈服 —— 事实上，我们大多数人非常乐意与你平等地交流，只要你付出小小努力来满足基本要求，我们就会欢迎你加入我们的文化。但让我们帮助那些不愿意帮助自己的人是没有效率的。无知没有关系，但装白痴就是不行。</p><p>所以，你不必在技术上很在行才能吸引我们的注意，但你必须表现出能引导你变得在行的特质 —— 机敏、有想法、善于观察、乐于主动参与解决问题。如果你做不到这些使你与众不同的事情，我们建议你花点钱找家商业公司签个技术支持服务合同，而不是要求黑客个人无偿地帮助你。</p><p>如果你决定向我们求助，当然你也不希望被视为失败者，更不愿成为失败者中的一员。能立刻得到快速并有效答案的最好方法，就是像赢家那样提问 —— 聪明、自信、有解决问题的思路，只是偶尔在特定的问题上需要获得一点帮助。</p><p>（欢迎对本指南提出改进意见。你可以 email 你的建议至 <a href="mailto:esr@thyrsus.com">esr@thyrsus.com</a> 或 <a href="mailto:respond-auto@linuxmafia.com">respond-auto@linuxmafia.com</a>。然而请注意，本文并非网络礼节的通用指南，而我们通常会拒绝无助于在技术论坛得到有用答案的建议）。</p><h2 id="在提问之前">在提问之前<a class="fa-solid fa-hashtag" href="#在提问之前"></a></h2><p>在你准备要通过电子邮件、新闻群组或者聊天室提出技术问题前，请先做到以下事情：</p><ol><li>尝试在你准备提问的论坛的旧文章中搜索答案。</li><li>尝试上网搜索以找到答案。</li><li>尝试阅读手册以找到答案。</li><li>尝试阅读常见问题文件（FAQ）以找到答案。</li><li>尝试自己检查或试验以找到答案。</li><li>向你身边的强者朋友打听以找到答案。</li><li>如果你是程序开发者，请尝试阅读源代码以找到答案。</li></ol><p>当你提出问题的时候，请先表明你已经做了上述的努力；这将有助于树立你并不是一个不劳而获且浪费别人的时间的提问者。如果你能一并表达在做了上述努力的过程中所学到的东西会更好，因为我们更乐于回答那些表现出能从答案中学习的人的问题。</p><p>运用某些策略，比如先用 Google 搜索你所遇到的各种错误信息（搜索 Google 论坛和网页），这样很可能直接就找到了能解决问题的文件或邮件列表线索。即使没有结果，在邮件列表或新闻组寻求帮助时加上一句 我在 Google 中搜过下列句子但没有找到什么有用的东西 也是件好事，即使它只是表明了搜索引擎不能提供哪些帮助。这么做（加上搜索过的字串）也让遇到相似问题的其他人能被搜索引擎引导到你的提问来。</p><p>别着急，不要指望几秒钟的 Google 搜索就能解决一个复杂的问题。在向专家求助之前，再阅读一下常见问题文件（FAQ）、放轻松、坐舒服一些，再花点时间思考一下这个问题。相信我们，他们能从你的提问看出你做了多少阅读与思考，如果你是有备而来，将更有可能得到解答。不要将所有问题一股脑拋出，只因你的第一次搜索没有找到答案（或者找到太多答案）。</p><p>准备好你的问题，再将问题仔细的思考过一遍，因为草率的发问只能得到草率的回答，或者根本得不到任何答案。越是能表现出在寻求帮助前你为解决问题所付出的努力，你越有可能得到实质性的帮助。</p><p>小心别问错了问题。如果你的问题基于错误的假设，某个普通黑客（J. Random Hacker）多半会一边在心里想着蠢问题…， 一边用无意义的字面解释来答复你，希望着你会从问题的回答（而非你想得到的答案）中汲取教训。</p><p>绝不要自以为够格得到答案，你没有；你并没有。毕竟你没有为这种服务支付任何报酬。你将会是自己去挣到一个答案，靠提出有内涵的、有趣的、有思维激励作用的问题 —— 一个有潜力能贡献社区经验的问题，而不仅仅是被动的从他人处索取知识。</p><p>另一方面，表明你愿意在找答案的过程中做点什么是一个非常好的开端。谁能给点提示？、我的这个例子里缺了什么？以及我应该检查什么地方比请把我需要的确切的过程贴出来更容易得到答复。因为你表现出只要有人能指个正确方向，你就有完成它的能力和决心。</p><h2 id="当你提问时">当你提问时<a class="fa-solid fa-hashtag" href="#当你提问时"></a></h2><h3 id="慎选提问的论坛">慎选提问的论坛<a class="fa-solid fa-hashtag" href="#慎选提问的论坛"></a></h3><p>小心选择你要提问的场合。如果你做了下述的事情，你很可能被忽略掉或者被看作失败者：</p><ul><li>在与主题不合的论坛上贴出你的问题。</li><li>在探讨进阶技术问题的论坛张贴非常初级的问题；反之亦然。</li><li>在太多的不同新闻群组上重复转贴同样的问题（cross-post）。</li><li>向既非熟人也没有义务解决你问题的人发送私人电邮。</li></ul><p>黑客会剔除掉那些搞错场合的问题，以保护他们沟通的渠道不被无关的东西淹没。你不会想让这种事发生在自己身上的。</p><p>因此，第一步是找到对的论坛。再说一次，Google 和其它搜索引擎还是你的朋友，用它们来找到与你遭遇到困难的软硬件问题最相关的网站。通常那儿都有常见问题（FAQ）、邮件列表及相关说明文件的链接。如果你的努力（包括阅读 FAQ）都没有结果，网站上也许还有报告 Bug（Bug-reporting）的流程或链接，如果是这样，链过去看看。</p><p>向陌生的人或论坛发送邮件最可能是风险最大的事情。举例来说，别假设一个提供丰富内容的网页的作者会想充当你的免费顾问。不要对你的问题是否会受到欢迎做太乐观的估计 —— 如果你不确定，那就向别处发送，或者压根别发。</p><p>在选择论坛、新闻群组或邮件列表时，别太相信名字，先看看 FAQ 或者许可书以弄清楚你的问题是否切题。发文前先翻翻已有的话题，这样可以让你感受一下那里的文化。事实上，事先在新闻组或邮件列表的历史记录中搜索与你问题相关的关键词是个极好的主意，也许这样就找到答案了。即使没有，也能帮助你归纳出更好的问题。</p><p>别像机关枪似的一次&quot;扫射&quot;所有的帮助渠道，这就像大喊大叫一样会使人不快。要一个一个地来。</p><p>搞清楚你的主题！最典型的错误之一是在某种致力于跨平台可移植的语言、套件或工具的论坛中提关于 Unix 或 Windows 操作系统程序界面的问题。如果你不明白为什么这是大错，最好在搞清楚这之间差异之前什么也别问。</p><p>一般来说，在仔细挑选的公共论坛中提问，会比在私有论坛中提同样的问题更容易得到有用的回答。有几个理由可以支持这点，一是看潜在的回复者有多少，二是看观众有多少。黑客较愿意回答那些能帮助到许多人的问题。</p><p>可以理解的是，老练的黑客和一些热门软件的作者正在接受过多的错发信息。就像那根最后压垮骆驼背的稻草一样，你的加入也有可能使情况走向极端 —— 已经好几次了，一些热门软件的作者从自己软件的支持中抽身出来，因为伴随而来涌入其私人邮箱的无用邮件变得无法忍受。</p><h3 id="Stack-Overflow">Stack Overflow<a class="fa-solid fa-hashtag" href="#Stack-Overflow"></a></h3><p>搜索，然后 在 Stack Exchange 问。</p><p>近年来，Stack Exchange community 社区已经成为回答技术及其他问题的主要渠道，尤其是那些开放源码的项目。</p><p>因为 Google 索引是即时的，在看 Stack Exchange 之前先在 Google 搜索。有很高的机率某人已经问了一个类似的问题，而且 Stack Exchange 网站们往往会是搜索结果中最前面几个。如果你在 Google 上没有找到任何答案，你再到特定相关主题的网站去找。用标签（Tag）搜索能让你更缩小你的搜索结果。</p><p>Stack Exchange 已经成长到超过一百个网站，以下是最常用的几个站：</p><ul><li>Super User 是问一些通用的电脑问题，如果你的问题跟代码或是写程序无关，只是一些网络连线之类的，请到这里。</li><li>Stack Overflow 是问写程序有关的问题。</li><li>Server Fault 是问服务器和网管相关的问题。</li></ul><h3 id="网站和-IRC-论坛">网站和 IRC 论坛<a class="fa-solid fa-hashtag" href="#网站和-IRC-论坛"></a></h3><p>本地的使用者群组（user group），或者你所用的 Linux 发行版本也许正在宣传他们的网页论坛或 IRC 频道，并提供新手帮助（在一些非英语国家，新手论坛很可能还是邮件列表）， 这些地方是开始提问的好首选，特别是当你觉得遇到的也许只是相对简单或者很普通的问题时。有广告赞助的 IRC 频道是公开欢迎提问的地方，通常可以即时得到回应。</p><p>事实上，如果程序出的问题只发生在特定 Linux 发行版提供的版本（这很常见），最好先去该发行版的论坛或邮件列表中提问，再到程序本身的论坛或邮件列表提问。（否则）该项目的黑客可能仅仅回复 “用我们的版本”。</p><p>在任何论坛发文以前，先确认一下有没有搜索功能。如果有，就试着搜索一下问题的几个关键词，也许这会有帮助。如果在此之前你已做过通用的网页搜索（你也该这样做），还是再搜索一下论坛，搜索引擎有可能没来得及索引此论坛的全部内容。</p><p>通过论坛或 IRC 频道来提供使用者支持服务有增长的趋势，电子邮件则大多为项目开发者间的交流而保留。所以最好先在论坛或 IRC 中寻求与该项目相关的协助。</p><p>在使用 IRC 的时候，首先最好不要发布很长的问题描述，有些人称之为频道洪水。最好通过一句话的问题描述来开始聊天。</p><h3 id="第二步，使用项目邮件列表">第二步，使用项目邮件列表<a class="fa-solid fa-hashtag" href="#第二步，使用项目邮件列表"></a></h3><p>当某个项目提供开发者邮件列表时，要向列表而不是其中的个别成员提问，即使你确信他能最好地回答你的问题。查一查项目的文件和首页，找到项目的邮件列表并使用它。有几个很好的理由支持我们采用这种办法：</p><ul><li>任何好到需要向个别开发者提出的问题，也将对整个项目群组有益。反之，如果你认为自己的问题对整个项目群组来说太愚蠢，也不能成为骚扰个别开发者的理由。</li><li>向列表提问可以分散开发者的负担，个别开发者（尤其是项目领导人）也许太忙以至于没法回答你的问题。</li><li>大多数邮件列表都会被存档，那些被存档的内容将被搜索引擎索引。如果你向列表提问并得到解答，将来其它人可以通过网页搜索找到你的问题和答案，也就不用再次发问了。</li><li>如果某些问题经常被问到，开发者可以利用此信息来改进说明文件或软件本身，以使其更清楚。如果只是私下提问，就没有人能看到最常见问题的完整场景。</li></ul><p>如果一个项目既有&quot;使用者&quot; 也有&quot;开发者&quot;（或&quot;黑客&quot;）邮件列表或论坛，而你又不会动到那些源代码，那么就向&quot;使用者&quot;列表或论坛提问。不要假设自己会在开发者列表中受到欢迎，那些人多半会将你的提问视为干扰他们开发的噪音。</p><p>然而，如果你确信你的问题很特别，而且在&quot;使用者&quot; 列表或论坛中几天都没有回复，可以试试前往&quot;开发者&quot;列表或论坛发问。建议你在张贴前最好先暗地里观察几天以了解那里的行事方式（事实上这是参与任何私有或半私有列表的好主意）</p><p>如果你找不到一个项目的邮件列表，而只能查到项目维护者的电子邮件地址，尽管向他发信。即使是在这种情况下，也别假设（项目）邮件列表不存在。在你的电子邮件中，请陈述你已经试过但没有找到合适的邮件列表，也提及你不反对将自己的邮件转发给他人（许多人认为，即使没什么秘密，私人电子邮件也不应该被公开。通过允许将你的电子邮件转发他人，你给了相应人员处置你邮件的选择）。</p><h3 id="使用有意义且描述明确的标题">使用有意义且描述明确的标题<a class="fa-solid fa-hashtag" href="#使用有意义且描述明确的标题"></a></h3><p>在邮件列表、新闻群组或论坛中，大约 50 字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的帮帮忙、跪求、急（更别说救命啊!!! 这样让人反感的话，用这种标题会被条件反射式地忽略）来浪费这个机会。不要妄想用你的痛苦程度来打动我们，而应该是在这点空间中使用极简单扼要的描述方式来提出问题。</p><p>一个好标题范例是目标 —— 差异式的描述，许多技术支持组织就是这样做的。在目标部分指出是哪一个或哪一组东西有问题，在差异部分则描述与期望的行为不一致的地方。</p><blockquote><p>蠢问题：救命啊！我的笔记本电脑不能正常显示了！</p></blockquote><blockquote><p>聪明问题：<a href="http://X.org">X.org</a> 6.8.1 的鼠标光标会变形，某牌显卡 MV1005 芯片组。</p></blockquote><blockquote><p>更聪明问题：<a href="http://X.org">X.org</a> 6.8.1 的鼠标光标，在某牌显卡 MV1005 芯片组环境下 - 会变形。</p></blockquote><p>编写目标 —— 差异 式描述的过程有助于你组织对问题的细致思考。是什么被影响了？ 仅仅是鼠标光标或者还有其它图形？只在 <a href="http://X.org">X.org</a> 的 X 版中出现？或只是出现在 6.8.1 版中？ 是针对某牌显卡芯片组？或者只是其中的 MV1005 型号？ 一个黑客只需瞄一眼就能够立即明白你的环境和你遇到的问题。</p><p>总而言之，请想像一下你正在一个只显示标题的存档讨论串（Thread）索引中查寻。让你的标题更好地反映问题，可使下一个搜索类似问题的人能够关注这个讨论串，而不用再次提问相同的问题。</p><p>如果你想在回复中提出问题，记得要修改内容标题，以表明你是在问一个问题， 一个看起来像 Re: 测试 或者 Re: 新 bug 的标题很难引起足够重视。另外，在不影响连贯性之下，适当引用并删减前文的内容，能给新来的读者留下线索。</p><p>对于讨论串，不要直接点击回复来开始一个全新的讨论串，这将限制你的观众。因为有些邮件阅读程序，比如 mutt ，允许使用者按讨论串排序并通过折叠讨论串来隐藏消息，这样做的人永远看不到你发的消息。</p><p>仅仅改变标题还不够。mutt 和其它一些邮件阅读程序还会检查邮件标题以外的其它信息，以便为其指定讨论串。所以宁可发一个全新的邮件。</p><p>在网页论坛上，好的提问方式稍有不同，因为讨论串与特定的信息紧密结合，并且通常在讨论串外就看不到里面的内容，故通过回复提问，而非改变标题是可接受的。不是所有论坛都允许在回复中出现分离的标题，而且这样做了基本上没有人会去看。不过，通过回复提问，这本身就是暧昧的做法，因为它们只会被正在查看该标题的人读到。所以，除非你只想在该讨论串当前活跃的人群中提问，不然还是另起炉灶比较好。</p><h3 id="使问题容易回复">使问题容易回复<a class="fa-solid fa-hashtag" href="#使问题容易回复"></a></h3><p>以请将你的回复发送到……来结束你的问题多半会使你得不到回答。如果你觉得花几秒钟在邮件客户端设置一下回复地址都麻烦，我们也觉得花几秒钟思考你的问题更麻烦。如果你的邮件程序不支持这样做，换个好点的；如果是操作系统不支持这种邮件程序，也换个好点的。</p><p>在论坛，要求通过电子邮件回复是非常无礼的，除非你认为回复的信息可能比较敏感（有人会为了某些未知的原因，只让你而不是整个论坛知道答案）。如果你只是想在有人回复讨论串时得到电子邮件提醒，可以要求网页论坛发送给你。几乎所有论坛都支持诸如追踪此讨论串、有回复时发送邮件提醒等功能。</p><h3 id="用清晰、正确、精准且语法正确的语句">用清晰、正确、精准且语法正确的语句<a class="fa-solid fa-hashtag" href="#用清晰、正确、精准且语法正确的语句"></a></h3><p>我们从经验中发现，粗心的提问者通常也会粗心的写程序与思考（我敢打包票）。回答粗心大意者的问题很不值得，我们宁愿把时间耗在别处。</p><p>正确的拼写、标点符号和大小写是很重要的。一般来说，如果你觉得这样做很麻烦，不想在乎这些，那我们也觉得麻烦，不想在乎你的提问。花点额外的精力斟酌一下字句，用不着太僵硬与正式 —— 事实上，黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它必须很准确，而且有迹象表明你是在思考和关注问题。</p><p>正确地拼写、使用标点和大小写，不要将 its 混淆为 it’s，loose 搞成 lose 或者将 discrete 弄成 discreet。不要全部用大写，这会被视为无礼的大声嚷嚷（全部小写也好不到哪去，因为不易阅读。Alan Cox 也许可以这样做，但你不行）。</p><p>更白话的说，如果你写得像是个半文盲 [译注：小白]，那多半得不到理睬。也不要使用即时通信中的简写或火星文，如将的简化为 d 会使你看起来像一个为了少打几个键而省字的小白。更糟的是，如果像个小孩似地鬼画符那绝对是在找死，可以肯定没人会理你（或者最多是给你一大堆指责与挖苦）。</p><p>如果在使用非母语的论坛提问，你可以犯点拼写和语法上的小错，但决不能在思考上马虎（没错，我们通常能弄清两者的分别）。同时，除非你知道回复者使用的语言，否则请使用英语书写。繁忙的黑客一般会直接删除用他们看不懂语言写的消息。在网络上英语是通用语言，用英语书写可以将你的问题在尚未被阅读就被直接删除的可能性降到最低。</p><p>如果英文是你的外语（Second language），提示潜在回复者你有潜在的语言困难是很好的：</p><p>[译注：以下附上原文以供使用]</p><blockquote><p>English is not my native language; please excuse typing errors.</p></blockquote><ul><li>英文不是我的母语，请原谅我的错字或语法。</li></ul><blockquote><p>If you speak $LANGUAGE, please email/PM me;</p><p>I may need assistance translating my question.</p></blockquote><ul><li>如果你说<strong>某语言</strong>，请寄信/私讯给我；我需要有人协助我翻译我的问题。</li></ul><blockquote><p>I am familiar with the technical terms,</p><p>but some slang expressions and idioms are difficult for me.</p></blockquote><ul><li>我对技术名词很熟悉，但对于俗语或是特别用法比较不甚了解。</li></ul><blockquote><p>I’ve posted my question in $LANGUAGE and English.</p><p>I’ll be glad to translate responses, if you only use one or the other.</p></blockquote><ul><li>我把我的问题用<strong>某语言</strong>和英文写出来，如果你只用一种语言回答，我会乐意将其翻译成另一种。</li></ul><h3 id="使用易于读取且标准的文件格式发送问题">使用易于读取且标准的文件格式发送问题<a class="fa-solid fa-hashtag" href="#使用易于读取且标准的文件格式发送问题"></a></h3><p>如果你人为地将问题搞得难以阅读，它多半会被忽略，人们更愿读易懂的问题，所以：</p><ul><li>使用纯文字而不是 HTML (<a href="http://archive.birdhouse.org/etc/evilmail.html">关闭 HTML</a> 并不难）。</li><li>使用 MIME 附件通常是可以的，前提是真正有内容（譬如附带的源代码或 patch），而不仅仅是邮件程序生成的模板（譬如只是信件内容的拷贝）。</li><li>不要发送一段文字只是一行句子但自动换行后会变成多行的邮件（这使得回复部分内容非常困难）。设想你的读者是在 80 个字符宽的终端机上阅读邮件，最好设置你的换行分割点小于 80 字。</li><li>但是，对一些特殊的文件<strong>不要</strong>设置固定宽度（譬如日志档案拷贝或会话记录）。数据应该原样包含，让回复者有信心他们看到的是和你看到的一样的东西。</li><li>在英语论坛中，不要使用<code>Quoted-Printable</code> MIME 编码发送消息。这种编码对于张贴非 ASCII 语言可能是必须的，但很多邮件程序并不支持这种编码。当它们处理换行时，那些文本中四处散布的<code>=20</code>符号既难看也分散注意力，甚至有可能破坏内容的语意。</li><li>绝对，<strong>永远</strong>不要指望黑客们阅读使用封闭格式编写的文档，像微软公司的 Word 或 Excel 文件等。大多数黑客对此的反应就像有人将还在冒热气的猪粪倒在你家门口时你的反应一样。即便他们能够处理，他们也很厌恶这么做。</li><li>如果你从使用 Windows 的电脑发送电子邮件，关闭微软愚蠢的<code>智能引号</code>功能 （从[选项] &gt; [校订] &gt; [自动校正选项]，勾选掉<code>智能引号</code>单选框），以免在你的邮件中到处散布垃圾字符。</li><li>在论坛，勿滥用<code>表情符号</code>和<code>HTML</code>功能（当它们提供时）。一两个表情符号通常没有问题，但花哨的彩色文本倾向于使人认为你是个无能之辈。过滥地使用表情符号、色彩和字体会使你看来像个傻笑的小姑娘。这通常不是个好主意，除非你只是对性而不是对答案感兴趣。</li></ul><p>如果你使用图形用户界面的邮件程序（如微软公司的 Outlook 或者其它类似的），注意它们的默认设置不一定满足这些要求。大多数这类程序有基于选单的查看源代码命令，用它来检查发送文件夹中的邮件，以确保发送的是纯文本文件同时没有一些奇怪的字符。</p><h3 id="精确地描述问题并言之有物">精确地描述问题并言之有物<a class="fa-solid fa-hashtag" href="#精确地描述问题并言之有物"></a></h3><ul><li>仔细、清楚地描述你的问题或 Bug 的症状。</li><li>描述问题发生的环境（机器配置、操作系统、应用程序、以及相关的信息），提供经销商的发行版和版本号（如：<code>Fedora Core 4</code>、<code>Slackware 9.1</code>等）。</li><li>描述在提问前你是怎样去研究和理解这个问题的。</li><li>描述在提问前为确定问题而采取的诊断步骤。</li><li>描述最近做过什么可能相关的硬件或软件变更。</li><li>尽可能的提供一个可以<code>重现这个问题的可控环境</code>的方法。</li></ul><p>尽量去揣测一个黑客会怎样反问你，在你提问之前预先将黑客们可能遇到的问题回答一遍。</p><p>以上几点中，当你报告的是你认为可能在代码中的问题时，给黑客一个可以重现你的问题的环境尤其重要。当你这么做时，你得到有效的回答的机会和速度都会大大的提升。</p><p>Simon Tatham 写过一篇名为《如何有效的报告 Bug》的出色文章。强力推荐你也读一读。</p><h3 id="话不在多而在精">话不在多而在精<a class="fa-solid fa-hashtag" href="#话不在多而在精"></a></h3><p>你需要提供精确有内容的信息。这并不是要求你简单的把成堆的出错代码或者资料完全转录到你的提问中。如果你有庞大而复杂的测试样例能重现程序挂掉的情境，尽量将它剪裁得越小越好。</p><p>这样做的用处至少有三点。</p><p>第一，表现出你为简化问题付出了努力，这可以使你得到回答的机会增加；</p><p>第二，简化问题使你更有可能得到有用的答案；</p><p>第三，在精炼你的 bug 报告的过程中，你很可能就自己找到了解决方法或权宜之计。</p><h3 id="别动辄声称找到-Bug">别动辄声称找到 Bug<a class="fa-solid fa-hashtag" href="#别动辄声称找到-Bug"></a></h3><p>当你在使用软件中遇到问题，除非你非常、非常的有根据，不要动辄声称找到了 Bug。提示：除非你能提供解决问题的源代码补丁，或者提供回归测试来表明前一版本中行为不正确，否则你都多半不够完全确信。这同样适用在网页和文件，如果你（声称）发现了文件的 Bug，你应该能提供相应位置的修正或替代文件。</p><p>请记得，还有许多其它使用者没遇到你发现的问题，否则你在阅读文件或搜索网页时就应该发现了（你在抱怨前已经做了这些，是吧？）。这也意味着很有可能是你弄错了而不是软件本身有问题。</p><p>编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了 Bug，也就是在质疑他们的能力，即使你是对的，也有可能会冒犯到其中某部分人。当你在标题中嚷嚷着有 Bug 时，这尤其严重。</p><p>提问时，即使你私下非常确信已经发现一个真正的 Bug，最好写得像是你做错了什么。如果真的有 Bug，你会在回复中看到这点。这样做的话，如果真有 Bug，维护者就会向你道歉，这总比你惹恼别人然后欠别人一个道歉要好一点。</p><h3 id="低声下气不能代替你的功课">低声下气不能代替你的功课<a class="fa-solid fa-hashtag" href="#低声下气不能代替你的功课"></a></h3><p>有些人明白他们不该粗鲁或傲慢的提问并要求得到答复，但他们选择另一个极端 —— 低声下气：我知道我只是个可悲的新手，一个撸瑟，但… 这既使人困扰，也没有用，尤其是伴随着与实际问题含糊不清的描述时更令人反感。</p><p>别用原始灵长类动物的把戏来浪费你我的时间。取而代之的是，尽可能清楚地描述背景条件和你的问题情况。这比低声下气更好地定位了你的位置。</p><p>有时网页论坛会设有专为新手提问的版面，如果你真的认为遇到了初学者的问题，到那去就是了，但一样别那么低声下气。</p><h3 id="描述问题症状而非你的猜测">描述问题症状而非你的猜测<a class="fa-solid fa-hashtag" href="#描述问题症状而非你的猜测"></a></h3><p>告诉黑客们你认为问题是怎样造成的并没什么帮助。（如果你的推断如此有效，还用向别人求助吗？），因此要确信你原原本本告诉了他们问题的症状，而不是你的解释和理论；让黑客们来推测和诊断。如果你认为陈述自己的猜测很重要，清楚地说明这只是你的猜测，并描述为什么它们不起作用。</p><p>蠢问题</p><blockquote><p>我在编译内核时接连遇到 SIG11 错误，</p><p>我怀疑某条飞线搭在主板的走线上了，这种情况应该怎样检查最好？</p></blockquote><p>聪明问题</p><blockquote><p>我的组装电脑是 FIC-PA2007 主机板搭载 AMD K6/233 CPU（威盛 Apollo VP2 芯片组），</p><p>256MB Corsair PC133 SDRAM 内存，在编译内核时，从开机 20 分钟以后就频频产生 SIG11 错误，</p><p>但是在头 20 分钟内从没发生过相同的问题。重新启动也没有用，但是关机一晚上就又能工作 20 分钟。</p><p>所有内存都换过了，没有效果。相关部分的标准编译记录如下…。</p></blockquote><p>由于以上这点似乎让许多人觉得难以配合，这里有句话可以提醒你：所有的诊断专家都来自密苏里州。 美国国务院的官方座右铭则是：让我看看（出自国会议员 Willard D. Vandiver 在 1899 年时的讲话：我来自一个出产玉米，棉花，牛蒡和民主党人的国家，滔滔雄辩既不能说服我，也不会让我满意。我来自密苏里州，你必须让我看看。） 针对诊断者而言，这并不是一种怀疑，而只是一种真实而有用的需求，以便让他们看到的是与你看到的原始证据尽可能一致的东西，而不是你的猜测与归纳的结论。所以，大方的展示给我们看吧！</p><h3 id="按发生时间先后列出问题症状">按发生时间先后列出问题症状<a class="fa-solid fa-hashtag" href="#按发生时间先后列出问题症状"></a></h3><p>问题发生前的一系列操作，往往就是对找出问题最有帮助的线索。因此，你的说明里应该包含你的操作步骤，以及机器和软件的反应，直到问题发生。在命令行处理的情况下，提供一段操作记录（例如运行脚本工具所生成的），并引用相关的若干行（如 20 行）记录会非常有帮助。</p><p>如果挂掉的程序有诊断选项（如 -v 的详述开关），试着选择这些能在记录中增加调试信息的选项。记住，多不等于好。试着选取适当的调试级别以便提供有用的信息而不是让读者淹没在垃圾中。</p><p>如果你的说明很长（如超过四个段落），在开头简述问题，接下来再按时间顺序详述会有所帮助。这样黑客们在读你的记录时就知道该注意哪些内容了。</p><h3 id="描述目标而不是过程">描述目标而不是过程<a class="fa-solid fa-hashtag" href="#描述目标而不是过程"></a></h3><p>如果你想弄清楚如何做某事（而不是报告一个 Bug），在开头就描述你的目标，然后才陈述重现你所卡住的特定步骤。</p><p>经常寻求技术帮助的人在心中有个更高层次的目标，而他们在自以为能达到目标的特定道路上被卡住了，然后跑来问该怎么走，但没有意识到这条路本身就有问题。结果要费很大的劲才能搞定。</p><p>蠢问题</p><blockquote><p>我怎样才能从某绘图程序的颜色选择器中取得十六进制的的 RGB 值？</p></blockquote><p>聪明问题</p><blockquote><p>我正试着用替换一幅图片的色码（color table）成自己选定的色码，我现在知道的唯一方法是编辑每个色码区块（table slot），</p><p>但却无法从某绘图程序的颜色选择器取得十六进制的的 RGB 值。</p></blockquote><p>第二种提问法比较聪明，你可能得到像是建议采用另一个更合适的工具的回复。</p><h3 id="别要求使用私人电邮回复">别要求使用私人电邮回复<a class="fa-solid fa-hashtag" href="#别要求使用私人电邮回复"></a></h3><p>黑客们认为问题的解决过程应该公开、透明，此过程中如果更有经验的人注意到不完整或者不当之处，最初的回复才能够、也应该被纠正。同时，作为提供帮助者可以得到一些奖励，奖励就是他的能力和学识被其他同行看到。</p><p>当你要求私下回复时，这个过程和奖励都被中止。别这样做，让回复者来决定是否私下回答 —— 如果他真这么做了，通常是因为他认为问题编写太差或者太肤浅，以至于对其它人没有兴趣。</p><p>这条规则存在一条有限的例外，如果你确信提问可能会引来大量雷同的回复时，那么这个神奇的提问句会是向我发电邮，我将为论坛归纳这些回复。试着将邮件列表或新闻群组从洪水般的雷同回复中解救出来是非常有礼貌的 —— 但你必须信守诺言。</p><h3 id="清楚明确的表达你的问题以及需求">清楚明确的表达你的问题以及需求<a class="fa-solid fa-hashtag" href="#清楚明确的表达你的问题以及需求"></a></h3><p>漫无边际的提问是近乎无休无止的时间黑洞。最有可能给你有用答案的人通常也正是最忙的人（他们忙是因为要亲自完成大部分工作）。这样的人对无节制的时间黑洞相当厌恶，所以他们也倾向于厌恶那些漫无边际的提问。</p><p>如果你明确表述需要回答者做什么（如提供指点、发送一段代码、检查你的补丁、或是其他等等），就最有可能得到有用的答案。因为这会定出一个时间和精力的上限，便于回答者能集中精力来帮你。这么做很棒。</p><p>要理解专家们所处的世界，请把专业技能想像为充裕的资源，而回复的时间则是稀缺的资源。你要求他们奉献的时间越少，你越有可能从真正专业而且很忙的专家那里得到解答。</p><p>所以，界定一下你的问题，使专家花在辨识你的问题和回答所需要付出的时间减到最少，这技巧对你有用答案相当有帮助 —— 但这技巧通常和简化问题有所区别。因此，问我想更好的理解 X，可否指点一下哪有好一点说明？通常比问你能解释一下 X 吗？更好。如果你的代码不能运作，通常请别人看看哪里有问题，比要求别人替你改正要明智得多。</p><h3 id="询问有关代码的问题时">询问有关代码的问题时<a class="fa-solid fa-hashtag" href="#询问有关代码的问题时"></a></h3><p>别要求他人帮你调试有问题的代码，不提示一下应该从何入手。张贴几百行的代码，然后说一声：它不能工作会让你完全被忽略。只贴几十行代码，然后说一句：在第七行以后，我期待它显示 <x>，但实际出现的是 <y>比较有可能让你得到回应。</p><p>最有效描述程序问题的方法是提供最精简的 Bug 展示测试用例（bug-demonstrating test case）。什么是最精简的测试用例？那是问题的缩影；一小个程序片段能刚好展示出程序的异常行为，而不包含其他令人分散注意力的内容。怎么制作最精简的测试用例？如果你知道哪一行或哪一段代码会造成异常的行为，复制下来并加入足够重现这个状况的代码（例如，足以让这段代码能被编译/直译/被应用程序处理）。如果你无法将问题缩减到一个特定区块，就复制一份代码并移除不影响产生问题行为的部分。总之，测试用例越小越好（查看话不在多而在精一节）。</p><p>一般而言，要得到一段相当精简的测试用例并不太容易，但永远先尝试这样做的是种好习惯。这种方式可以帮助你了解如何自行解决这个问题 —— 而且即使你的尝试不成功，黑客们也会看到你在尝试取得答案的过程中付出了努力，这可以让他们更愿意与你合作。</p><p>如果你只是想让别人帮忙审查（Review）一下代码，在信的开头就要说出来，并且一定要提到你认为哪一部分特别需要关注以及为什么。</p><h3 id="别把自己家庭作业的问题贴上来">别把自己家庭作业的问题贴上来<a class="fa-solid fa-hashtag" href="#别把自己家庭作业的问题贴上来"></a></h3><p>黑客们很擅长分辨哪些问题是家庭作业式的问题；因为我们中的大多数都曾自己解决这类问题。同样，这些问题得由你来搞定，你会从中学到东西。你可以要求给点提示，但别要求得到完整的解决方案。</p><p>如果你怀疑自己碰到了一个家庭作业式的问题，但仍然无法解决，试试在使用者群组，论坛或（最后一招）在项目的使用者邮件列表或论坛中提问。尽管黑客们会看出来，但一些有经验的使用者也许仍会给你一些提示。</p><h3 id="去掉无意义的提问句">去掉无意义的提问句<a class="fa-solid fa-hashtag" href="#去掉无意义的提问句"></a></h3><p>避免用无意义的话结束提问，例如有人能帮我吗？或者这有答案吗？。</p><p>首先：如果你对问题的描述不是很好，这样问更是画蛇添足。</p><p>其次：由于这样问是画蛇添足，黑客们会很厌烦你 —— 而且通常会用逻辑上正确，但毫无意义的回答来表示他们的蔑视， 例如：没错，有人能帮你或者不，没答案。</p><p>一般来说，避免用 是或否、对或错、有或没有类型的问句，除非你想得到是或否类型的回答。</p><h3 id="即使你很急也不要在标题写紧急">即使你很急也不要在标题写<code>紧急</code><a class="fa-solid fa-hashtag" href="#即使你很急也不要在标题写紧急"></a></h3><p>这是你的问题，不是我们的。宣称紧急极有可能事与愿违：大多数黑客会直接删除无礼和自私地企图即时引起关注的问题。更严重的是，紧急这个字（或是其他企图引起关注的标题）通常会被垃圾信过滤器过滤掉 —— 你希望能看到你问题的人可能永远也看不到。</p><p>有半个例外的情况是，如果你是在一些很高调，会使黑客们兴奋的地方，也许值得这样去做。在这种情况下，如果你有时间压力，也很有礼貌地提到这点，人们也许会有兴趣回答快一点。</p><p>当然，这风险很大，因为黑客们兴奋的点多半与你的不同。譬如从 NASA 国际空间站（International Space Station）发这样的标题没有问题，但用自我感觉良好的慈善行为或政治原因发肯定不行。事实上，张贴诸如紧急：帮我救救这个毛绒绒的小海豹！肯定让你被黑客忽略或惹恼他们，即使他们认为毛绒绒的小海豹很重要。</p><p>如果你觉得这点很不可思议，最好再把这份指南剩下的内容多读几遍，直到你弄懂了再发文。</p><h3 id="礼多人不怪，而且有时还很有帮助">礼多人不怪，而且有时还很有帮助<a class="fa-solid fa-hashtag" href="#礼多人不怪，而且有时还很有帮助"></a></h3><p>彬彬有礼，多用请和谢谢您的关注，或谢谢你的关照。让大家都知道你对他们花时间免费提供帮助心存感激。</p><p>坦白说，这一点并没有比清晰、正确、精准并合法语法和避免使用专用格式重要（也不能取而代之）。黑客们一般宁可读有点唐突但技术上鲜明的 Bug 报告，而不是那种有礼但含糊的报告。（如果这点让你不解，记住我们是按问题能教给我们什么来评价问题的价值的）</p><p>然而，如果你有一串的问题待解决，客气一点肯定会增加你得到有用回应的机会。</p><p>（我们注意到，自从本指南发布后，从资深黑客那里得到的唯一严重缺陷反馈，就是对预先道谢这一条。一些黑客觉得先谢了意味着事后就不用再感谢任何人的暗示。我们的建议是要么先说先谢了，然后事后再对回复者表示感谢，或者换种方式表达感激，譬如用谢谢你的关注或谢谢你的关照。）</p><h3 id="问题解决后，加个简短的补充说明">问题解决后，加个简短的补充说明<a class="fa-solid fa-hashtag" href="#问题解决后，加个简短的补充说明"></a></h3><p>问题解决后，向所有帮助过你的人发个说明，让他们知道问题是怎样解决的，并再一次向他们表示感谢。如果问题在新闻组或者邮件列表中引起了广泛关注，应该在那里贴一个说明比较恰当。</p><p>最理想的方式是向最初提问的话题回复此消息，并在标题中包含已修正，已解决或其它同等含义的明显标记。在人来人往的邮件列表里，一个看见讨论串问题 X 和问题 X - 已解决的潜在回复者就明白不用再浪费时间了（除非他个人觉得问题 X 的有趣），因此可以利用此时间去解决其它问题。</p><p>补充说明不必很长或是很深入；简单的一句你好，原来是网线出了问题！谢谢大家 – Bill 比什么也不说要来的好。事实上，除非结论真的很有技术含量，否则简短可爱的小结比长篇大论更好。说明问题是怎样解决的，但大可不必将解决问题的过程复述一遍。</p><p>对于有深度的问题，张贴调试记录的摘要是有帮助的。描述问题的最终状态，说明是什么解决了问题，在此之后才指明可以避免的盲点。避免盲点的部分应放在正确的解决方案和其它总结材料之后，而不要将此信息搞成侦探推理小说。列出那些帮助过你的名字，会让你交到更多朋友。</p><p>除了有礼貌和有内涵以外，这种类型的补充也有助于他人在邮件列表/新闻群组/论坛中搜索到真正解决你问题的方案，让他们也从中受益。</p><p>至少，这种补充有助于让每位参与协助的人因问题的解决而从中得到满足感。如果你自己不是技术专家或者黑客，那就相信我们，这种感觉对于那些你向他们求助的大师或者专家而言，是非常重要的。问题悬而未决会让人灰心；黑客们渴望看到问题被解决。好人有好报，满足他们的渴望，你会在下次提问时尝到甜头。</p><p>思考一下怎样才能避免他人将来也遇到类似的问题，自问写一份文件或加个常见问题（FAQ）会不会有帮助。如果是的话就将它们发给维护者。</p><p>在黑客中，这种良好的后继行动实际上比传统的礼节更为重要，也是你如何透过善待他人而赢得声誉的方式，这是非常有价值的资产。</p><h2 id="如何解读答案">如何解读答案<a class="fa-solid fa-hashtag" href="#如何解读答案"></a></h2><h3 id="RTFM-和-STFW：如何知道你已完全搞砸了">RTFM 和 STFW：如何知道你已完全搞砸了<a class="fa-solid fa-hashtag" href="#RTFM-和-STFW：如何知道你已完全搞砸了"></a></h3><p>有一个古老而神圣的传统：如果你收到 RTFM （Read The Fucking Manual）的回应，回答者认为你应该去读他妈的手册。当然，基本上他是对的，你应该去读一读。</p><p>RTFM 有一个年轻的亲戚。如果你收到 STFW（Search The Fucking Web）的回应，回答者认为你应该到他妈的网上搜索。那人多半也是对的，去搜索一下吧。（更温和一点的说法是 Google 是你的朋友！）</p><p>在论坛，你也可能被要求去爬爬论坛的旧文。事实上，有人甚至可能热心地为你提供以前解决此问题的讨论串。但不要依赖这种关照，提问前应该先搜索一下旧文。</p><p>通常，用这两句之一回答你的人会给你一份包含你需要内容的手册或者一个网址，而且他们打这些字的时候也正在读着。这些答复意味着回答者认为</p><ul><li><strong>你需要的信息非常容易获得</strong>；</li><li><strong>你自己去搜索这些信息比灌给你，能让你学到更多</strong>。</li></ul><p>你不应该因此不爽；依照黑客的标准，他已经表示了对你一定程度的关注，而没有对你的要求视而不见。你应该对他祖母般的慈祥表示感谢。</p><h3 id="如果还是搞不懂">如果还是搞不懂<a class="fa-solid fa-hashtag" href="#如果还是搞不懂"></a></h3><p>如果你看不懂回应，别立刻要求对方解释。像你以前试着自己解决问题时那样（利用手册，FAQ，网络，身边的高手），先试着去搞懂他的回应。如果你真的需要对方解释，记得表现出你已经从中学到了点什么。</p><p>比方说，如果我回答你：看来似乎是 zentry 卡住了；你应该先清除它。，然后，这是一个很糟的后续问题回应：zentry 是什么？ 好的问法应该是这样：哦~~~我看过说明了但是只有 -z 和 -p 两个参数中提到了 zentries，而且还都没有清楚的解释如何清除它。你是指这两个中的哪一个吗？还是我看漏了什么？</p><h3 id="处理无礼的回应">处理无礼的回应<a class="fa-solid fa-hashtag" href="#处理无礼的回应"></a></h3><p>很多黑客圈子中看似无礼的行为并不是存心冒犯。相反，它是直接了当，一针见血式的交流风格，这种风格更注重解决问题，而不是使人感觉舒服而却模模糊糊。</p><p>如果你觉得被冒犯了，试着平静地反应。如果有人真的做了出格的事，邮件列表、新闻群组或论坛中的前辈多半会招呼他。如果这没有发生而你却发火了，那么你发火对象的言语可能在黑客社区中看起来是正常的，而你将被视为有错的一方，这将伤害到你获取信息或帮助的机会。</p><p>另一方面，你偶尔真的会碰到无礼和无聊的言行。与上述相反，对真正的冒犯者狠狠地打击，用犀利的语言将其驳得体无完肤都是可以接受的。然而，在行事之前一定要非常非常的有根据。纠正无礼的言论与开始一场毫无意义的口水战仅一线之隔，黑客们自己莽撞地越线的情况并不鲜见。如果你是新手或外人，避开这种莽撞的机会并不高。如果你想得到的是信息而不是消磨时光，这时最好不要把手放在键盘上以免冒险。</p><p>（有些人断言很多黑客都有轻度的自闭症或亚斯伯格综合症，缺少用于润滑人类社会正常交往所需的神经。这既可能是真也可能是假的。如果你自己不是黑客，兴许你认为我们脑袋有问题还能帮助你应付我们的古怪行为。只管这么干好了，我们不在乎。我们喜欢我们现在这个样子，并且通常对病患标记都有站得住脚的怀疑）。</p><p>Jeff Bigler 的观察总结和这个相关也值得一读 (tact filters)。</p><p>在下一节，我们会谈到另一个问题，当你行为不当时所会受到的冒犯。</p><h2 id="如何避免扮演失败者">如何避免扮演失败者<a class="fa-solid fa-hashtag" href="#如何避免扮演失败者"></a></h2><p>在黑客社区的论坛中有那么几次你可能会搞砸 —— 以本指南所描述到的或类似的方式。而你会在公开场合中被告知你是如何搞砸的，也许攻击的言语中还会带点夹七夹八的颜色。</p><p>这种事发生以后，你能做的最糟糕的事莫过于哀嚎你的遭遇、宣称被口头攻击、要求道歉、高声尖叫、憋闷气、威胁诉诸法律、向其雇主报怨、忘了关马桶盖等等。相反地，你该这么做：</p><p>熬过去，这很正常。事实上，它是有益健康且合理的。</p><p>社区的标准不会自行维持，它们是通过参与者积极而公开地执行来维持的。不要哭嚎所有的批评都应该通过私下的邮件传送，它不是这样运作的。当有人评论你的一个说法有误或者提出不同看法时，坚持声称受到个人攻击也毫无益处，这些都是失败者的态度。</p><p>也有其它的黑客论坛，受过高礼节要求的误导，禁止参与者张贴任何对别人帖子挑毛病的消息，并声称如果你不想帮助用户就闭嘴。 结果造成有想法的参与者纷纷离开，这么做只会使它们沦为毫无意义的唠叨与无用的技术论坛。</p><p>夸张的讲法是：你要的是“友善”（以上述方式）还是有用？两个里面挑一个。</p><p>记着：当黑客说你搞砸了，并且（无论多么刺耳）告诉你别再这样做时，他正在为关心你和他的社区而行动。对他而言，不理你并将你从他的生活中滤掉更简单。如果你无法做到感谢，至少要表现得有点尊严，别大声哀嚎，也别因为自己是个有戏剧性超级敏感的灵魂和自以为有资格的新来者，就指望别人像对待脆弱的洋娃娃那样对你。</p><p>有时候，即使你没有搞砸（或者只是在他的想像中你搞砸了），有些人也会无缘无故地攻击你本人。在这种情况下，抱怨倒是真的会把问题搞砸。</p><p>这些来找麻烦的人要么是毫无办法但自以为是专家的不中用家伙，要么就是测试你是否真会搞砸的心理专家。其它读者要么不理睬，要么用自己的方式对付他们。这些来找麻烦的人在给他们自己找麻烦，这点你不用操心。</p><p>也别让自己卷入口水战，最好不要理睬大多数的口水战 —— 当然，这是在你检验它们只是口水战，并且未指出你有搞砸的地方，同时也没有巧妙地将问题真正的答案藏于其后（这也是有可能的）。</p><h2 id="不该问的问题">不该问的问题<a class="fa-solid fa-hashtag" href="#不该问的问题"></a></h2><p>以下是几个经典蠢问题，以及黑客没回答时心中所想的：</p><p>问题：我能在哪找到 X 程序或 X 资源？</p><p>问题：我怎样用 X 做 Y？</p><p>问题：如何设定我的 shell 提示？</p><p>问题：我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 档案转换为 TeX 格式吗？</p><p>问题：我的程序/设定/SQL 语句没有用</p><p>问题：我的 Windows 电脑有问题，你能帮我吗？</p><p>问题：我的程序不会动了，我认为系统工具 X 有问题</p><p>问题：我在安装 Linux（或者 X ）时有问题，你能帮我吗？</p><p>问题：我怎么才能PJ root 帐号/窃取 OP 特权/读别人的邮件呢？</p><hr><blockquote><p>问题：我能在哪找到 X 程序或 X 资源？</p></blockquote><p>回答：就在我找到它的地方啊，白痴 —— 搜索引擎的那一头。天哪！难道还有人不会用 Google 吗？</p><blockquote><p>问题：我怎样用 X 做 Y？</p></blockquote><p>回答：如果你想解决的是 Y ，提问时别给出可能并不恰当的方法。这种问题说明提问者不但对 X 完全无知，也对 Y 要解决的问题糊涂，还被特定形势禁锢了思维。最好忽略这种人，等他们把问题搞清楚了再说。</p><blockquote><p>问题：如何设定我的 shell 提示？？</p></blockquote><p>回答：如果你有足够的智慧提这个问题，你也该有足够的智慧去 RTFM，然后自己去找出来。</p><blockquote><p>问题：我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 档案转换为 TeX 格式吗？</p></blockquote><p>回答：试试看就知道了。如果你试过，你既知道了答案，就不用浪费我的时间了。</p><blockquote><p>问题：我的{程序/设定/SQL 语句}不工作</p></blockquote><p>回答：这不算是问题吧，我对要我问你二十个问题才找得出你真正问题的问题没兴趣 —— 我有更有意思的事要做呢。在看到这类问题的时候，我的反应通常不外如下三种</p><ul><li>你还有什么要补充的吗？</li><li>真糟糕，希望你能搞定。</li><li>这关我屁事？</li></ul><blockquote><p>问题：我的 Windows 电脑有问题，你能帮我吗？</p></blockquote><p>回答：能啊，扔掉微软的垃圾，换个像 Linux 或 BSD 的开源操作系统吧。</p><p>注意：如果程序有官方版 Windows 或者与 Windows 有互动（如 Samba），你可以问与 Windows 相关的问题， 只是别对问题是由 Windows 操作系统而不是程序本身造成的回复感到惊讶， 因为 Windows 一般来说实在太烂，这种说法通常都是对的。</p><blockquote><p>问题：我的程序不会动了，我认为系统工具 X 有问题</p></blockquote><p>回答：你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与函数库档案有明显缺陷的人，更有可能的是你完全没有根据。不同凡响的说法需要不同凡响的证据，当你这样声称时，你必须有清楚而详尽的缺陷说明文件作后盾。</p><blockquote><p>问题：我在安装 Linux（或者 X ）时有问题，你能帮我吗？</p></blockquote><p>回答：不能，我只有亲自在你的电脑上动手才能找到毛病。还是去找你当地的 Linux 使用群组者寻求实际的指导吧（你能在这儿找到使用者群组的清单）。</p><p>注意：如果安装问题与某 Linux 的发行版有关，在它的邮件列表、论坛或本地使用者群组中提问也许是恰当的。此时，应描述问题的准确细节。在此之前，先用 Linux 和所有被怀疑的硬件作关键词仔细搜索。</p><blockquote><p>问题：我怎么才能PJ root 帐号/窃取 OP 特权/读别人的邮件呢？</p></blockquote><p>回答：想要这样做，说明了你是个卑鄙小人；想找个黑客帮你，说明你是个白痴！</p><h2 id="好问题与蠢问题">好问题与蠢问题<a class="fa-solid fa-hashtag" href="#好问题与蠢问题"></a></h2><p>最后，我将透过举一些例子，来说明怎样聪明的提问；同一个问题的两种问法被放在一起，一种是愚蠢的，另一种才是明智的。</p><p>蠢问题：</p><blockquote><p>我可以在哪儿找到关于 Foonly Flurbamatic 的资料？</p></blockquote><p>这种问法无非想得到 STFW 这样的回答。</p><p>聪明问题：</p><blockquote><p>我用 Google 搜索过 “Foonly Flurbamatic 2600”，但是没找到有用的结果。谁知道上哪儿去找对这种设备编程的资料？</p></blockquote><p>这个问题已经 STFW 过了，看起来他真的遇到了麻烦。</p><p>蠢问题：</p><blockquote><p>我从 foo 项目找来的源码没法编译。它怎么这么烂？</p></blockquote><p>他觉得都是别人的错，这个傲慢自大的提问者。</p><p>聪明问题：</p><blockquote><p>foo 项目代码在 Nulix 6.2 版下无法编译通过。我读过了 FAQ，但里面没有提到跟 Nulix 有关的问题。这是我编译过程的记录，我有什么做的不对的地方吗？</p></blockquote><p>提问者已经指明了环境，也读过了 FAQ，还列出了错误，并且他没有把问题的责任推到别人头上，他的问题值得被关注。</p><p>蠢问题：</p><blockquote><p>我的主机板有问题了，谁来帮我？</p></blockquote><p>某黑客对这类问题的回答通常是：好的，还要帮你拍拍背和换尿布吗？，然后按下删除键。</p><p>聪明问题：</p><blockquote><p>我在 S2464 主机板上试过了 X 、 Y 和 Z ，但没什么作用，我又试了 A 、 B 和 C 。请注意当我尝试 C 时的奇怪现象。显然 florbish 正在 grommicking，但结果出人意料。通常在 Athlon MP 主机板上引起 grommicking 的原因是什么？有谁知道接下来我该做些什么测试才能找出问题？</p></blockquote><p>这个家伙，从另一个角度来看，值得去回答他。他表现出了解决问题的能力，而不是坐等天上掉答案。</p><p>在最后一个问题中，注意告诉我答案和给我启示，指出我还应该做什么诊断工作之间微妙而又重要的区别。</p><p>事实上，后一个问题源自于 2001 年 8 月在 Linux 内核邮件列表（lkml）上的一个真实的提问。我（Eric）就是那个提出问题的人。我在 Tyan S2464 主板上观察到了这种无法解释的锁定现象，列表成员们提供了解决这一问题的重要信息。</p><p>通过我的提问方法，我给了别人可以咀嚼玩味的东西；我设法让人们很容易参与并且被吸引进来。我显示了自己具备和他们同等的能力，并邀请他们与我共同探讨。通过告诉他们我所走过的弯路，以避免他们再浪费时间，我也表明了对他们宝贵时间的尊重。</p><p>事后，当我向每个人表示感谢，并且赞赏这次良好的讨论经历的时候， 一个 Linux 内核邮件列表的成员表示，他觉得我的问题得到解决并非由于我是这个列表中的名人，而是因为我用了正确的方式来提问。</p><p>黑客从某种角度来说是拥有丰富知识但缺乏人情味的家伙；我相信他是对的，如果我像个乞讨者那样提问，不论我是谁，一定会惹恼某些人或者被他们忽视。他建议我记下这件事，这直接导致了本指南的出现。</p><h2 id="如果得不到回答">如果得不到回答<a class="fa-solid fa-hashtag" href="#如果得不到回答"></a></h2><p>如果仍得不到回答，请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。没有回应不代表你被忽视，虽然不可否认这种差别很难区分。</p><p>总的来说，简单的重复张贴问题是个很糟的点子。这将被视为无意义的喧闹。有点耐心，知道你问题答案的人可能生活在不同的时区，可能正在睡觉，也有可能你的问题一开始就没有组织好。</p><p>你可以通过其他渠道获得帮助，这些渠道通常更适合初学者的需要。</p><p>有许多网上的以及本地的使用者群组，由热情的软件爱好者（即使他们可能从没亲自写过任何软件）组成。通常人们组建这样的团体来互相帮助并帮助新手。</p><p>另外，你可以向很多商业公司寻求帮助，不论公司大还是小。别为要付费才能获得帮助而感到沮丧！毕竟，假使你的汽车发动机汽缸密封圈爆掉了 —— 完全可能如此 —— 你还得把它送到修车铺，并且为维修付费。就算软件没花费你一分钱，你也不能强求技术支持总是免费的。</p><p>对像是 Linux 这种大众化的软件，每个开发者至少会对应到上万名使用者。根本不可能由一个人来处理来自上万名使用者的求助电话。要知道，即使你要为这些协助付费，和你所购买的同类软件相比，你所付出的也是微不足道的（通常封闭源代码软件的技术支持费用比开源软件的要高得多，且内容也没那么丰富）。</p><h2 id="如何更好地回答问题">如何更好地回答问题<a class="fa-solid fa-hashtag" href="#如何更好地回答问题"></a></h2><p>态度和善一点。问题带来的压力常使人显得无礼或愚蠢，其实并不是这样。</p><p>对初犯者私下回复。对那些坦诚犯错之人没有必要当众羞辱，一个真正的新手也许连怎么搜索或在哪找常见问题都不知道。</p><p>如果你不确定，一定要说出来！一个听起来权威的错误回复比没有还要糟，别因为听起来像个专家很好玩，就给别人乱指路。要谦虚和诚实，给提问者与同行都树个好榜样。</p><p>如果帮不了忙，也别妨碍他。不要在实际步骤上开玩笑，那样也许会毁了使用者的设置 —— 有些可怜的呆瓜会把它当成真的指令。</p><p>试探性的反问以引出更多的细节。如果你做得好，提问者可以学到点东西 —— 你也可以。试试将蠢问题转变成好问题，别忘了我们都曾是新手。</p><p>尽管对那些懒虫抱怨一声 RTFM 是正当的，能指出文件的位置（即使只是建议个 Google 搜索关键词）会更好。</p><p>如果你决定回答，就请给出好的答案。当别人正在用错误的工具或方法时别建议笨拙的权宜之计（workaround），应推荐更好的工具，重新界定问题。</p><p>正面的回答问题！如果这个提问者已经很深入的研究而且也表明已经试过 X 、 Y 、 Z 、 A 、 B 、 C 但没得到结果，回答 试试看 A 或是 B 或者 试试 X 、 Y 、 Z 、 A 、 B 、 C 并附上一个链接一点用都没有。</p><p>帮助你的社区从问题中学习。当回复一个好问题时，问问自己如何修改相关文件或常见问题文件以免再次解答同样的问题？，接着再向文件维护者发一份补丁。</p><p>如果你是在研究一番后才做出的回答，展现你的技巧而不是直接端出结果。毕竟授人以鱼不如授人以渔。</p><h2 id="相关资源">相关资源<a class="fa-solid fa-hashtag" href="#相关资源"></a></h2><p>如果你需要个人电脑、Unix 系统和网络如何运作的基础知识，参阅 Unix 系统和网络基本原理。</p><p>当你发布软件或补丁时，试着按软件发布实践操作。</p><h2 id="鸣谢">鸣谢<a class="fa-solid fa-hashtag" href="#鸣谢"></a></h2><p>Evelyn Mitchel 贡献了一些愚蠢问题例子并启发了编写如何更好地回答问题这一节， Mikhail Ramendik 贡献了一些特别有价值的建议和改进。</p>]]></c:encoded></item><item><title>Waline 评论系统部署日志</title><link>https://blog.ccknbc.cc/posts/waline-comments-system-deployment-logs/</link><description>Waline 评论系统部署日志，希望你也能用上这款评论系统</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%B7%A5%E5%85%B7/">工具</category><category domain="https://blog.ccknbc.cc/tags/%E5%B7%A5%E5%85%B7/">工具</category><pubDate>Fri, 10 Jul 2026 01:27:42 GMT</pubDate><c:encoded><![CDATA[<div class="note danger simple"><p>本文大部分内容已作废，请直接查看<a href="https://waline.js.org/"><strong>官方文档</strong></a></p></div><p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/20/"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/waline-commens-system-deployment-logs/"><strong>CC的部落格</strong></a></p><p><strong>本文仅作为官方文档的补充，若有错误，还望指正</strong></p><p><a href="https://ccknbc.now.sh/posts/waline-commens-system-deployment-logs/#Todo">Waline 评论系统部署日志</a></p><hr><p>Waline - 一款从 <a href="https://valine.js.org">Valine</a> 衍生的带后端评论系统。可以将 Waline 等价成 With backend Valine.</p><h2 id="特性">特性<a class="fa-solid fa-hashtag" href="#特性"></a></h2><ul><li>快速</li><li>真·安全</li><li>Markdown 语法支持</li><li>轻量易用</li><li>免费部署</li><li>多种部署部署方式和存储服务支持，每列选择一项多达 84 种（可以更多）部署方式任君选择</li></ul><table><thead><tr><th></th><th>Waline</th><th></th></tr></thead><tbody><tr><td><strong>客户端脚本</strong></td><td><strong>服务端部署</strong></td><td><strong>数据存储</strong></td></tr><tr><td><a href="https://waline.js.org/"><strong>@waline/client</strong></a></td><td>Vercel</td><td>LeanCloud</td></tr><tr><td><a href="https://minivaline.js.org/"><strong>MiniValine</strong></a></td><td>CloudBase</td><td>CloudBase</td></tr><tr><td><a href="https://github.com/innc11/AprilComment"><strong>AprilComment</strong></a></td><td>Docker</td><td>MongoDB</td></tr><tr><td></td><td>独立部署</td><td>MySQL</td></tr><tr><td></td><td></td><td>SQLite</td></tr><tr><td></td><td></td><td>PostgreSQL</td></tr><tr><td></td><td></td><td>GitHub</td></tr></tbody></table><p>对于想免费使用的用户， <code>Vercel</code>  + <code>LeanCloud（国际版）</code>  是不错的选择，不过<code>Deta</code>一个服务就能解决所有问题而且还快点，如果你主要面向对象为大陆用户，使用 <code>CloudBase</code>  部署也是个不错的选择，它在海外表现也没那么差，或者您仅使用 <code>CloudBase</code>  来做数据存储</p><p><font style="color:#333333;"><div class="note warning simple"><p>如果您使用 </font> <code>Vercel</code> + <code>LeanCloud</code> ，并且使用 <code>Vercel</code>  发送评论通知，您不必担心 LeanCloud 流控问题，并且之前使用过 Valine 或者部署过 <code>Valine-Admin</code>  项目的可以直接拿来用；对于评论转移，官方提供了<a href="https://waline.js.org/migration/tool.html">迁移助手</a>供您使用，不用担心之前评论丢失的问题<font style="color:#333333;"></p></div></font></p><h2 id="Todo">Todo<a class="fa-solid fa-hashtag" href="#Todo"></a></h2><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;> 微信通知</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>QQ 通知</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>Telegram 通知</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>Akismet</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>文章统计</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>多语言同步</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>自定义语言支持</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;> 登录支持</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>评论管理</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>评论删除</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p>其它数据库支持 </font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>基于 IP 的发布评论频率限制</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>基于关键词的评论过滤限制</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>IP 黑名单</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>重复内容检测</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>CloudBase 腾讯云开发部署支持</font><font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p></font><font style=color:#333333;>社交登录</p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox red'><input type="checkbox" />            <p></font>AWS</p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox red'><input type="checkbox" />            <p></font>置顶评论<font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox red'><input type="checkbox" />            <p></font>评论赞踩<font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class='checkbox blue'><input type="checkbox" />            <p></font>其它…<font style=color:#333333;></p>            </div></font></p><p><font style="color:#333333;"><div class="note warning simple"><p>目前社交登录仅支持 </font><code>&lt;font style=&quot;color:#333333;&quot;&gt;GitHub&lt;/font&gt;</code> <font style="color:#333333;">， 未来会支持更多平台</p></div></font></p><hr><h2 id="Vercel-LeanCloud-部署">Vercel + LeanCloud 部署<a class="fa-solid fa-hashtag" href="#Vercel-LeanCloud-部署"></a></h2><p>这部分请前往<a href="https://waline.js.org/quick-start.html">官方文档</a>查看，不过需要注意的是如果你的 <code>GitHub</code>  账号主邮箱是 <code>QQ</code> 邮箱的话建议更改为其他邮箱（毕竟他们认为QQ邮箱是垃圾邮箱）再去注册   Vercel（或者你可以选择给客服发一封邮件让他们帮忙解锁你的账号），环境变量配置部分官方文档也写了，这里不再赘述</p><p>如果您之前用过 Valine，那么关于 LeanCloud 部分你就不用做什么了，数据兼容，拿到那几个 <code>key</code> 即可</p><h3 id="配置项">配置项<a class="fa-solid fa-hashtag" href="#配置项"></a></h3><p>这个可直接参考官方文档按需进行配置即可，因为目前云开发因众所周知的原因不支持连接 <code>Telegram</code> 服务器，所以如果您要配置电报新评论通知，请使用 Vercel 进行配置，不过因为目前没有异步通知，加上反垃圾检测等功能，发布评论可能需要很长时间，这个我使用了 LeanCloud 来继续帮我发送通知（反正我也没什么评论，流控问题第二天补发评论也不是不可）</p><p><font style="color:#333333;"><div class="note warning simple"><p>对于邮件通知部分，目前的设定是，对于新评论，如果博主配置了 QQ/微信/Telegram 通知中任意一种或多种，则邮件通知将会取消，而对于回复（子评论），博主和被回复者（如果填了邮箱的话）均可收到邮件通知</p></div></font></p><p><font style="color:#333333;">我目前使用的 Hexo Butterfly 主题已经从 3.5.0 beta3 版本起内置了 Waline 评论系统，如果您使用老版本主题请升级，或者根据您所用版本的 Valine 模板 pug 来照葫芦画瓢，根据官方配置进行对应修改，主题中 option 为可选配置，万一将来增加了某些配置，主题不必为此升级, bg 为主题配置项</font></p><p>这里注意一下 serverURL 以及环境变量里的 SITE_URL 网址最后的斜杠因为作者没做兼容，所以不要带上 / ，导致跳转不到对应评论界面</p><p>客户端脚本里可以通过 <code>langMode.admin</code>  这个配置自定义角标的文案,例如：</p><figure class="highlight javascript"><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="keyword">function</span> <span class="title function_">waline</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> <span class="title class_">Waline</span> = <span class="built_in">require</span>(<span class="string">&#x27;@waline/client&#x27;</span>);</span><br><span class="line">  <span class="keyword">new</span> <span class="title class_">Waline</span>(&#123;</span><br><span class="line">    <span class="attr">el</span>: <span class="string">&#x27;#waline-comment&#x27;</span>,</span><br><span class="line">    <span class="attr">serverURL</span>: <span class="string">&#x27;https://waline.vercel.app&#x27;</span>,</span><br><span class="line">    <span class="attr">path</span>: <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">pathname</span>,</span><br><span class="line">    <span class="attr">visitor</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">lang</span>: location.<span class="property">pathname</span>.<span class="title function_">startsWith</span>(<span class="string">&#x27;/en/&#x27;</span>) ? <span class="string">&#x27;en&#x27;</span> : <span class="string">&#x27;zh-CN&#x27;</span>,</span><br><span class="line">    <span class="attr">langMode</span>: &#123;</span><br><span class="line">      <span class="attr">admin</span>: location.<span class="property">pathname</span>.<span class="title function_">startsWith</span>(<span class="string">&#x27;/en/&#x27;</span>) ? <span class="string">&#x27;Administrator&#x27;</span> : <span class="string">&#x27;可爱的管理员&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>对于同主题在主题配置里找到 <code>waline</code>  配置项相关内容</p><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><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"># waline - A simple comment system with backend support fork from Valine</span></span><br><span class="line"><span class="comment"># https://waline.js.org/</span></span><br><span class="line"><span class="attr">waline:</span></span><br><span class="line">  <span class="attr">serverURL:</span> <span class="string">https://waline.ccknbc.ml</span> <span class="comment"># Waline server address url</span></span><br><span class="line">  <span class="attr">avatar:</span> <span class="string">monsterid</span> <span class="comment"># gravatar style https://zh-tw.gravatar.com/site/implement/images/#default-image</span></span><br><span class="line">  <span class="attr">bg:</span> <span class="comment"># waline background</span></span><br><span class="line">  <span class="attr">emojiCDN:</span> <span class="string">https://cdn.jsdelivr.net/gh/GamerNoTitle/ValineCDN@master/</span></span><br><span class="line">  <span class="attr">visitor:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">option:</span> </span><br><span class="line">    <span class="attr">pageSize:</span> <span class="number">10</span></span><br><span class="line">    <span class="attr">requiredFields:</span> <span class="string">mail</span></span><br><span class="line">    <span class="comment"># anonymous: false </span></span><br><span class="line">    <span class="attr">placeholder:</span>                                                                                      </span><br><span class="line">    <span class="attr">avatarCDN:</span> <span class="string">https://sdn.geekzu.org/avatar/</span></span><br><span class="line">    <span class="comment">#https://valinecdn.bili33.top/</span></span><br><span class="line">    <span class="attr">langMode:</span></span><br><span class="line">      <span class="attr">admin:</span> <span class="string">博主兼管理员</span></span><br><span class="line">      <span class="attr">nick:</span> <span class="string">昵称(选填)</span></span><br><span class="line">      <span class="attr">mail:</span> <span class="string">邮箱(必填)</span></span><br><span class="line">      <span class="attr">link:</span> <span class="string">网址(选填)</span></span><br><span class="line">      <span class="attr">sofa:</span> <span class="string">这里冷冷清清的，快来留下脚印吧！</span></span><br><span class="line"> <span class="comment"># 如果你查看了源码，会发现还有这个可以配置 copyRight: false，但不建议大家设为 false 啦，保留也没什么的（没错，我不要脸）</span></span><br></pre></td></tr></table></figure><p><s>还有就是可能有人会觉得默认邮件通知模板太单调，想和 Valine-Admin 一样切换模板，其实有这个配置的，只是目前的方法是写在环境变量中，而环境变量限制长度（大小），或者说是不适合这种方式配置，如果要改的话可以先查看</s><a href="https://github.com/lizheming/waline/issues/106"><s>issues/106</s></a><s>相关内容，或者等以后优化再说；当然如果你的评论不是很多，并且之前配置过 Valine-Admin，那么你仍然可以使用 LeanCloud 来做异步发送通知，关闭默认的通知配置，或者使用 js 推送</s></p><p>关于邮件模板大家可查看<a href="https://waline.js.org/server/notification.html#%E9%80%9A%E7%9F%A5%E6%A8%A1%E6%9D%BF">官方文档</a>相关章节，或者使用<a href="#%E9%82%AE%E4%BB%B6%E9%80%9A%E7%9F%A5%E6%A8%A1%E6%9D%BF">附录提供的邮件通知模板</a>，也提交了 PR</p><p><a href="https://waline.js.org/server/basic.html#%E8%AF%84%E8%AE%BA-hooks">评论 Hooks</a>，可以根据官方的例子自己做一些配置，相比于其他，违禁词，屏蔽IP等配置可以说是人性化了，但万一配置不好一些正常评论可能也会被判定为垃圾内容，所以我推荐使用人工审核功能，不过这边不得不说另一个评论系统 <a href="https://twikoo.js.org/">Twikoo</a>，支持查看自己审核中的评论，评论置顶，点赞等，不过我想 Waline 将来也能实现，毕竟 Flag 立那了</p><p>图片上传 uploadImage 部分配置 理论上是可以适配任何图床，配置例子可查看 <a href="https://github.com/lizheming/waline/issues/123">issues/123</a>，当然内置了一个默认图床，开箱即用</p><p>表情配置和之前 Valine 是一样的，同主题还可使用 <code>walien.json</code> 的配置方式，具体可查看<a href="https://butterfly.js.org/posts/ceeb73f/#%E8%A9%95%E8%AB%96">主题文档</a></p><h2 id="CloudBase-云开发部署">CloudBase 云开发部署<a class="fa-solid fa-hashtag" href="#CloudBase-云开发部署"></a></h2><h3 id="一键部署">一键部署<a class="fa-solid fa-hashtag" href="#一键部署"></a></h3><p>一键脚本部署可以查看<a href="https://waline.js.org/server/cloudbase.html">官方文档</a>，我删了之后就没成功过</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612362992018-14b2a225-27d6-4996-948b-e746d26bb2e0.png" alt="" loading="lazy"></p><p>截至文档最新更新日期，这个已被修复（不过tcb-starter那个链接还没改所以还是失败），不过我只能说作者非常不细心，毕竟能一天发十几个版本，详见 <a href="https://github.com/lizheming/waline/commit/d87d3092a34fd6b2b7f0b1c72bd95ad784a086e7">commit</a>，他还是把链接协议头多打了一个 h ,所以请<a href="https://console.cloud.tencent.com/tcb/env/index?action=CreateAndDeployCloudBaseProject&amp;appUrl=https%3A%2F%2Fgithub.com%2Fwalinejs%2Ftcb-starter&amp;branch=master&amp;appName=waline">点击这里</a>一键部署</p><p>嗯，后来修复了，期待接下来的开发</p><hr><p>警告内容来自 <a href="https://twikoo.js.org/quick-start.html">Twikoo 官方文档</a> 建议您直接查看 <a href="#%E6%89%8B%E5%8A%A8%E9%83%A8%E7%BD%B2">手动部署部分</a>！！！</p><p><font style="color:#333333;"><div class="note warning simple"><p></font></p></p><p>一键部署虽然方便，但是仅支持按量计费环境——也就是说，<strong>一键部署的环境，当免费资源用尽后，将会产生费用</strong>。且按量计费环境无法切换为包年包月环境。免费额度数据库读操作数只有 500 次 / 天，<strong>无法支撑 Twikoo 的运行需求</strong>。Twikoo 建议您<a href="#%E6%89%8B%E5%8A%A8%E9%83%A8%E7%BD%B2">手动部署</a>以节约成本。</p><p><font style="color:#333333;"></div></font></p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1610953378969-db93161e-24d3-4a48-8934-5566774b94d2.png" alt="" loading="lazy"></p><p>对于新用户或者说没有创建过按量计费环境的用户会显示如下内容，记得勾选开启免费资源</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1610873567827-825cde85-7c99-4c5a-95e0-44c0966784cb.png" alt="" loading="lazy"></p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612859364523-006d98ba-bd5c-4868-878f-9c9ac158d836.png" alt="" loading="lazy"></p><p>为了日后升级的方便，不管您是否使用了 Vercel 部署，您都可以 fork <a href="https://github.com/ccknbc-actions/waline">我的仓库</a> ，稍加配置即可完成自动部署更新</p><h3 id="手动部署">手动部署<a class="fa-solid fa-hashtag" href="#手动部署"></a></h3><p>首先前往<a href="https://cloud.tencent.com/act/pro/cloudbase01"><strong>腾讯云的活动区域</strong></a>，注册/登陆后往下滑，找到新用户专享云开发标准型（基础版1）资源套餐，0元购买一个免费包年包月环境</p><hr><p>没错，这个环境不错吧</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1610870670315-08e65148-3819-48fb-878e-03fdb0c9ab64.png" alt="" loading="lazy"></p><p>按照提示购买后稍等几分钟，<a href="https://console.cloud.tencent.com/tcb/env/index">在这个界面可查看您所购买的环境</a></p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1610870083481-8e4cad1a-c70a-4cad-9192-11be8003241c.png" alt="" loading="lazy"></p><p>有能力的其实可以看一下 Vercel <a href="#%E8%87%AA%E5%8A%A8%E5%8D%87%E7%BA%A7">自动升级</a>和TCB<a href="#%E8%87%AA%E5%8A%A8%E5%8D%87%E7%BA%A7-1">自动升级</a>部分，间接实现一键部署，自动更新</p><p><a href="https://console.cloud.tencent.com/tcb/scf/index">点击云函数</a>，新建云函数，函数内存选择 128M，名称随意，例如 Waline，其他默认,单击进入下一步</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612359288449-66b53150-2146-4ec9-aa08-910b99aebd1b.png" alt="" loading="lazy"></p><p>下图中的函数代码部分填入以下代码</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612359460424-4b8cf9b4-2ef4-4758-92f6-09ae040a91ea.png" alt="" loading="lazy"></p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Tencent is pleased to support the open source community by making CloudBaseFramework - 云原生一体化部署工具 available.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Please refer to license text included with this package for license details.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span>.<span class="property">main</span> = <span class="title function_">async</span> (event, context) =&gt; &#123;</span><br><span class="line">  context.<span class="property">callbackWaitsForEmptyEventLoop</span> = <span class="literal">false</span>;</span><br><span class="line">  <span class="keyword">const</span> entry = (<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> result = <span class="built_in">require</span>(<span class="string">&#x27;./app.js&#x27;</span>);</span><br><span class="line">    <span class="comment">// const app = require(&#x27;express&#x27;)();</span></span><br><span class="line">    <span class="comment">// result = app.use(result);</span></span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">  &#125;)();</span><br><span class="line">  <span class="keyword">const</span> serverless = <span class="built_in">require</span>(<span class="string">&#x27;serverless-http&#x27;</span>);</span><br><span class="line">  <span class="keyword">let</span> app = entry;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// support for async load app</span></span><br><span class="line">  <span class="keyword">if</span> (entry &amp;&amp; entry.<span class="property">tcbGetApp</span> &amp;&amp; <span class="keyword">typeof</span> entry.<span class="property">tcbGetApp</span> === <span class="string">&#x27;function&#x27;</span>) &#123;</span><br><span class="line">    app = <span class="keyword">await</span> entry.<span class="title function_">tcbGetApp</span>();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">serverless</span>(app, &#123;</span><br><span class="line">    <span class="attr">binary</span>: [</span><br><span class="line">      <span class="string">&#x27;application/javascript&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;application/json&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;application/octet-stream&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;application/xml&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;font/eot&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;font/opentype&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;font/otf&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;image/*&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;video/*&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;audio/*&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;text/comma-separated-values&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;text/css&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;text/javascript&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;text/plain&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;text/text&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;text/xml&#x27;</span>,</span><br><span class="line">    ],</span><br><span class="line">  &#125;)(event, context);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>点击对应的云函数，进入在线编辑页面，按照<a href="https://github.com/walinejs/tcb-starter">模板仓库</a>里的文件，新建对应的文件，并复制粘贴对应的内容即可</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612360652232-9eb2ad2b-bebe-4964-bb5f-75e2f9946d25.png" alt="" loading="lazy"></p><p>注意点击<strong>保存并安装依赖</strong>，可能会没有反应一会儿，然后等待转圈圈部署完毕即可</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612360855940-241970ec-5c18-4bc8-9168-9fd945deb761.png" alt="" loading="lazy"><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612361085479-f39b6b2b-2293-4685-882e-9e20aa611dea.png" alt="" loading="lazy"></p><p>当然还没有结束，我们需要点击 <code>环境 --&gt; HTTP 访问服务</code> （<a href="https://console.cloud.tencent.com/tcb/env/access">点击直达</a>)，如果你想绑定自定义域名可以照图中绑定，记得先申请一下证书，如果你想要 HTTPS（这个可能花的时间有点长）</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612361294908-3ef584b5-5cbc-43e5-b744-cda357057ec0.png" alt="" loading="lazy"></p><p>点击新建，新建触发路径，点击保存即可，注意路径最后没有 / ，等待构建完成后你就可通过对应的链接访问 demo 页面了，这个链接就是上面提到的 <code>serverURL</code> ，例如我的 <a href="https://tcb.ccknbc.cc/waline">https://tcb.ccknbc.cc/waline</a></p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612361631129-fecd45a5-f694-4154-8707-9976eb10adb5.png" alt="" loading="lazy"></p><p>然后我们需要设置<a href="https://console.cloud.tencent.com/tcb/env/safety"> WEB 安全域名</a>，把你的域名放入白名单即可（本地测试的话端口也要对应上哦）</p><h2 id="如何升级">如何升级<a class="fa-solid fa-hashtag" href="#如何升级"></a></h2><h3 id="Vercel">Vercel<a class="fa-solid fa-hashtag" href="#Vercel"></a></h3><h4 id="手动升级">手动升级<a class="fa-solid fa-hashtag" href="#手动升级"></a></h4><p>找到 Vercel 帮你在创建的仓库，叫 <code>waline</code> 啦，编辑 <code>package.json</code> 中依赖版本号即可完成升级，版本号以 <code>npm</code> <img src="https://img.shields.io/npm/v/@waline/vercel?color=critical&amp;logo=npm&amp;style=flat-square" alt="" loading="lazy"><font style="color:#2C3E50;"> 为准，因为 GitHub 由于考虑到电报机器人自动推送消息过于频繁影响到群友，会延迟推送</font></p><h4 id="自动升级">自动升级<a class="fa-solid fa-hashtag" href="#自动升级"></a></h4><p>其实原理还是一样的，因为Vercel会监控仓库文件的变化来帮我们自动部署，那么我们要做的就是自动更改版本号，这里你可以用 <code>Github Actions</code> 实现，定时每隔半小时自动更新并push，但这样似乎有点浪费资源，所以不怎么推荐，而我们这个仓库通常都是公开的（私有也没关系）</p><p>首先你需要安装一个应用<a href="https://github.com/marketplace/renovate">Renovate</a>,选择免费版计划即可，他会帮我们监控所用依赖的版本更新变化，并为提交一个 <code>PR</code> ，我们要做的只是合并 PR 而已，但手动合并之前也讲过，多少有点不方便，自动合并我们知道有打标签自动合并，GitHub Actions 工具人自动合并，这些大家搜以下关键词就好，但这个应用它本身实际上支持自动合并，查看<a href="https://docs.renovatebot.com/configuration-options/#automerge">官方文档</a>发现在 <code>renovate.json</code> 中配置即可，示例代码如下，其中代理人是为了通知更新的作用，与PR同理，但也可删除此段配置，同样的PR也可关闭通知静默自动更新。</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><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;extends&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;config:base&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;assignees&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;CCKNBC&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;separateMinorPatch&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;packageRules&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;updateTypes&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">          <span class="string">&quot;minor&quot;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="string">&quot;patch&quot;</span></span><br><span class="line">      <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;automerge&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;automergeType&quot;</span><span class="punctuation">:</span> <span class="string">&quot;branch&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>我目前还是用的默认的提交PR自动合并的方式，如果你是公开仓库，还可以使用<a href="https://github.com/marketplace/mergify">Mergify</a>，安装完成后他能它免费帮我们自动合并公开仓库的PR，我们设定一个条件，比如 PR 提交作者为 renovate，就自动帮我们点击合并，并删除多余分支，当然这些都需要配置，这里具体会在另一篇文档中讲到</p><p><font style="color:#333333;"><div class="note info simple"><p></font>以上两个应用你可以选择安装到全部仓库，或者只安装到选择的仓库<font style="color:#333333;"></p></div></font></p><p>如果你想懒的话可以先删除你现有的名为 Waine 的仓库，再 fork <a href="https://github.com/ccknbc-actions/waline">我的仓库</a>，然后去你的 Vercel 解绑之前的仓库，再绑定你fork的仓库，最后点一下重新部署即可</p><p>但是如果你没用tcb 就把  <code>.github/workflows/Update Waline TCB.yml</code>  里的文件删掉，因为涉及到自动部署更新云开发，还有环境变量问题，如果没设定会导致报错</p><h3 id="CloudBase">CloudBase<a class="fa-solid fa-hashtag" href="#CloudBase"></a></h3><hr><h4 id="一键部署-2">一键部署<a class="fa-solid fa-hashtag" href="#一键部署-2"></a></h4><p>就是点击<a href="https://console.cloud.tencent.com/tcb/apps/index">我的应用</a>找到 Waline 点击部署即可</p><p><img src="https://cdn.nlark.com/yuque/0/2021/png/8391407/1612711217029-250d0b1a-75d1-4a7c-9f4c-8a9413ab51fa.png" alt="" loading="lazy"></p><h4 id="手动部署-2">手动部署<a class="fa-solid fa-hashtag" href="#手动部署-2"></a></h4><h5 id="手动升级-2">手动升级<a class="fa-solid fa-hashtag" href="#手动升级-2"></a></h5><p>就是去<a href="https://github.com/walinejs/tcb-starter">仓库</a>复制粘贴修改过的文件的事情了，如果没有文件改动就点击 <code>保存并安装依赖</code> 即可（知道在哪了吧）</p><h5 id="自动升级-2">自动升级<a class="fa-solid fa-hashtag" href="#自动升级-2"></a></h5><p>原理在上面讲了，结合 <a href="#%E8%87%AA%E5%8A%A8%E5%8D%87%E7%BA%A7">Vercel 自动升级</a>部分查看，这部分其实可以作为上面的手动部署，或者自动部署？</p><p>你可以 fork <a href="https://github.com/ccknbc-actions/waline">我的仓库</a> 进行更改，和上面提到的原理差不多，只是用到了 Actions（如果你之前没接触过这些，建议使用 Vercel 部署或者上面的一键部署，也比较方便），在合并PR后帮我们自动升级部署到云开发，解释一下几个密钥，您需要在 仓库的 <code>settings/secrets/actions</code> 中配置，组织的话可以把常用到的密钥添加为组织密钥</p><p>，比如 ID KEY 等</p><table><thead><tr><th>变量名</th><th>变量解释</th></tr></thead><tbody><tr><td><font style="color:#404040;background-color:#FFFFFF;">SECRETID</font></td><td>API 访问密钥 ID，可<a href="https://console.cloud.tencent.com/cam/capi">点击这里</a>新建/查看</td></tr><tr><td><font style="color:#404040;background-color:#FFFFFF;">SECRETKEY</font></td><td><font style="color:#404040;background-color:#FFFFFF;">API 访问密钥 KEY，可</font><a href="https://console.cloud.tencent.com/cam/capi">点击这里</a><font style="color:#404040;background-color:#FFFFFF;">新建/查看</font></td></tr><tr><td>TCBFUNNAME（没什么好加密的，就叫 waline 算了）</td><td>你想要新建/已有函数的名称，比如 <code>Waline</code></td></tr><tr><td>TCBENVID</td><td>环境ID，可<a href="https://console.cloud.tencent.com/tcb/env/overview">点击这里</a>或<a href="https://console.cloud.tencent.com/tcb/env/index">这里</a>查看，地址栏后也会显示，反正就是很多地方都在上面点一下就能看到</td></tr></tbody></table><h2 id="附录">附录<a class="fa-solid fa-hashtag" href="#附录"></a></h2><h3 id="邮件通知模板">邮件通知模板<a class="fa-solid fa-hashtag" href="#邮件通知模板"></a></h3><figure class="highlight javascript"><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="attr">mailSubject</span>: <span class="string">&#x27;&#123;&#123;parent.nick&#125;&#125;，您在 &#123;&#123;site.name&#125;&#125; 上发表的评论,收到了来自 &#123;&#123;self.nick&#125;&#125; 的回复&#x27;</span>,</span><br><span class="line"><span class="attr">mailSubjectAdmin</span>: <span class="string">&#x27;&#123;&#123;site.name&#125;&#125; 上收到了来自 &#123;&#123;self.nick&#125;&#125; 的留言&#x27;</span>,</span><br><span class="line"><span class="attr">mailTemplate</span>: <span class="string">&#x27;&lt;head&gt;&lt;base target=&quot;_blank&quot;/&gt;&lt;style id=&quot;scrollbar&quot;type=&quot;text/css&quot;&gt;::-webkit-scrollbar&#123;width:0!important&#125;pre&#123;white-space:pre-wrap!important;word-wrap:break-word!important;*white-space:normal!important&#125;pre&#123;white-space:pre-wrap!important;word-wrap:break-word!important;*white-space:normal!important&#125;#letter img&#123;max-width:300px&#125;&lt;/style&gt;&lt;style id=&quot;from-wrapstyle&quot;type=&quot;text/css&quot;&gt;#form-wrap&#123;overflow:hidden;height:447px;position:relative;top:0px;transition:all 1s ease-in-out.3s;z-index:0&#125;&lt;/style&gt;&lt;style id=&quot;from-wraphoverstyle&quot;type=&quot;text/css&quot;&gt;#form-wrap:hover&#123;height:1300px;top:-200px&#125;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div style=&quot;width: 530px;margin: 20px auto 0;height: 1000px;&quot;&gt;&lt;div id=&quot;form-wrap&quot;&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/Akilarlxh/Valine-Admin@v1.0/source/img/before.png&quot;alt=&quot;before&quot;style=&quot;position: absolute;bottom: 126px;left: 0px;background-repeat: no-repeat;width: 530px;height: 317px;z-index:-100&quot;&gt;&lt;div style=&quot;position: relative;overflow: visible;height: 1500px;width: 500px;margin: 0px auto;transition: all 1s ease-in-out .3s;padding-top:200px;&quot;&lt;form&gt;&lt;div style=&quot;background: white;width: 95%;max-width: 800px;margin: auto auto;border-radius: 5px;border: 1px solid;overflow: hidden;-webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.12);box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.18);&quot;&gt;&lt;img style=&quot;width:100%;overflow: hidden;&quot;src=&quot;https://area.sinaapp.com/bingImg&quot;/&gt;&lt;div style=&quot;padding: 5px 20px;&quot;&gt;&lt;br&gt;&lt;div&gt;&lt;h3 style=&quot;text-decoration: none; color: #8fbc8f;&quot;&gt;&#123;&#123;parent.nick&#125;&#125;，见信安：&lt;/h3&gt;&lt;/div&gt;&lt;br&gt;&lt;div id=&quot;letter&quot;style=&quot;overflow:auto;height:300px;width:100%;display:block;word-break: break-all;word-wrap: break-word;&quot;&gt;&lt;p style=&quot;display: inline-block;&quot;&gt;您在&lt;a style=&quot;text-decoration: none;color: #8fbc8f&quot;target=&quot;_blank&quot;href=&quot;&#123;&#123;site.postUrl&#125;&#125; display: inline-block;&quot;&gt;&#123;&#123;site.name&#125;&#125;&lt;/a&gt;上发表的评论:&lt;/p&gt;&lt;div style=&quot;border-bottom: #ddd 1px solid;border-left: #ddd 1px solid;padding-bottom: 20px;background-color: #eee;margin: 15px 0px;padding-left: 20px;padding-right: 20px;border-top: #ddd 1px solid;border-right: #ddd 1px solid;padding-top: 20px;font-family: &quot;Arial&quot;, &quot;Microsoft YaHei&quot; , &quot;黑体&quot; , &quot;宋体&quot; , sans-serif;&quot;&gt;&#123;&#123;parent.comment | safe&#125;&#125;&lt;/div&gt;&lt;p&gt;收到了来自&#123;&#123;self.nick&#125;&#125;的回复：&lt;/p&gt;&lt;div style=&quot;border-bottom: #ddd 1px solid;border-left: #ddd 1px solid;padding-bottom: 20px;background-color: #eee;margin: 15px 0px;padding-left: 20px;padding-right: 20px;border-top: #ddd 1px solid;border-right: #ddd 1px solid;padding-top: 20px;font-family: &quot;Arial&quot;, &quot;Microsoft YaHei&quot; , &quot;黑体&quot; , &quot;宋体&quot; , sans-serif;&quot;&gt;&#123;&#123;self.comment | safe&#125;&#125;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div style=&quot;text-align: center;margin-top: 40px;&quot;&gt;&lt;img src=&quot;https://ae01.alicdn.com/kf/U0968ee80fd5c4f05a02bdda9709b041eE.png&quot;alt=&quot;hr&quot;style=&quot;width:100%; margin:5px auto 5px auto; display: block;&quot;/&gt;&lt;a style=&quot;text-transform: uppercase;text-decoration: none;font-size: 14px;border: 2px solid #ace0f9;color: #FFFFFF;padding: 10px;display: inline-block;margin: 10px auto 0;background-color: #8fbc8f;&quot;target=&quot;_blank&quot;href=&quot;&#123;&#123;site.postUrl&#125;&#125;&quot;&gt;&#123;&#123;site.name&#125;&#125;｜请您签收~&lt;/a&gt;&lt;/div&gt;&lt;p style=&quot;font-size: 12px;text-align: center;color: #999;&quot;&gt;自动书记人偶竭诚为您服务！&lt;br&gt;©2020 - 2021 &lt;a style=&quot;text-decoration:none; color:#8fbc8f&quot;href=&quot;&#123;&#123;site.url&#125;&#125;&quot;&gt;&#123;&#123;site.name&#125;&#125;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/form&gt;&lt;/div&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/Akilarlxh/Valine-Admin@v1.0/source/img/after.png&quot;alt=&quot;after&quot;style=&quot;      position: absolute;bottom: -2px;left: 0;background-repeat: no-repeat;width: 530px;height: 259px;z-index:100&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/body&gt;&#x27;</span>,</span><br><span class="line"><span class="attr">mailTemplateAdmin</span>: <span class="string">&#x27;&lt;head&gt;&lt;base target=&quot;_blank&quot;/&gt;&lt;style id=&quot;scrollbar&quot;type=&quot;text/css&quot;&gt;::-webkit-scrollbar&#123;width:0!important&#125;pre&#123;white-space:pre-wrap!important;word-wrap:break-word!important;*white-space:normal!important&#125;#letter img&#123;max-width:300px&#125;&lt;/style&gt;&lt;style id=&quot;from-wrapstyle&quot;type=&quot;text/css&quot;&gt;#form-wrap&#123;overflow:hidden;height:447px;position:relative;top:0px;transition:all 1s ease-in-out.3s;z-index:0&#125;&lt;/style&gt;&lt;style id=&quot;from-wraphoverstyle&quot;type=&quot;text/css&quot;&gt;#form-wrap:hover&#123;height:1300px;top:-200px&#125;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div style=&quot;width: 530px;margin: 20px auto 0;height: 1000px;&quot;&gt;&lt;div id=&quot;form-wrap&quot;&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/Akilarlxh/Valine-Admin@v1.0/source/img/before.png&quot;alt=&quot;before&quot;style=&quot;position: absolute;bottom: 126px;left: 0px;background-repeat: no-repeat;width: 530px;height: 317px;z-index:-100&quot;&gt;&lt;div style=&quot;position: relative;overflow: visible;height: 1500px;width: 500px;margin: 0px auto;transition: all 1s ease-in-out .3s;padding-top:200px;&quot;&gt;&lt;form&gt;&lt;div style=&quot;background: white;width: 95%;max-width: 800px;margin: auto auto;border-radius: 5px;border: 1px solid;overflow: hidden;-webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.12);box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.18);&quot;&gt;&lt;img style=&quot;width:100%;overflow: hidden;&quot;src=&quot;https://area.sinaapp.com/bingImg&quot;/&gt;&lt;div style=&quot;padding: 5px 20px;&quot;&gt;&lt;br&gt;&lt;div&gt;&lt;h3 style=&quot;text-decoration: none; color: #8fbc8f;&quot;&gt;来自&#123;&#123;self.nick&#125;&#125;的留言:&lt;/h3&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;div id=&quot;letter&quot;style=&quot;overflow:auto;height:300px;width:100%;display:block;word-break: break-all;word-wrap: break-word;&quot;&gt;&lt;div style=&quot;border-bottom: #ddd 1px solid;border-left: #ddd 1px solid;padding-bottom: 20px;background-color: #eee;margin: 15px 0px;padding-left: 20px;padding-right: 20px;border-top: #ddd 1px solid;border-right: #ddd 1px solid;padding-top: 20px;font-family: &quot;Arial&quot;, &quot;Microsoft YaHei&quot; , &quot;黑体&quot; , &quot;宋体&quot; , sans-serif;&quot;&gt;&#123;&#123;self.comment | safe&#125;&#125;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;margin-top: 40px;&quot;&gt;&lt;img src=&quot;https://ae01.alicdn.com/kf/U0968ee80fd5c4f05a02bdda9709b041eE.png&quot;alt=&quot;hr&quot;style=&quot;width:100%; margin:5px auto 5px auto; display: block;&quot;/&gt;&lt;a style=&quot;text-transform: uppercase;text-decoration: none;font-size: 14px;border: 2px solid #ace0f9;color: #FFFFFF;padding: 10px;display: inline-block;margin: 10px auto 0;background-color: #8fbc8f;&quot;target=&quot;_blank&quot;href=&quot;&#123;&#123;site.postUrl&#125;&#125;&quot;&gt;&#123;&#123;site.name&#125;&#125;｜请您过目~&lt;/a&gt;&lt;/div&gt;&lt;p style=&quot;font-size: 12px;text-align: center;color: #999;&quot;&gt;©2020 - 2021 &lt;a style=&quot;text-decoration:none; color:#8fbc8f&quot;href=&quot;&#123;&#123;site.url&#125;&#125;&quot;&gt;&#123;&#123;site.name&#125;&#125;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/form&gt;&lt;/div&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/Akilarlxh/Valine-Admin@v1.0/source/img/after.png&quot;alt=&quot;after&quot;style=&quot;      position: absolute;bottom: -2px;left: 0;background-repeat: no-repeat;width: 530px;height: 259px;z-index:100&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/body&gt;&#x27;</span></span><br></pre></td></tr></table></figure><h3 id="下载">下载<a class="fa-solid fa-hashtag" href="#下载"></a></h3><p><a href="https://file.nmb.show/down.php/4ca88b8fe0729c213cd3a425f87d2f51.rar">邮件通知模板下载</a>（包含 Waline/Valine/Twikoo），您可以下载后根据官方文档提及的变量自行修改<code>index.js</code>相关内容，以上代码仅作参考，对于本文未涉及到的其他内容，请自行查看官方文档，如有错误，欢迎指正，谢谢！</p>]]></c:encoded></item><item><title>一款简洁却不简单的 m3u8 下载工具</title><link>https://blog.ccknbc.cc/posts/a-simple-but-not-simple-m3u8-download-tool/</link><description>一款简洁却不简单的 m3u8 下载工具</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%B7%A5%E5%85%B7/">工具</category><category domain="https://blog.ccknbc.cc/tags/%E5%B7%A5%E5%85%B7/">工具</category><pubDate>Fri, 10 Jul 2026 01:27:42 GMT</pubDate><c:encoded><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/19/"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/a-simple-but-not-simple-m3u8-download-tool/"><strong>CC的部落格</strong></a></p><p><a href="https://github.com/nilaoda/N_m3u8DL-CLI">官方仓库</a></p><p><img src="https://cdn.nlark.com/yuque/0/2021/gif/8391407/1610273643341-942cd95d-6f1e-4356-afc9-d5961c7d078a.gif" alt="" loading="lazy"></p><p>批量下载优酷m3u8</p><p><img src="https://cdn.nlark.com/yuque/0/2021/gif/8391407/1610273775655-7e8c3956-6d5a-4760-a59b-d02e6c21126e.gif" alt="" loading="lazy"></p><p>LINETV（台湾站解析）<br><img src="https://cdn.nlark.com/yuque/0/2021/gif/8391407/1610273823214-764f768e-4b64-4073-8793-498c61a30285.gif" alt="" loading="lazy"></p><p>其实 SimpleG 提供了 CLI 更直观简单的调用方式，因此更加方便快捷，解密，录直播必备。</p>]]></c:encoded></item></channel></rss>