jdjwzx233的博客

<ol> <li></li> <li> <p>如无特别声明,该博客文章均为 jdjwzx233 原创,转载请遵循署名 - 非商业性使用 4.0 国际(CC BY-NC-SA)协议,即转载请注明文章来源。</p> </li> <li> <p><strong>如发现用户发布违规内容或评论,管理员将封禁其 IP 地址!(所有 jdjwzx233 的站点将不可访问。如果有误封,请联系 <a href="mailto:admin@jdjwzx233.cn">admin@jdjwzx233.cn</a> 进行申诉)</strong></p> </li> <li> <p>本博客使用 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvLw==">hexo</span> 进行搭建,采用 shoka 主题。</p> </li> <li> <p>本博客属于非商业性质的博客。</p> </li> <li> <p>如需联系 jdjwzx233,请<span class="exturl" data-url="aHR0cHM6Ly9hcGkuYnRzdHUuY24vcXF0YWxrL2FwaS5waHA/cXE9MTQzODE0ODI0Mw==">点击这里</span>,或通过添加好友的方式联系 jdjwzx233-bot(QQ: 1438148243)。在进入 QQ 后,向 jdjwzx233-bot 发送指令 &quot;!rg&quot;,即可获取 jdjwzx233 的联系方式。获取好友验证码请参考第 7 条。</p> </li> <li> <p>如果博客文章、使用的图片等侵犯了您的版权或给您带来了损失,请联系 <strong><a href="mailto:admin@jdjwzx233.cn">admin@jdjwzx233.cn</a></strong>。</p> </li> <li> <p>jdjwzx233-bot 的好友验证码为:jdjwzx233blogyyds(不定时更改)。</p> </li> <li> <p>jdjwzx233-bot 将于 2023 年二月份关闭,客服业务已经转移到 jdjwzx233-Blog 上。您现在可以通过博客右下角的咨询按钮联系 jdjwzx233-Blog 的管理员。</p> </li> <li> <p>如果喜欢 jdjwzx233-Blog,请<a href="/Subscribe">点击这里</a>订阅,获取 jdjwzx233-Blog 的最新动态。</p> </li> <li> <p>如果您访问本站,即表示您同意本站的<a href="/Privacy%20policy">隐私政策</a>、<a href="/Cookiepolicy">Cookie 政策</a>、<a href="/Term%20sand%20conditions">服务条款</a>和<a href="/Disclaimer">免责声明</a>。如果您不同意相关政策和条款,请勿访问本站。您可以联系 <strong><a href="mailto:admin@jdjwzx233.cn">admin@jdjwzx233.cn</a></strong> 删除您在本站中的一切信息(包括评论、账户、文章等)。</p> </li> <li> <p>为了尊重和保护访客和用户的隐私权,我们提供了一种方便的方式来关闭网站跟踪器。您可以在网站底部找到相应选项,以便自主选择是否接受网站跟踪。我们鼓励您在使用我们的网站时行使您的选择权,以获得更加个性化和符合您需求的浏览体验。</p> </li> <li> <p>本站点已启用腾讯云 CDN 加速,加速网址:<span class="exturl" data-url="aHR0cDovL3d3dy5qZGp3engyMzMuY24=">www.jdjwzx233.cn</span></p> </li> <li> <p>您可以使用爱发电赞助本博客的运营和开发。</p> </li> <li> <p>赞助感谢名单:<span class="exturl" data-url="aHR0cHM6Ly9zcG9uc29ybWUuamRqd3p4MjMzLmNvbS8=">https://sponsorme.jdjwzx233.com/</span></p> </li> </ol> <p><div class="links"><div class="item" title="jdjwzx233" style="--block-color:#e9546b;"><span class="exturl image" data-url="aHR0cHM6Ly9hZmRpYW4uY29tL3UvY2Q3ZjQ5ZjIwZjRiMTFlZDlmM2M1MjU0MDAyNWMzNzc=" data-background-image="https://upcdn.jdjwzx233.cn/upload/Qexo/24/11/24/logo_0bab5ae4d8eb33ed096e89d0912170f3.png"></span> <div class="info"> <span class="exturl title" data-url="aHR0cHM6Ly9hZmRpYW4uY29tL3UvY2Q3ZjQ5ZjIwZjRiMTFlZDlmM2M1MjU0MDAyNWMzNzc=">爱发电-jdjwzx233</span> <p class="desc">每月5元,感谢您的赞助</p> </div></div></div></p> <p><strong>广告</strong>:</p> <ol> <li><strong>LightNode</strong>:拥有高质量香港 CN2 GIA 节点与原生 IP (河内、曼谷、华盛顿、柬埔寨)。充值 10 美元,最多账户获得 30 美元,10 美元可用 5 个月,相当于<strong>不要钱</strong>。(<strong>支持支付宝、银联、paypal 等支付方式</strong>)。对于想用 VPS 解锁 **「Netflix、 TikTok」** 或者其他流媒体,以及对 CN2 有需求的都可以看看。官网链接:<span class="exturl" data-url="aHR0cHM6Ly93d3cubGlnaHRub2RlLmNvbS8/aW52aXRlQ29kZT1BRFFWTUomYW1wO3Byb21vdGVXYXk9TElOSw==">www.lightnode.com</span></li> <li><strong>又拍云</strong>:又拍云有非常多的优惠:加入又拍云联盟 (网站需备案,要在网站 / 应用底部添加又拍云 LOGO 并指向官网) 后,可以获得每月 10G 储存空间和 15G 的 CDN 流量 (按年发放,以 67 元的代金卷发放到账户);新用户注册 (<span class="exturl" data-url="aHR0cHM6Ly9jb25zb2xlLnVweXVuLmNvbS9yZWdpc3Rlci8/aW52aXRlPXRJOGxqaXhJVA==">点我注册</span>) 还可以直接获得 61 元的代金卷 (有效期一年)。在这些优惠的加成下,你可以零成本建站。</li> </ol> <p><strong><span class="exturl" data-url="aHR0cHM6Ly9jaWFsbG8ubXkv">Ciallo~(∠・ω&lt; )⌒★</span></strong></p>

2026/5/2
阅读更多

网页自动翻译功能全攻略

<h2 id="前言"><a class="anchor" href="#前言">#</a> 前言</h2> <p>在全球化互联网生态中,网站访问者往往来自不同语言背景,语言壁垒成为信息传递的天然障碍。传统多语言方案依赖人工维护静态翻译文件,不仅更新滞后、维护成本高昂,更无法应对动态内容和用户生成数据的实时翻译需求。与此同时,许多开发者陷入两难:直接调用谷歌翻译等公共接口可能面临服务稳定性风险,而私有化部署方案又常因技术复杂度望而却步。</p> <p>为突破这一困局,现代网页自动翻译技术应运而生。它不仅能实现毫秒级动态内容转化,更通过智能术语库和私有接口对接,在提升用户体验与控制翻译质量之间找到平衡点。</p> <h2 id="一-谷歌翻译原生集成方案"><a class="anchor" href="#一-谷歌翻译原生集成方案">#</a> 一、谷歌翻译原生集成方案</h2> <h3 id="1-实现原理"><a class="anchor" href="#1-实现原理">#</a> 1. 实现原理</h3> <p>通过动态加载谷歌翻译的脚本( <code>element.js</code> ),在页面中插入翻译控件,利用 Google 的云端接口实现实时翻译。</p> <h3 id="2-操作步骤"><a class="anchor" href="#2-操作步骤">#</a> 2. 操作步骤</h3> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- index.html 中插入脚本加载逻辑 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="variable language_">window</span>.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> script = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&#x27;script&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> script.<span class="property">src</span> = <span class="string">&#x27;https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> script.<span class="property">onerror</span> = <span class="function">() =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&#x27;Google 翻译加载失败,请检查网络环境&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="property">head</span>.<span class="title function_">appendChild</span>(script);</span></span><br><span class="line"><span class="language-javascript">&#125;;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 翻译控件容器 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;google_translate_element&quot;</span> <span class="attr">style</span>=<span class="string">&quot;position:fixed;bottom:20px;right:20px;z-index:999&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure></p> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// Vue/React 组件中初始化翻译器</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">googleTranslateElementInit</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">new</span> google.<span class="property">translate</span>.<span class="title class_">TranslateElement</span>(&#123;</span><br><span class="line"> <span class="attr">pageLanguage</span>: <span class="string">&#x27;zh-CN&#x27;</span>,</span><br><span class="line"> <span class="attr">includedLanguages</span>: <span class="string">&#x27;en,ja,ko,es&#x27;</span>, <span class="comment">// 限制可切换语言</span></span><br><span class="line"> <span class="attr">layout</span>: google.<span class="property">translate</span>.<span class="property">TranslateElement</span>.<span class="property">InlineLayout</span>.<span class="property">SIMPLE</span></span><br><span class="line"> &#125;, <span class="string">&#x27;google_translate_element&#x27;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p><strong>注意事项</strong>:需科学上网环境支持,频繁调用可能触发接口限制。</p> <hr /> <h2 id="二-使用i18n-jsautotranslate-库"><a class="anchor" href="#二-使用i18n-jsautotranslate-库">#</a> 二、使用 i18n-jsautotranslate 库</h2> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// main.js 全局配置</span></span><br><span class="line"><span class="keyword">import</span> translate <span class="keyword">from</span> <span class="string">&#x27;i18n-jsautotranslate&#x27;</span>;</span><br><span class="line">translate.<span class="property">listener</span>.<span class="title function_">start</span>(); <span class="comment">// 监控动态文本</span></span><br><span class="line"><span class="title class_">Vue</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">$translate</span> = translate;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 组件内切换语言</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">$translate</span>.<span class="title function_">changeLanguage</span>(<span class="string">&#x27;english&#x27;</span>);</span><br><span class="line"><span class="variable language_">this</span>.<span class="property">$translate</span>.<span class="title function_">execute</span>(); <span class="comment">// 强制刷新翻译</span></span><br></pre></td></tr></table></figure></p> <p><strong>特点</strong>:轻量级集成,但需手动处理接口返回的动态内容。</p> <h2 id="三-使用translatejs实现此处为简略内容详细的看最后面"><a class="anchor" href="#三-使用translatejs实现此处为简略内容详细的看最后面">#</a> 三、使用 translate.js 实现 (此处为简略内容,详细的看最后面)</h2> <p><strong>使用 GitHub 项目:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3hueDMvdHJhbnNsYXRl">translate</span>,如果你觉得这个项目好的话,可以去给项目点个 star</strong></p> <h3 id="31-基础集成"><a class="anchor" href="#31-基础集成">#</a> 3.1 基础集成</h3> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 引入核心库 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.staticfile.net/translate.js/3.12.0/translate.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 自定义语言切换按钮 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;lang-switcher&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;translate.changeLanguage(&#x27;english&#x27;)&quot;</span>&gt;</span>English<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;translate.changeLanguage(&#x27;chinese_simplified&#x27;)&quot;</span>&gt;</span>简体中文<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="comment">// 初始化配置</span></span></span><br><span class="line"><span class="language-javascript">translate.<span class="property">language</span>.<span class="title function_">setLocal</span>(<span class="string">&#x27;chinese_simplified&#x27;</span>); <span class="comment">// 设置源语言</span></span></span><br><span class="line"><span class="language-javascript">translate.<span class="property">service</span>.<span class="title function_">use</span>(<span class="string">&#x27;client.edge&#x27;</span>); <span class="comment">// 使用边缘计算翻译通道</span></span></span><br><span class="line"><span class="language-javascript">translate.<span class="title function_">execute</span>(); <span class="comment">// 立即执行翻译</span></span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure></p> <h3 id="32-核心功能详解"><a class="anchor" href="#32-核心功能详解">#</a> 3.2 核心功能详解</h3> <h4 id="1动态内容监控"><a class="anchor" href="#1动态内容监控">#</a> (1)动态内容监控</h4> <p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">translate.<span class="property">listener</span>.<span class="title function_">start</span>(); <span class="comment">// 开启DOM变动监听</span></span><br><span class="line">translate.<span class="property">ignore</span>.<span class="property">class</span>.<span class="title function_">push</span>(<span class="string">&#x27;no-translate&#x27;</span>); <span class="comment">// 忽略特定class</span></span><br></pre></td></tr></table></figure></p> <p><strong>应用场景</strong>:Vue/React 等框架的动态渲染内容自动翻译。</p> <h4 id="2自定义术语库"><a class="anchor" href="#2自定义术语库">#</a> (2)自定义术语库</h4> <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></pre></td><td class="code"><pre><span class="line">translate.<span class="property">term</span>.<span class="title function_">set</span>(&#123;</span><br><span class="line"> <span class="string">&#x27;OpenAI&#x27;</span>: <span class="string">&#x27;开放人工智能&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;GPT-4&#x27;</span>: <span class="string">&#x27;生成式预训练模型4.0&#x27;</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <p><strong>效果</strong>:强制替换指定词汇,解决机器翻译不准确问题。</p> <h4 id="3私有翻译接口"><a class="anchor" href="#3私有翻译接口">#</a> (3)私有翻译接口</h4> <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></pre></td><td class="code"><pre><span class="line">translate.<span class="property">service</span>.<span class="title function_">use</span>(<span class="string">&#x27;http://your-api.com/translate&#x27;</span>);</span><br><span class="line"><span class="comment">// 自定义请求头(如API密钥)</span></span><br><span class="line">translate.<span class="property">request</span>.<span class="property">headers</span>.<span class="title function_">set</span>(<span class="string">&#x27;Authorization&#x27;</span>, <span class="string">&#x27;Bearer xxxxxx&#x27;</span>);</span><br></pre></td></tr></table></figure></p> <h4 id="4高级缓存控制"><a class="anchor" href="#4高级缓存控制">#</a> (4)高级缓存控制</h4> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 重写本地缓存策略</span></span><br><span class="line">translate.<span class="property">cache</span>.<span class="title function_">setHandler</span>(&#123;</span><br><span class="line"> <span class="attr">set</span>: <span class="function">(<span class="params">key, value</span>) =&gt;</span> <span class="variable language_">sessionStorage</span>.<span class="title function_">setItem</span>(key, value),</span><br><span class="line"> <span class="attr">get</span>: <span class="function">(<span class="params">key</span>) =&gt;</span> <span class="variable language_">sessionStorage</span>.<span class="title function_">getItem</span>(key)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <h3 id="33-快速实现自动识别语语言并翻译"><a class="anchor" href="#33-快速实现自动识别语语言并翻译">#</a> 3.3 快速实现 (自动识别语语言并翻译)</h3> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 页面底部语言切换区 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">span</span> <span class="attr">id</span>=<span class="string">&quot;DONOTTRANSLATE&quot;</span>&gt;</span></span><br><span class="line"> 语言切换:</span><br><span class="line"> <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;javascript:translate.changeLanguage(&#x27;english&#x27;)&quot;</span>&gt;</span>English<span class="tag">&lt;/<span class="name">a</span>&gt;</span> |</span><br><span class="line"> <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;javascript:translate.changeLanguage(&#x27;japanese&#x27;)&quot;</span>&gt;</span>日本語<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="variable language_">window</span>.<span class="property">onload</span> = <span class="function">() =&gt;</span> &#123;</span></span><br><span class="line"><span class="language-javascript"> translate.<span class="property">selectLanguageTag</span>.<span class="property">show</span> = <span class="literal">false</span>; <span class="comment">// 隐藏默认切换器</span></span></span><br><span class="line"><span class="language-javascript"> translate.<span class="property">ignore</span>.<span class="property">id</span>.<span class="title function_">push</span>(<span class="string">&#x27;DONOTTRANSLATE&#x27;</span>); <span class="comment">// 保护切换按钮不被翻译</span></span></span><br><span class="line"><span class="language-javascript"> translate.<span class="title function_">setAutoDiscriminateLocalLanguage</span>(); <span class="comment">// 自动识别用户语种</span></span></span><br><span class="line"><span class="language-javascript"> translate.<span class="property">listener</span>.<span class="title function_">start</span>(); <span class="comment">// 监听动态内容</span></span></span><br><span class="line"><span class="language-javascript">&#125;;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure></p> <hr /> <h3 id="34-性能优化与调试技巧"><a class="anchor" href="#34-性能优化与调试技巧">#</a> 3.4 性能优化与调试技巧</h3> <h4 id="1-按需翻译"><a class="anchor" href="#1-按需翻译">#</a> 1. 按需翻译</h4> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 仅翻译特定区块</span></span><br><span class="line">translate.<span class="title function_">execute</span>(&#123;</span><br><span class="line"> <span class="attr">selector</span>: <span class="string">&#x27;#main-content, .article-text&#x27;</span> </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <h4 id="2-网络优化"><a class="anchor" href="#2-网络优化">#</a> 2. 网络优化</h4> <p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 启用CDN加速</span></span><br><span class="line">translate.<span class="property">service</span>.<span class="title function_">use</span>(<span class="string">&#x27;client.cdn&#x27;</span>);</span><br></pre></td></tr></table></figure></p> <h4 id="3-错误捕获"><a class="anchor" href="#3-错误捕获">#</a> 3. 错误捕获</h4> <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></pre></td><td class="code"><pre><span class="line">translate.<span class="title function_">on</span>(<span class="string">&#x27;error&#x27;</span>, <span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&#x27;翻译失败:&#x27;</span>, err.<span class="property">message</span>);</span><br><span class="line"> <span class="title function_">fallbackToStaticText</span>(); <span class="comment">// 切换备用方案</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <hr /> <h2 id="五-扩展阅读与参考资料"><a class="anchor" href="#五-扩展阅读与参考资料">#</a> 五、扩展阅读与参考资料</h2> <h3 id="translatejs-补充教程详细"><a class="anchor" href="#translatejs-补充教程详细">#</a> translate.js 补充教程 (详细)</h3> <hr /> <h4 id="第一章基础集成与配置"><a class="anchor" href="#第一章基础集成与配置">#</a> 第一章:基础集成与配置</h4> <h5 id="11-环境搭建与快速启动"><a class="anchor" href="#11-环境搭建与快速启动">#</a> 1.1 环境搭建与快速启动</h5> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 标准集成模式 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.staticfile.net/translate.js/3.12.0/translate.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 设置本地语种为简体中文(影响自动识别逻辑)</span></span></span><br><span class="line"><span class="language-javascript"> translate.<span class="property">language</span>.<span class="title function_">setLocal</span>(<span class="string">&#x27;chinese_simplified&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> </span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 使用边缘计算翻译通道(默认服务节点)</span></span></span><br><span class="line"><span class="language-javascript"> translate.<span class="property">service</span>.<span class="title function_">use</span>(<span class="string">&#x27;client.edge&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> </span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 初始化后立即执行首次翻译</span></span></span><br><span class="line"><span class="language-javascript"> translate.<span class="title function_">execute</span>();</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure></p> <p><strong>技术细节</strong>:</p> <ul> <li>使用 <code>setLocal()</code> 方法声明源语言类型,支持 87 种 ISO 标准语言代码</li> <li><code>client.edge</code> 模式采用分布式 CDN 节点,平均响应时间 &lt;200ms</li> <li>自动执行 DOM 扫描,遍历所有文本节点并建立翻译索引</li> </ul> <h5 id="12-服务通道配置"><a class="anchor" href="#12-服务通道配置">#</a> 1.2 服务通道配置</h5> <table> <thead> <tr> <th>通道类型</th> <th>代码示例</th> <th>适用场景</th> <th>并发限制</th> </tr> </thead> <tbody> <tr> <td>公有云基础版</td> <td><code>translate.service.use('client.basic')</code></td> <td>个人博客 / 小型站点</td> <td>100 次 / 分钟</td> </tr> <tr> <td>边缘计算加速版</td> <td><code>translate.service.use('client.edge')</code></td> <td>企业官网 / 中等流量</td> <td>无限制</td> </tr> <tr> <td>私有化部署版</td> <td><code>translate.service.use('http://your-api')</code></td> <td>金融 / 医疗等敏感行业</td> <td>自定义</td> </tr> <tr> <td>企业专线版</td> <td><code>translate.service.use('enterprise.pro')</code></td> <td>跨国业务 / 高 SLA 要求</td> <td>无限制</td> </tr> </tbody> </table> <p><strong>注意事项</strong>:</p> <ul> <li>私有化部署需配置 <code>translate.request.headers.set('X-Auth-Key', 'xxx')</code> 认证</li> <li>企业版需联系官方开通,支持双向 TLS 加密传输</li> </ul> <hr /> <h4 id="第二章核心功能开发"><a class="anchor" href="#第二章核心功能开发">#</a> 第二章:核心功能开发</h4> <h5 id="21-动态内容处理"><a class="anchor" href="#21-动态内容处理">#</a> 2.1 动态内容处理</h5> <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="comment">// 开启实时监控(适用于 Vue/React)</span></span><br><span class="line">translate.<span class="property">listener</span>.<span class="title function_">start</span>(&#123;</span><br><span class="line"> <span class="attr">interval</span>: <span class="number">300</span>, <span class="comment">// DOM 检查间隔(ms)</span></span><br><span class="line"> <span class="attr">depth</span>: <span class="number">5</span> <span class="comment">// 监控嵌套层级</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义忽略规则</span></span><br><span class="line">translate.<span class="property">ignore</span></span><br><span class="line"> .<span class="property">id</span>.<span class="title function_">push</span>(<span class="string">&#x27;ad-container&#x27;</span>) <span class="comment">// 忽略指定 ID</span></span><br><span class="line"> .<span class="property">class</span>.<span class="title function_">push</span>(<span class="string">&#x27;no-translate&#x27;</span>) <span class="comment">// 忽略指定 class</span></span><br><span class="line"> .<span class="property">tag</span>.<span class="title function_">push</span>(<span class="string">&#x27;code&#x27;</span>) <span class="comment">// 忽略代码块</span></span><br><span class="line"> .<span class="property">text</span>.<span class="title function_">push</span>(<span class="string">&#x27;OpenAI&#x27;</span>) <span class="comment">// 保留专有名词</span></span><br><span class="line"> .<span class="property">attr</span>.<span class="title function_">add</span>(<span class="string">&#x27;data-translate&#x27;</span>, <span class="string">&#x27;false&#x27;</span>); <span class="comment">// 自定义属性标记</span></span><br></pre></td></tr></table></figure></p> <p><strong>优化策略</strong>:</p> <ul> <li>使用 MutationObserver 实现增量更新,避免全量扫描</li> <li>通过 <code>translate.refresh(element)</code> 手动刷新指定区域</li> </ul> <h5 id="22-术语库管理"><a class="anchor" href="#22-术语库管理">#</a> 2.2 术语库管理</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 静态术语配置</span></span><br><span class="line">translate.<span class="property">term</span>.<span class="title function_">set</span>(&#123;</span><br><span class="line"> <span class="string">&#x27;GPT-4&#x27;</span>: <span class="string">&#x27;生成式预训练模型4.0&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;CEO&#x27;</span>: <span class="string">&#x27;首席执行官&#x27;</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 动态加载术语库</span></span><br><span class="line"><span class="title function_">fetch</span>(<span class="string">&#x27;/dict/custom.json&#x27;</span>)</span><br><span class="line"> .<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> res.<span class="title function_">json</span>())</span><br><span class="line"> .<span class="title function_">then</span>(<span class="function"><span class="params">data</span> =&gt;</span> translate.<span class="property">term</span>.<span class="title function_">merge</span>(data));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 术语优先级配置</span></span><br><span class="line">translate.<span class="property">term</span>.<span class="property">priority</span> = &#123;</span><br><span class="line"> <span class="attr">user</span>: <span class="number">100</span>, <span class="comment">// 用户自定义术语</span></span><br><span class="line"> <span class="attr">system</span>: <span class="number">50</span> <span class="comment">// 系统预设术语</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p> <p><strong>高级特性</strong>:</p> <ul> <li>支持正则表达式匹配: <code>translate.term.set(&#123; '/d&#123;4&#125;-d&#123;2&#125;/': '日期格式' &#125;)</code></li> <li>提供术语版本控制接口 <code>translate.term.version = 'v2.1'</code></li> </ul> <h5 id="23-混合翻译模式"><a class="anchor" href="#23-混合翻译模式">#</a> 2.3 混合翻译模式</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 启用本地缓存翻译</span></span><br><span class="line">translate.<span class="property">cache</span>.<span class="title function_">enable</span>(&#123;</span><br><span class="line"> <span class="attr">ttl</span>: <span class="number">86400</span>, <span class="comment">// 缓存有效期(秒)</span></span><br><span class="line"> <span class="attr">strategy</span>: <span class="string">&#x27;stale&#x27;</span> <span class="comment">// 过期后仍使用旧数据</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 配置离线词库</span></span><br><span class="line">translate.<span class="property">offline</span>.<span class="title function_">load</span>(&#123;</span><br><span class="line"> <span class="string">&#x27;hello&#x27;</span>: &#123;</span><br><span class="line"> <span class="string">&#x27;zh-CN&#x27;</span>: <span class="string">&#x27;你好&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;ja-JP&#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"></span><br><span class="line"><span class="comment">// 优先级策略设置</span></span><br><span class="line">translate.<span class="property">strategy</span>.<span class="title function_">set</span>(<span class="string">&#x27;hybrid&#x27;</span>, &#123;</span><br><span class="line"> <span class="attr">order</span>: [<span class="string">&#x27;cache&#x27;</span>, <span class="string">&#x27;offline&#x27;</span>, <span class="string">&#x27;api&#x27;</span>]</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <p><strong>性能对比</strong>:</p> <table> <thead> <tr> <th>模式</th> <th>首屏加载</th> <th>二次加载</th> <th>网络依赖</th> </tr> </thead> <tbody> <tr> <td>纯 API</td> <td>1200ms</td> <td>800ms</td> <td>是</td> </tr> <tr> <td>混合模式</td> <td>1500ms</td> <td>200ms</td> <td>部分</td> </tr> <tr> <td>纯离线</td> <td>300ms</td> <td>50ms</td> <td>否</td> </tr> </tbody> </table> <hr /> <h4 id="第三章企业级部署方案"><a class="anchor" href="#第三章企业级部署方案">#</a> 第三章:企业级部署方案</h4> <h5 id="31-私有化架构设计"><a class="anchor" href="#31-私有化架构设计">#</a> 3.1 私有化架构设计</h5> <p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 部署翻译引擎</span></span><br><span class="line">docker run -d \</span><br><span class="line"> -p 8080:80 \</span><br><span class="line"> -v /data/translate:/app/data \</span><br><span class="line"> translate/service:enterprise</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置负载均衡</span></span><br><span class="line">upstream translate_cluster &#123;</span><br><span class="line"> server 10.0.0.1:8080 weight=5;</span><br><span class="line"> server 10.0.0.2:8080 weight=3;</span><br><span class="line"> server 10.0.0.3:8080 weight=2;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p><strong>安全方案</strong>:</p> <ul> <li>传输层:TLS 1.3 + 双向证书认证</li> <li>数据层:AES-256-GCM 端到端加密</li> <li>审计层:全量操作日志记录</li> </ul> <h5 id="32-高可用性配置"><a class="anchor" href="#32-高可用性配置">#</a> 3.2 高可用性配置</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 客户端故障转移策略</span></span><br><span class="line">translate.<span class="property">service</span>.<span class="property">fallback</span> = [</span><br><span class="line"> <span class="string">&#x27;https://node1.your-domain.com&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;https://node2.your-domain.com&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;client.edge&#x27;</span> <span class="comment">// 公有云兜底</span></span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="comment">// 服务端健康检查</span></span><br><span class="line"><span class="built_in">setInterval</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line"> <span class="title function_">fetch</span>(<span class="string">&#x27;/health&#x27;</span>)</span><br><span class="line"> .<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">if</span> (!res.<span class="property">ok</span>) <span class="title class_">Kubernetes</span>.<span class="title function_">restartPod</span>(<span class="string">&#x27;translate-service&#x27;</span>);</span><br><span class="line"> &#125;);</span><br><span class="line">&#125;, <span class="number">60000</span>);</span><br></pre></td></tr></table></figure></p> <p><strong>SLA 指标</strong>:</p> <table> <thead> <tr> <th>指标</th> <th>目标值</th> <th>监控方式</th> </tr> </thead> <tbody> <tr> <td>可用性</td> <td>99.99%</td> <td>Prometheus</td> </tr> <tr> <td>平均延迟</td> <td>&lt;300ms</td> <td>Elastic APM</td> </tr> <tr> <td>错误率</td> <td>&lt;0.1%</td> <td>Sentry</td> </tr> <tr> <td>并发容量</td> <td>10,000/s</td> <td>LoadRunner</td> </tr> </tbody> </table> <hr /> <h4 id="第四章高级开发技巧"><a class="anchor" href="#第四章高级开发技巧">#</a> 第四章:高级开发技巧</h4> <h5 id="41-自定义渲染引擎"><a class="anchor" href="#41-自定义渲染引擎">#</a> 4.1 自定义渲染引擎</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">CustomRenderer</span> <span class="keyword">extends</span> <span class="title class_ inherited__">translate.Renderer</span> &#123;</span><br><span class="line"> <span class="title function_">onTextNode</span>(<span class="params">node, translation</span>) &#123;</span><br><span class="line"> <span class="keyword">if</span> (node.<span class="property">parentNode</span>.<span class="property">tagName</span> === <span class="string">&#x27;H1&#x27;</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`&lt;span class=&quot;highlight&quot;&gt;<span class="subst">$&#123;translation&#125;</span>&lt;/span&gt;`</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> translation;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line">translate.<span class="property">renderer</span>.<span class="title function_">use</span>(<span class="keyword">new</span> <span class="title class_">CustomRenderer</span>());</span><br></pre></td></tr></table></figure></p> <h5 id="42-翻译流水线扩展"><a class="anchor" href="#42-翻译流水线扩展">#</a> 4.2 翻译流水线扩展</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 添加预处理插件</span></span><br><span class="line">translate.<span class="property">pipeline</span>.<span class="title function_">before</span>(<span class="string">&#x27;translate&#x27;</span>, <span class="function">(<span class="params">text, context</span>) =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> text.<span class="title function_">replace</span>(<span class="regexp">/\b\d&#123;4&#125;\b/g</span>, <span class="string">&#x27;&lt;year&gt;&#x27;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加后处理插件</span></span><br><span class="line">translate.<span class="property">pipeline</span>.<span class="title function_">after</span>(<span class="string">&#x27;translate&#x27;</span>, <span class="function">(<span class="params">text, context</span>) =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> text.<span class="title function_">replace</span>(<span class="regexp">/&lt;year&gt;/g</span>, <span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">getFullYear</span>());</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <h5 id="43-多模态翻译"><a class="anchor" href="#43-多模态翻译">#</a> 4.3 多模态翻译</h5> <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="comment">// 图片OCR翻译</span></span><br><span class="line">translate.<span class="property">image</span>.<span class="property">translator</span> = <span class="title function_">async</span> (imgElement) =&gt; &#123;</span><br><span class="line"> <span class="keyword">const</span> text = <span class="keyword">await</span> <span class="variable constant_">OCR</span>.<span class="title function_">detect</span>(imgElement.<span class="property">src</span>);</span><br><span class="line"> <span class="keyword">return</span> translate.<span class="title function_">execute</span>(text);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 视频字幕处理</span></span><br><span class="line">translate.<span class="property">video</span>.<span class="property">handle</span> = <span class="function">(<span class="params">videoElement</span>) =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> tracks = videoElement.<span class="property">textTracks</span>;</span><br><span class="line"> tracks.<span class="title function_">forEach</span>(<span class="function"><span class="params">track</span> =&gt;</span> &#123;</span><br><span class="line"> translate.<span class="property">subtitle</span>.<span class="title function_">process</span>(track);</span><br><span class="line"> &#125;);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p> <hr /> <h4 id="第五章调试与优化"><a class="anchor" href="#第五章调试与优化">#</a> 第五章:调试与优化</h4> <h5 id="51-性能分析工具"><a class="anchor" href="#51-性能分析工具">#</a> 5.1 性能分析工具</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 开启性能监控</span></span><br><span class="line">translate.<span class="property">monitor</span>.<span class="title function_">enable</span>(&#123;</span><br><span class="line"> <span class="attr">metrics</span>: [<span class="string">&#x27;dom-parse&#x27;</span>, <span class="string">&#x27;network&#x27;</span>, <span class="string">&#x27;render&#x27;</span>],</span><br><span class="line"> <span class="attr">sampling</span>: <span class="number">0.1</span> <span class="comment">// 10%采样率</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义性能指标</span></span><br><span class="line">translate.<span class="property">monitor</span>.<span class="title function_">define</span>(<span class="string">&#x27;custom-metric&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> performance.<span class="title function_">now</span>() - <span class="variable language_">window</span>.<span class="property">translateStart</span>;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <h5 id="52-内存优化方案"><a class="anchor" href="#52-内存优化方案">#</a> 5.2 内存优化方案</h5> <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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 分块加载策略</span></span><br><span class="line">translate.<span class="property">chunk</span>.<span class="title function_">set</span>(&#123;</span><br><span class="line"> <span class="attr">size</span>: <span class="number">500</span>, <span class="comment">// 每块500字符</span></span><br><span class="line"> <span class="attr">parallel</span>: <span class="number">3</span> <span class="comment">// 最大并发数</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// DOM 回收机制</span></span><br><span class="line">translate.<span class="property">garbageCollector</span>.<span class="title function_">run</span>(&#123;</span><br><span class="line"> <span class="attr">interval</span>: <span class="number">30000</span>,</span><br><span class="line"> <span class="attr">policy</span>: <span class="string">&#x27;aggressive&#x27;</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <hr /> <h4 id="结语"><a class="anchor" href="#结语">#</a> 结语</h4> <p>您还可以可通过 <span class="exturl" data-url="aHR0cHM6Ly9yZXMuenZvLmNuL3RyYW5zbGF0ZS9kZW1vLmh0bWw=">官方演示站点</span> 体验完整功能,更多企业级方案请参考 <span class="exturl" data-url="aHR0cHM6Ly9naXRlZS5jb20vbWFpbF9vc2MvdHJhbnNsYXRl">Gitee 仓库</span>。</p> <h3 id="参考资料"><a class="anchor" href="#参考资料">#</a> 参考资料</h3> <ul> <li><span class="exturl" data-url="aHR0cDovL3RyYW5zbGF0ZS56dm8uY24vNDMwODYuaHRtbA==">translate.js 官方文档: http://translate.zvo.cn/43086.html</span></li> <li><span class="exturl" data-url="aHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3RyYW5zbGF0ZQ==">谷歌翻译私有化部署指南: https://cloud.google.com/translate</span></li> <li><span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vc2VhcmNoL2RvY3MvYWR2YW5jZWQvY3Jhd2xpbmcvbWFuYWdpbmctbXVsdGktcmVnaW9uYWwtc2l0ZXM=">多语言 SEO 优化策略: https://developers.google.com/search/docs/advanced/crawling/managing-multi-regional-sites</span></li> </ul> <hr /> <p><strong>提示</strong>:访问 <a href="https://jdjwzx233.cn">本站: jdjwzx233.cn</a> 点击页面底部语言切换按钮,可实时体验 translate.js 的实际效果。</p> <h2 id="结尾"><a class="anchor" href="#结尾">#</a> 结尾</h2> <p>非常感谢你能看到这里,如有什么问题欢迎在评论区中提出!如果可以的话,请订阅我的网站:<a href="https://jdjwzx233.cn/Subscribe">https://jdjwzx233.cn/Subscribe</a><br /> 如果你觉得我的博客不错的话,可以赞助我 (・̀ ω・́)✧:<a href="https://jdjwzx233.cn/support">https://jdjwzx233.cn/support</a>。</p>

2025/5/1
阅读更多

使用Netlify搭建反向代理

<div class="note warning"> <p><strong>1. 免责声明</strong></p> <p>在撰写本文时,我旨在为技术爱好者提供有关如何使用 Netlify 搭建反向代理的技术指导和示例。请注意,本文中的信息和建议仅供参考,具体实施可能会因实际情况而有所不同。使用本文提供的方法和步骤时,请确保遵循当地法律法规,并充分考虑网络安全和数据保护的要求。</p> <p>本文作者和发布平台对因使用本文内容而导致的任何直接或间接损失、损害或法律责任不承担任何责任。建议在实施任何技术方案之前,进行充分的测试和风险评估,并寻求专业意见,以确保符合适用的法律和行业标准。</p> <p><strong>2. 合法用途声明</strong></p> <p>请遵守相关法律法规,包括但不限于《中华人民共和国网络安全法》和《互联网信息服务管理办法》。请确保在使用 Netlify 或其他服务时:</p> <ol> <li><strong>合法合规</strong>:确保所搭建的反向代理不用于违反法律法规的活动,包括但不限于绕过审查、非法数据传输、或其他违法用途。</li> <li><strong>尊重版权和隐私</strong>:遵守版权法律,确保所代理的内容不侵犯第三方的知识产权。同时,保障用户隐私,遵循数据保护的相关要求。</li> <li><strong>网络安全</strong>:采取必要的安全措施,防止反向代理服务被用于恶意目的,保障系统和用户数据的安全。</li> <li><strong>信息透明</strong>:确保提供的服务信息清晰透明,用户可以明确知晓反向代理的用途和可能的风险。</li> </ol> </div> <h2 id="前言摘要"><a class="anchor" href="#前言摘要">#</a> 前言 / 摘要</h2> <p>在当今互联网环境下,尤其是部分国外和国内网站常常由于 DNS 污染和其他原因而无法正常访问,这成为了许多用户的一大困扰。此外,有些网站虽然仅能通过 IP 地址进行访问,却无法绑定自定义域名,这同样限制了其灵活性和可用性。为了解决这些问题,搭建一个反向代理服务器成为了一个有效的解决方案。反向代理不仅可以帮助用户绕过 DNS 污染的问题,还能让我们以自定义的域名来访问那些仅能通过 IP 地址访问的网站。</p> <p>在本篇文章中,我们将利用 Netlify 这一强大而易于使用的工具来搭建反向代理。Netlify 的强大之处在于其简洁的配置过程和强大的功能,使得即使是对技术不太熟悉的用户也能轻松上手。要完成这项任务,你只需具备两个基本条件:一个 Netlify 账号和一个 GitHub 账号。接下来,我们将详细介绍如何通过这两个账户配置反向代理。</p> <h2 id="正文"><a class="anchor" href="#正文">#</a> 正文</h2> <div class="note info"> <p><strong>温馨提示</strong><br /> 标题后面有 (选) 的为后台相关内容,如不需要可以跳过</p> </div> <h3 id="第一步-准备用于搭建反代的环境"><a class="anchor" href="#第一步-准备用于搭建反代的环境">#</a> 第一步 准备用于搭建反代的环境</h3> <h4 id="1-创建储存库"><a class="anchor" href="#1-创建储存库">#</a> 1. 创建储存库</h4> <p>创建一个用于存放 Netlify 配置文件的 GitHub 储存库</p> <p>如图:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/1726582387299_23298110f4e294999cce8e5ddb9919ed.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/1726582387299_23298110f4e294999cce8e5ddb9919ed.png" /></p> <h4 id="2-创建配置文件"><a class="anchor" href="#2-创建配置文件">#</a> 2. 创建配置文件</h4> <p>新建名为 <code>netlify.toml</code> 的配置文件</p> <p>如图:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_b32990708afc79c8ac57533641e18942.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_b32990708afc79c8ac57533641e18942.png" /></p> <p>文件内容为:</p> <p><figure class="highlight toml"><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="section">[[redirects]]</span></span><br><span class="line"> <span class="attr">from</span> = <span class="string">&quot;/*&quot;</span></span><br><span class="line"> <span class="attr">to</span> = <span class="string">&quot;https://github.com/:splat&quot;</span></span><br><span class="line"> <span class="attr">status</span> = <span class="number">200</span></span><br></pre></td></tr></table></figure></p> <h4 id="选择性内容"><a class="anchor" href="#选择性内容">#</a> 选择性内容</h4> <p>再新建一个储存库,用于搭建管理后台 (选)</p> <p>如图:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/1726582387299_23298110f4e294999cce8e5ddb9919ed.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/1726582387299_23298110f4e294999cce8e5ddb9919ed.png" /></p> <h5 id="储存库中包含的文件选"><a class="anchor" href="#储存库中包含的文件选">#</a> 储存库中包含的文件 (选):</h5> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">│ index.html</span><br><span class="line">│ package.json</span><br><span class="line">│ README.md</span><br><span class="line">│</span><br><span class="line">└─netlify</span><br><span class="line">  └─functions</span><br><span class="line">    auth-callback.js</span><br><span class="line">    check-auth.js</span><br><span class="line">    update-redirect.js</span><br></pre></td></tr></table></figure></p> <ol> <li><strong>index.html</strong>:应用的主要前端页面,包含用户登录和配置反向代理的表单。(选)</li> </ol> <div class="note info"> <p><strong>温馨提示</strong><br /> 请在代码中的【这里填你的反代网站,不是后台】中填入你的反代网址 (就是用存放 Netlify 配置文件的 GitHub 储存库搭建的那个)【这里填你的 GitHub clientid】中填入你的 GitHub clientid,获取方法见下文</p> </div> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;zh&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">title</span>&gt;</span>反代配置<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">body</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-family</span>: Arial, sans-serif;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>: <span class="built_in">linear-gradient</span>(to bottom, <span class="number">#87CEFA</span>, <span class="number">#FFFFFF</span>);</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: flex;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">justify-content</span>: center;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">align-items</span>: center;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">height</span>: <span class="number">100vh</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">overflow-x</span>: hidden;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.container</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-align</span>: center;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="number">90%</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">max-width</span>: <span class="number">500px</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">h1</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#333</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-bottom</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">1.8em</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">form</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>: <span class="number">#f9f9f9</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">15px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">4px</span> <span class="number">8px</span> <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.1</span>);</span></span><br><span class="line"><span class="language-css"> <span class="attribute">transition</span>: transform <span class="number">0.3s</span> ease-in-out;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">form</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">transform</span>: <span class="built_in">scale</span>(<span class="number">1.02</span>);</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">label</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">1.2em</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: block;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-bottom</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#555</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">input</span><span class="selector-attr">[type=<span class="string">&quot;url&quot;</span>]</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="built_in">calc</span>(<span class="number">100%</span> - <span class="number">22px</span>);</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">8px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#ddd</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-bottom</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">1em</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">box-sizing</span>: border-box;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">button</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: <span class="number">#87CEFA</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: white;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>: none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">10px</span> <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">8px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">1.1em</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">transition</span>: background-color <span class="number">0.3s</span> ease-in-out;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">button</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: <span class="number">#00BFFF</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-id">#message</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">1.2em</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#333</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-top</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.error-container</span>,</span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.success-container</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>: <span class="number">#f0f8ff</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#d4edda</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">8px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-top</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">4px</span> <span class="number">8px</span> <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.1</span>);</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-align</span>: center;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.error-container</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-color</span>: <span class="number">#f5c6cb</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>: <span class="number">#f8d7da</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#721c24</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.success-container</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-color</span>: <span class="number">#c3e6cb</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>: <span class="number">#d4edda</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#155724</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.error-container</span> <span class="selector-tag">p</span>,</span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.success-container</span> <span class="selector-tag">p</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.success-container</span> <span class="selector-tag">button</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-top</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: <span class="number">#4CAF50</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>: none;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.success-container</span> <span class="selector-tag">button</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: <span class="number">#45a049</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.tooltip</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">position</span>: relative;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: inline-block;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.tooltip</span> <span class="selector-class">.tooltiptext</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">visibility</span>: hidden;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="number">200px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: <span class="number">#333</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#fff</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-align</span>: center;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">6px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">5px</span> <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">position</span>: absolute;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">z-index</span>: <span class="number">1</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">bottom</span>: <span class="number">125%</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">left</span>: <span class="number">50%</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-left</span>: -<span class="number">100px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">opacity</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">transition</span>: opacity <span class="number">0.3s</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.tooltip</span><span class="selector-pseudo">:hover</span> <span class="selector-class">.tooltiptext</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">visibility</span>: visible;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">opacity</span>: <span class="number">1</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-id">#loginContainer</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: none;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"> </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;container&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">h1</span>&gt;</span>反代配置器<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;loginContainer&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">p</span>&gt;</span>请登录以访问此页面。<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;loginButton&quot;</span>&gt;</span>使用 GitHub 登录<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">form</span> <span class="attr">id</span>=<span class="string">&quot;redirectForm&quot;</span> <span class="attr">style</span>=<span class="string">&quot;display: none;&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;tooltip&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">&quot;website&quot;</span>&gt;</span>请输入要反代到的网址:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;tooltiptext&quot;</span>&gt;</span>请输入完整的 URL 地址,例如 https://example.com<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;url&quot;</span> <span class="attr">id</span>=<span class="string">&quot;website&quot;</span> <span class="attr">name</span>=<span class="string">&quot;website&quot;</span> <span class="attr">required</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span>&gt;</span>提交<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;errorMessage&quot;</span> <span class="attr">class</span>=<span class="string">&quot;error-container&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">p</span> <span class="attr">id</span>=<span class="string">&quot;errorStatusMessage&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;successMessage&quot;</span> <span class="attr">class</span>=<span class="string">&quot;success-container&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">p</span> <span class="attr">id</span>=<span class="string">&quot;successStatusMessage&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;redirectButton&quot;</span> <span class="attr">style</span>=<span class="string">&quot;display: none;&quot;</span>&gt;</span>前往反代网站<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"> <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">checkAuthentication</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;/.netlify/functions/check-auth&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> result = <span class="keyword">await</span> response.<span class="title function_">json</span>();</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">if</span> (result.<span class="property">authenticated</span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;loginContainer&#x27;</span>).<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;redirectForm&#x27;</span>).<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;block&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;loginContainer&#x27;</span>).<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;block&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;redirectForm&#x27;</span>).<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125;</span></span><br><span class="line"><span class="language-javascript"> &#125;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;loginButton&#x27;</span>).<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">href</span> = <span class="string">`https://github.com/login/oauth/authorize?client_id=【这里填你的GitHub clientid】&amp;redirect_uri=<span class="subst">$&#123;<span class="built_in">encodeURIComponent</span>(<span class="variable language_">window</span>.location.origin + <span class="string">&#x27;/.netlify/functions/auth-callback&#x27;</span>)&#125;</span>`</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;redirectForm&#x27;</span>).<span class="title function_">addEventListener</span>(<span class="string">&#x27;submit&#x27;</span>, <span class="title function_">async</span> (event) =&gt; &#123;</span></span><br><span class="line"><span class="language-javascript"> event.<span class="title function_">preventDefault</span>();</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> website = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;website&#x27;</span>).<span class="property">value</span>;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> urlPattern = <span class="regexp">/^https?:\/\/[^\/]+$/</span>;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> errorMessageElement = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;errorStatusMessage&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> successMessageElement = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;successStatusMessage&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> errorContainer = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;errorMessage&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> successContainer = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;successMessage&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> redirectButton = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;redirectButton&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">if</span> (!urlPattern.<span class="title function_">test</span>(website)) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> suggestion = website.<span class="title function_">replace</span>(<span class="regexp">/\/+$/</span>, <span class="string">&#x27;&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript"> errorMessageElement.<span class="property">innerText</span> = <span class="string">`输入的 URL 格式不正确。请确保网址以 &#x27;https://example.com&#x27; 形式输入。你可能的正确输入是:<span class="subst">$&#123;suggestion&#125;</span>`</span>;</span></span><br><span class="line"><span class="language-javascript"> errorContainer.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;block&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> successContainer.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;/.netlify/functions/update-redirect&#x27;</span>, &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">method</span>: <span class="string">&#x27;POST&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">headers</span>: &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span></span></span><br><span class="line"><span class="language-javascript"> &#125;,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; website &#125;)</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> result = <span class="keyword">await</span> response.<span class="title function_">json</span>();</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">if</span> (result.<span class="property">message</span> === <span class="string">&#x27;Redirect updated successfully!&#x27;</span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> successMessageElement.<span class="property">innerText</span> = <span class="string">&#x27;反代配置成功!请等待服务器更新,预计1分钟。&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> successContainer.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;block&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> errorContainer.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> redirectButton.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;inline-block&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> redirectButton.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">href</span> = <span class="string">&#x27;【这里填你的反代网站,不是后台】&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> &#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="language-javascript"> errorMessageElement.<span class="property">innerText</span> = <span class="string">`配置失败:<span class="subst">$&#123;result.message&#125;</span>`</span>;</span></span><br><span class="line"><span class="language-javascript"> errorContainer.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;block&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> successContainer.<span class="property">style</span>.<span class="property">display</span> = <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125;</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// Initialize the authentication check</span></span></span><br><span class="line"><span class="language-javascript"> <span class="title function_">checkAuthentication</span>();</span></span><br><span class="line"><span class="language-javascript"> </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></p> <ol start="2"> <li><strong>/netlify/functions/auth-callback.js</strong>:处理 GitHub OAuth 回调的函数,设置用户的登录状态。(选)</li> </ol> <p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">exports</span>.<span class="property">handler</span> = <span class="keyword">async</span> <span class="keyword">function</span>(<span class="params">event, context</span>) &#123;</span><br><span class="line"> <span class="keyword">const</span> clientId = process.<span class="property">env</span>.<span class="property">GITHUB_CLIENT_ID</span>;</span><br><span class="line"> <span class="keyword">const</span> clientSecret = process.<span class="property">env</span>.<span class="property">GITHUB_CLIENT_SECRET</span>;</span><br><span class="line"> <span class="keyword">const</span> allowedUsers = process.<span class="property">env</span>.<span class="property">ALLOWED_USERS</span>.<span class="title function_">split</span>(<span class="string">&#x27;,&#x27;</span>);</span><br><span class="line"> <span class="keyword">const</span> jwtSecret = process.<span class="property">env</span>.<span class="property">JWT_SECRET</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> code = event.<span class="property">queryStringParameters</span>.<span class="property">code</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!code) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">400</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;Missing code parameter&#x27;</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> fetch = (<span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;node-fetch&#x27;</span>)).<span class="property">default</span>;</span><br><span class="line"> <span class="keyword">const</span> jwt = (<span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;jsonwebtoken&#x27;</span>)).<span class="property">default</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">`https://github.com/login/oauth/access_token`</span>, &#123;</span><br><span class="line"> <span class="attr">method</span>: <span class="string">&#x27;POST&#x27;</span>,</span><br><span class="line"> <span class="attr">headers</span>: &#123;</span><br><span class="line"> <span class="string">&#x27;Accept&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span></span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123;</span><br><span class="line"> <span class="attr">client_id</span>: clientId,</span><br><span class="line"> <span class="attr">client_secret</span>: clientSecret,</span><br><span class="line"> <span class="attr">code</span>: code</span><br><span class="line"> &#125;)</span><br><span class="line"> &#125;);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> data = <span class="keyword">await</span> response.<span class="title function_">json</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (data.<span class="property">error</span>) &#123;</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(data.<span class="property">error_description</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> userResponse = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;https://api.github.com/user&#x27;</span>, &#123;</span><br><span class="line"> <span class="attr">headers</span>: &#123;</span><br><span class="line"> <span class="title class_">Authorization</span>: <span class="string">`token <span class="subst">$&#123;data.access_token&#125;</span>`</span></span><br><span class="line"> &#125;</span><br><span class="line"> &#125;);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> userInfo = <span class="keyword">await</span> userResponse.<span class="title function_">json</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (allowedUsers.<span class="title function_">includes</span>(userInfo.<span class="property">login</span>)) &#123;</span><br><span class="line"> <span class="keyword">const</span> token = jwt.<span class="title function_">sign</span>(&#123; <span class="attr">username</span>: userInfo.<span class="property">login</span> &#125;, jwtSecret, &#123; <span class="attr">expiresIn</span>: <span class="string">&#x27;1h&#x27;</span> &#125;);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">302</span>,</span><br><span class="line"> <span class="attr">headers</span>: &#123;</span><br><span class="line"> <span class="string">&#x27;Set-Cookie&#x27;</span>: <span class="string">`token=<span class="subst">$&#123;token&#125;</span>; Path=/; HttpOnly`</span>,</span><br><span class="line"> <span class="string">&#x27;Location&#x27;</span>: <span class="string">&#x27;/&#x27;</span></span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="attr">body</span>: <span class="string">&#x27;&#x27;</span></span><br><span class="line"> &#125;;</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">403</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;Unauthorized&#x27;</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">500</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="string">`Error: <span class="subst">$&#123;error.message&#125;</span>`</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> <ol start="3"> <li><strong>/netlify/functions/check-auth.js</strong>:检查用户是否已登录的函数。(选)</li> </ol> <p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">exports</span>.<span class="property">handler</span> = <span class="keyword">async</span> <span class="keyword">function</span>(<span class="params">event, context</span>) &#123;</span><br><span class="line"> <span class="keyword">const</span> jwtSecret = process.<span class="property">env</span>.<span class="property">JWT_SECRET</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> cookieHeader = event.<span class="property">headers</span>.<span class="property">cookie</span> || <span class="string">&#x27;&#x27;</span>;</span><br><span class="line"> <span class="keyword">const</span> cookies = <span class="title class_">Object</span>.<span class="title function_">fromEntries</span>(cookieHeader.<span class="title function_">split</span>(<span class="string">&#x27;; &#x27;</span>).<span class="title function_">map</span>(<span class="function"><span class="params">cookie</span> =&gt;</span> cookie.<span class="title function_">split</span>(<span class="string">&#x27;=&#x27;</span>)));</span><br><span class="line"> <span class="keyword">const</span> token = cookies.<span class="property">token</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> jwt = (<span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;jsonwebtoken&#x27;</span>)).<span class="property">default</span>;</span><br><span class="line"> jwt.<span class="title function_">verify</span>(token, jwtSecret);</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">authenticated</span>: <span class="literal">true</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">403</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">authenticated</span>: <span class="literal">false</span> &#125;)</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> <ol start="4"> <li><strong>/netlify/functions/update-redirect.js</strong>:处理反向代理配置的函数。(选)</li> </ol> <div class="note info"> <p><strong>温馨提示</strong><br /> 请在代码中的【这里填入你的 GitHub 用户名】【用于存放 Netlify 配置文件的 GitHub 储存库名称】中分别填入你的 GitHub 用户名和用于存放 Netlify 配置文件的 GitHub 储存库名称,获取方法见下文</p> </div> <p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">exports</span>.<span class="property">handler</span></span><br><span class="line"><span class="keyword">const</span> jwtSecret = process.<span class="property">env</span>.<span class="property">JWT_SECRET</span>;</span><br><span class="line"> <span class="keyword">const</span> allowedUsers = process.<span class="property">env</span>.<span class="property">ALLOWED_USERS</span>.<span class="title function_">split</span>(<span class="string">&#x27;,&#x27;</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> cookieHeader = event.<span class="property">headers</span>.<span class="property">cookie</span> || <span class="string">&#x27;&#x27;</span>;</span><br><span class="line"> <span class="keyword">const</span> cookies = <span class="title class_">Object</span>.<span class="title function_">fromEntries</span>(cookieHeader.<span class="title function_">split</span>(<span class="string">&#x27;; &#x27;</span>).<span class="title function_">map</span>(<span class="function"><span class="params">cookie</span> =&gt;</span> cookie.<span class="title function_">split</span>(<span class="string">&#x27;=&#x27;</span>)));</span><br><span class="line"> <span class="keyword">const</span> token = cookies.<span class="property">token</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> decodedToken;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> jwt = (<span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;jsonwebtoken&#x27;</span>)).<span class="property">default</span>;</span><br><span class="line"> decodedToken = jwt.<span class="title function_">verify</span>(token, jwtSecret);</span><br><span class="line"> &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">403</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;Unauthorized&#x27;</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!allowedUsers.<span class="title function_">includes</span>(decodedToken.<span class="property">username</span>)) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">403</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;Unauthorized&#x27;</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> &#123; <span class="title class_">Octokit</span> &#125; = <span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;@octokit/rest&#x27;</span>);</span><br><span class="line"> <span class="keyword">const</span> octokit = <span class="keyword">new</span> <span class="title class_">Octokit</span>(&#123;</span><br><span class="line"> <span class="attr">auth</span>: process.<span class="property">env</span>.<span class="property">GITHUB_TOKEN</span></span><br><span class="line"> &#125;);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> &#123; website &#125; = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(event.<span class="property">body</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!website) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">400</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;No website provided&#x27;</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> fetch = (<span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;node-fetch&#x27;</span>)).<span class="property">default</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> &#123; <span class="attr">data</span>: fileData &#125; = <span class="keyword">await</span> octokit.<span class="property">repos</span>.<span class="title function_">getContent</span>(&#123;</span><br><span class="line"> <span class="attr">owner</span>: <span class="string">&#x27;【这里填入你的GitHub用户名】&#x27;</span>,</span><br><span class="line"> <span class="attr">repo</span>: <span class="string">&#x27;【用于存放Netlify配置文件的GitHub储存库名称】&#x27;</span>,</span><br><span class="line"> <span class="attr">path</span>: <span class="string">&#x27;netlify.toml&#x27;</span></span><br><span class="line"> &#125;);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> content = <span class="title class_">Buffer</span>.<span class="title function_">from</span>(fileData.<span class="property">content</span>, <span class="string">&#x27;base64&#x27;</span>).<span class="title function_">toString</span>();</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">const</span> newContent = content.<span class="title function_">replace</span>(<span class="regexp">/to\s*=\s*&quot;[^&quot;]+&quot;/</span>, <span class="string">`to = &quot;<span class="subst">$&#123;website&#125;</span>/:splat&quot;`</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">await</span> octokit.<span class="property">repos</span>.<span class="title function_">createOrUpdateFileContents</span>(&#123;</span><br><span class="line"> <span class="attr">owner</span>: <span class="string">&#x27;【这里填入你的GitHub用户名】&#x27;</span>,</span><br><span class="line"> <span class="attr">repo</span>: <span class="string">&#x27;【用于存放Netlify配置文件的GitHub储存库名称】&#x27;</span>,</span><br><span class="line"> <span class="attr">path</span>: <span class="string">&#x27;netlify.toml&#x27;</span>,</span><br><span class="line"> <span class="attr">message</span>: <span class="string">&#x27;Update redirect URL&#x27;</span>,</span><br><span class="line"> <span class="attr">content</span>: <span class="title class_">Buffer</span>.<span class="title function_">from</span>(newContent).<span class="title function_">toString</span>(<span class="string">&#x27;base64&#x27;</span>),</span><br><span class="line"> <span class="attr">sha</span>: fileData.<span class="property">sha</span></span><br><span class="line"> &#125;);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;Redirect updated successfully!&#x27;</span> &#125;)</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(error);</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="attr">statusCode</span>: <span class="number">500</span>,</span><br><span class="line"> <span class="attr">body</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">message</span>: <span class="string">&#x27;Failed to update redirect&#x27;</span> &#125;)</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> <ol start="5"> <li><strong>package.json</strong>:存放依赖的文件。(选)<br /> <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><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line"> <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Rcs,</span></span><br><span class="line"><span class="string"> &quot;</span>version<span class="string">&quot;: &quot;</span><span class="number">1.0</span><span class="number">.0</span><span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>description<span class="string">&quot;: &quot;</span>A reverse proxy configurator with GitHub authentication deployed on Netlify.<span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>main<span class="string">&quot;: &quot;</span>index.js<span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>scripts<span class="string">&quot;: &#123;</span></span><br><span class="line"><span class="string"> &quot;</span>start<span class="string">&quot;: &quot;</span>netlify dev<span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>build<span class="string">&quot;: &quot;</span>netlify build<span class="string">&quot;</span></span><br><span class="line"><span class="string"> &#125;,</span></span><br><span class="line"><span class="string"> &quot;</span>dependencies<span class="string">&quot;: &#123;</span></span><br><span class="line"><span class="string"> &quot;</span>@octokit/rest<span class="string">&quot;: &quot;</span>^<span class="number">19.0</span><span class="number">.7</span><span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>jsonwebtoken<span class="string">&quot;: &quot;</span>^<span class="number">9.0</span><span class="number">.2</span><span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>node-fetch<span class="string">&quot;: &quot;</span>^<span class="number">3.3</span><span class="number">.2</span><span class="string">&quot;</span></span><br><span class="line"><span class="string"> &#125;,</span></span><br><span class="line"><span class="string"> &quot;</span>devDependencies<span class="string">&quot;: &#123;</span></span><br><span class="line"><span class="string"> &quot;</span>netlify-cli<span class="string">&quot;: &quot;</span>^<span class="number">15.0</span><span class="number">.0</span><span class="string">&quot;</span></span><br><span class="line"><span class="string"> &#125;,</span></span><br><span class="line"><span class="string"> &quot;</span>engines<span class="string">&quot;: &#123;</span></span><br><span class="line"><span class="string"> &quot;</span>node<span class="string">&quot;: &quot;</span>&gt;=<span class="number">16.</span>x<span class="string">&quot;</span></span><br><span class="line"><span class="string"> &#125;,</span></span><br><span class="line"><span class="string"> &quot;</span>author<span class="string">&quot;: &quot;</span>j23<span class="string">&quot;,</span></span><br><span class="line"><span class="string"> &quot;</span>license<span class="string">&quot;: &quot;</span>MIT<span class="string">&quot;</span></span><br><span class="line"><span class="string">&#125;</span></span><br></pre></td></tr></table></figure></li> </ol> <h3 id="第二步-配置netlify"><a class="anchor" href="#第二步-配置netlify">#</a> 第二步 配置 Netlify</h3> <h4 id="1-创建一个站点"><a class="anchor" href="#1-创建一个站点">#</a> 1. 创建一个站点</h4> <p>如图:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_24ce560b9f2dc57d0d6f51bfebae6b71.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_24ce560b9f2dc57d0d6f51bfebae6b71.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_d0c9459ade47c217db7d74d4c0dc815f.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_d0c9459ade47c217db7d74d4c0dc815f.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_ee9fc4b5245b51661e8a91a2c509c959.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_ee9fc4b5245b51661e8a91a2c509c959.png" /></p> <ol start="4"> <li>选择你的用于存放 Netlify 配置文件的 GitHub 储存库</li> </ol> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_1f40a4eb848a567c69eee524172ba04a.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_1f40a4eb848a567c69eee524172ba04a.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE_17-9-2024_23297_app.netlify.com_9d63c0ed9504f5a945c156f026d8fc1f.jpeg" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/屏幕截图_17-9-2024_23297_app.netlify.com_9d63c0ed9504f5a945c156f026d8fc1f.jpeg" /></p> <h4 id="2配置自定义域名"><a class="anchor" href="#2配置自定义域名">#</a> 2. 配置自定义域名</h4> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_03b28a83de8ee0c91accd703fdca989d.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_03b28a83de8ee0c91accd703fdca989d.png" /></p> <div class="note info"> <p>自此所有基本操作已经完成,如果不需要配置后台,你只需要修改 Netlify 配置文件中的链接,就可以实现更换需要代理的网站。</p> </div> <p>修改内容如下 (注意!,网址格式必须为 https://example.com/,不能删去 https:// 也不能删去最后的 /):</p> <p><figure class="highlight toml"><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="section">[[redirects]]</span></span><br><span class="line"> <span class="attr">from</span> = <span class="string">&quot;/*&quot;</span></span><br><span class="line"> <span class="attr">to</span> = <span class="string">&quot;【修改这里】:splat&quot;</span></span><br><span class="line"> <span class="attr">status</span> = <span class="number">200</span></span><br></pre></td></tr></table></figure></p> <h3 id="选择性内容-2"><a class="anchor" href="#选择性内容-2">#</a> 选择性内容</h3> <h4 id="一github-登录"><a class="anchor" href="#一github-登录">#</a> 一.GitHub 登录</h4> <p>使用 GitHub 进行 OAuth 登录,确保只有授权用户可以访问配置功能。</p> <h5 id="第一步"><a class="anchor" href="#第一步">#</a> 第一步:</h5> <p>打开下面网址,并填好配置<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3NldHRpbmdzL2FwcGxpY2F0aW9ucy9uZXc="> https://github.com/settings/applications/new</span></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_08ba52609ba4bfe62f2563933cbba566.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_08ba52609ba4bfe62f2563933cbba566.png" /></p> <h5 id="第二步"><a class="anchor" href="#第二步">#</a> 第二步:</h5> <p>获取 Client ID,并生成 Client secrets,后面要用</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_038e6d1208bd8e0990b3b595a40f256e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_038e6d1208bd8e0990b3b595a40f256e.png" /><br /> 2.<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_0572103207489f7a3ae48fd3a3e2a2b6.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_0572103207489f7a3ae48fd3a3e2a2b6.png" /></p> <div class="note warning"> <p><strong>警告!</strong><br /> 请妥善保管好你的 Client secrets!</p> </div> <h4 id="二配置用于修改储存库的密钥"><a class="anchor" href="#二配置用于修改储存库的密钥">#</a> 二。配置用于修改储存库的密钥</h4> <ol> <li> <p>打开下面的网址<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3NldHRpbmdzL3Rva2Vucw=="> https://github.com/settings/tokens</span></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_29ac6da4b073ffc18764a3748bcc885a.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_29ac6da4b073ffc18764a3748bcc885a.png" /></p> </li> <li> <p>填入相关内容,选择不过期,勾选储存库</p> </li> </ol> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_bdfead6a17b8cdf05219e9ae7e9bd799.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_bdfead6a17b8cdf05219e9ae7e9bd799.png" /></p> <ol start="3"> <li>获取到密钥</li> </ol> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_56563b4d40ebd00c25c2ddbc0aea9565.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_56563b4d40ebd00c25c2ddbc0aea9565.png" /></p> <div class="note warning"> <p><strong>警告!</strong><br /> 请妥善保管好你的密钥</p> </div> <h4 id="三配置netlify"><a class="anchor" href="#三配置netlify">#</a> 三。配置 Netlify</h4> <h5 id="第一步创建站点"><a class="anchor" href="#第一步创建站点">#</a> 第一步:创建站点</h5> <p>如图:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_24ce560b9f2dc57d0d6f51bfebae6b71.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_24ce560b9f2dc57d0d6f51bfebae6b71.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_d0c9459ade47c217db7d74d4c0dc815f.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_d0c9459ade47c217db7d74d4c0dc815f.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_ee9fc4b5245b51661e8a91a2c509c959.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_ee9fc4b5245b51661e8a91a2c509c959.png" /></p> <ol start="4"> <li>选择你的后台储存库</li> </ol> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_1f40a4eb848a567c69eee524172ba04a.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_1f40a4eb848a567c69eee524172ba04a.png" /></p> <ol start="5"> <li>填入环境变量<br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ALLOWED_USERS:你授权使用后台的GitHub用户名,用半角逗号隔开,如果只有一个用户,则无需逗号。如:用户名1,用户名2</span><br><span class="line">GITHUB_CLIENT_ID:你的CLIENT_ID</span><br><span class="line">GITHUB_CLIENT_SECRET:你的CLIENT_SECRET</span><br><span class="line">GITHUB_TOKEN:你的GitHub账号密钥</span><br><span class="line">JWT_SECRET:一个随机的不限位数的字符串,如wfhehfihwjdwefnabwaieu72dub3uigfvqty2UGQWADIWGADIY3UGF378</span><br></pre></td></tr></table></figure></li> </ol> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_5bb90ceb6dd257c5c3e51cd20423f929.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_5bb90ceb6dd257c5c3e51cd20423f929.png" /><br /> 如果这一步漏掉了,可以在下面页面找到并补充</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_1184a04b95f68e809a5360a9e5925ecc.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_1184a04b95f68e809a5360a9e5925ecc.png" /></p> <h5 id="第二步配置自定义域名"><a class="anchor" href="#第二步配置自定义域名">#</a> 第二步。配置自定义域名</h5> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_03b28a83de8ee0c91accd703fdca989d.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_03b28a83de8ee0c91accd703fdca989d.png" /></p> <h2 id="结尾"><a class="anchor" href="#结尾">#</a> 结尾</h2> <p>非常感谢你能看到这里,如有什么问题欢迎在评论区中提出!如果可以的话,请订阅我的网站:<a href="https://jdjwzx233.cn/Subscribe">https://jdjwzx233.cn/Subscribe</a><br /> 如果你觉得我的博客不错的话,可以赞助我 (・̀ ω・́)✧:<a href="https://jdjwzx233.cn/support">https://jdjwzx233.cn/support</a>。</p>

2024/9/17
阅读更多

搭建jsdelivr镜像(又拍云/nginx/cfwokers/Deno)

<h2 id="前言"><a class="anchor" href="#前言">#</a> 前言</h2> <p>jsDelivr —— 一个免费、快速、可靠的为 JS 和开源项目服务的 CDN。但是由于国内访问速度慢,加之 jsDelivr 备案被吊销和 DNS 污染常出现,国内使用了 jsDelivr 的站点常常出现访问速度慢的问题。<br /> 你可能会问,为什么不去使用别人的镜像站呢?俗话说 &quot;自己动手,丰衣足食&quot;,自建镜像站可以让你更好地掌握自己的数据和服务。使用第三方镜像站存在一些潜在的风险和不确定性。首先,你无法确定第三方镜像站的可靠性和稳定性,它们可能在任何时候关闭或遭遇故障。这将对你的站点造成严重影响,可能导致服务中断。其次,第三方镜像站可能无法及时更新和同步你的站点内容,导致访问者无法获取最新的信息。最后,自建镜像站可以让你更加灵活地定制和管理自己的站点,满足特定需求和提供更好的用户体验。因此,建议在可行的情况下,考虑自建镜像站来确保数据的安全和可靠性。</p> <p>同时,本文也适用于其他网站的镜像搭建。</p> <h2 id="方法一使用又拍云搭建"><a class="anchor" href="#方法一使用又拍云搭建">#</a> 方法一:使用又拍云搭建</h2> <h3 id="优点"><a class="anchor" href="#优点">#</a> 优点:</h3> <ol> <li>又拍云是国内知名企业级云服务商,其服务极速、稳定、简单易用,用来搭建镜像站是十分合适的。又拍云有非常多的优惠:加入又拍云联盟 (网站需备案,要在网站 / 应用底部添加又拍云 LOGO 并指向官网) 后,可以获得每月 10G 储存空间和 15G 的 CDN 流量 (按年发放,以 67 元的代金卷发放到账户);新用户注册 (<span class="exturl" data-url="aHR0cHM6Ly9jb25zb2xlLnVweXVuLmNvbS9yZWdpc3Rlci8/aW52aXRlPXRJOGxqaXhJVA==">点我注册</span>) 还可以直接获得 61 元的代金卷 (有效期一年)。在这些优惠的加成下,你可以零成本搭建一个镜像站。</li> </ol> <p>2. 加速效果明显 (如图)</p> <p>加速前:<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/blog_img_%E5%8A%A0%E9%80%9F%E5%89%8D_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/blog_img_加速前_d41d8cd98f00b204e9800998ecf8427e.png" title="加速前" /></p> <p>加速后:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/blog_img_%E5%8A%A0%E9%80%9F%E5%90%8E_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/blog_img_加速后_d41d8cd98f00b204e9800998ecf8427e.png" title="加速后" /></p> <h3 id="缺点"><a class="anchor" href="#缺点">#</a> 缺点:</h3> <p>需要备案!!!</p> <h3 id="推荐指数"><a class="anchor" href="#推荐指数">#</a> 推荐指数:⭐⭐⭐⭐⭐</h3> <h3 id="搭建方法"><a class="anchor" href="#搭建方法">#</a> 搭建方法:</h3> <h4 id="第一步"><a class="anchor" href="#第一步">#</a> 第一步:</h4> <p>创建又拍云账户 (<span class="exturl" data-url="aHR0cHM6Ly9jb25zb2xlLnVweXVuLmNvbS9yZWdpc3Rlci8/aW52aXRlPXRJOGxqaXhJVA==">点我注册</span>)</p> <h4 id="第二步"><a class="anchor" href="#第二步">#</a> 第二步:</h4> <p>进入控制台的 CDN 管理界面 (<span class="exturl" data-url="aHR0cHM6Ly9jb25zb2xlLnVweXVuLmNvbS9zZXJ2aWNlcy9jZG4v">https://console.upyun.com/services/cdn/</span>), 并创建服务,然后配置服务 (具体参数如下)。</p> <ol> <li>服务名称:唯一标识服务,例如:image-upyun-com,一个服务下面可以绑定多个自有域名。</li> </ol> <div class="note info"> <p><strong>注意事项</strong><br /> 服务名称仅限 5~20 位; 必须以小写英文字符开头,仅支持小写英文字符、数字、中划线组合。</p> </div> <ol start="2"> <li>加速域名:填写此次需要配置的加速域名。</li> </ol> <div class="note info"> <p><strong>注意事项</strong><br /> 加速域名必须已在工信部备案; 待加速域名尚未在又拍云 CDN 平台配置。</p> </div> <p>加速域名需要进行<span class="exturl" data-url="aHR0cHM6Ly9oZWxwLnVweXVuLmNvbS9rbm93bGVkZ2UtYmFzZS9kb21haW4tdmVyaWZ5Lw==">域名所有权验证</span>,验证通过后方能添加成功。</p> <ol start="3"> <li>应用场景:这里选择全站加速</li> <li>回源协议:选协议跟随。</li> <li>源站证书校验:切记!!不要打开 (实测开了以后不能用)!!!</li> <li>线路配置:源站地址填 <code>cdn.jsdelivr.net</code> , 端口号不要动。</li> </ol> <h4 id="第三步"><a class="anchor" href="#第三步">#</a> 第三步</h4> <ol> <li>服务创建成功后,操作界面会提示 CDN 加速服务创建成功,并会自动跳转到该服务的【功能配置】界面</li> <li>在功能配置界面,有域名管理、回源管理、缓存配置、性能优化、HTTPS、访问控制、图片处理等功能配置模块,在【域名管理】模块下,可以针对该服务绑定多个自有域名,请耐心等待域名配置(约 10 分钟),查看域名对应的状态是否为[正常]</li> <li>可查看 CDN 平台为您分配的 CNAME 地址,此时需要去域名 DNS 解析商处,为该域名添加一条 CNAME 记录,待 CNAME 配置生效之后,方可使用 CDN 服务。</li> </ol> <h4 id="第四步非必要但是可以提升体验"><a class="anchor" href="#第四步非必要但是可以提升体验">#</a> 第四步 (非必要,但是可以提升体验)</h4> <ol> <li> <p>配置 HTTPS: 点击 [HTTPS], 点击 &quot;HTTPS 配置&quot; 右边的管理 (如图)<img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/image_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/image_d41d8cd98f00b204e9800998ecf8427e.png" /> 然后你可以选择添加自有证书或直接使用又拍云注册证书 (<span class="exturl" data-url="aHR0cHM6Ly9jb25zb2xlLnVweXVuLmNvbS90b29sYm94L3NzbC8=">点我前往证书管理</span>)。添加完后,打开 [HTTPS 访问],不建议勾选 [强制 HTTPS 访问]。</p> </li> <li> <p>建议打开智能压缩和页面压缩 (如图)<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703354977231_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703354977231_d41d8cd98f00b204e9800998ecf8427e.png" /></p> </li> <li> <p>建议配置缓存、浏览器缓存和分段缓存 (如图)<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355090340_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355090340_d41d8cd98f00b204e9800998ecf8427e.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355115278_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355115278_d41d8cd98f00b204e9800998ecf8427e.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355198422_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355198422_d41d8cd98f00b204e9800998ecf8427e.png" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355224230_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355224230_d41d8cd98f00b204e9800998ecf8427e.png" /></p> </li> <li> <p>在 [访问控制] 中,打开 Referer 防盗链、WAF 保护、HTTP 请求体大小限制、IP 访问限制 (如图)<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355343968_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355343968_d41d8cd98f00b204e9800998ecf8427e.png" /><br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355382813_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355382813_d41d8cd98f00b204e9800998ecf8427e.png" /><br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355473637_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355473637_d41d8cd98f00b204e9800998ecf8427e.png" /><br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355505400_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703355505400_d41d8cd98f00b204e9800998ecf8427e.png" /></p> <div class="note info"> <p>此配置仅作参考,请根据实际情况进行配置!</p> </div> </li> <li> <p>你还可以配置 [边缘规则],来实现一些特殊效果。(这里不做演示)</p> </li> </ol> <h2 id="方法二使用cloudflare-workers搭建"><a class="anchor" href="#方法二使用cloudflare-workers搭建">#</a> 方法二:使用 Cloudflare workers 搭建</h2> <h3 id="优点-2"><a class="anchor" href="#优点-2">#</a> 优点:</h3> <ol> <li>简单,步骤少,加速范围广</li> <li>无需备案,加速效果较好 (如图)<br /> 加速前:<img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/blog_img_%E5%8A%A0%E9%80%9F%E5%89%8D_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/blog_img_加速前_d41d8cd98f00b204e9800998ecf8427e.png" title="加速前" /><br /> 加速后:<img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/cfwokerjsd_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/cfwokerjsd_d41d8cd98f00b204e9800998ecf8427e.png" title="加速后" /></li> <li>无费用,每天有免费额度 (每天免费 100000 个请求)</li> </ol> <h3 id="缺点-2"><a class="anchor" href="#缺点-2">#</a> 缺点:</h3> <ol> <li>部分地区访问较慢</li> <li>免费额度较少,对于访问量大的站点可能不够</li> <li>需要有一个挂在 cloudflare 的域名</li> </ol> <h3 id="推荐指数-2"><a class="anchor" href="#推荐指数-2">#</a> 推荐指数:⭐⭐⭐⭐</h3> <h3 id="搭建方法-2"><a class="anchor" href="#搭建方法-2">#</a> 搭建方法</h3> <h4 id="第一步-2"><a class="anchor" href="#第一步-2">#</a> 第一步</h4> <ol> <li>在 Cloudflare 管理面板的 [Workers 和 Pages] 栏 -&gt;[概述]-&gt;[创建应用程序]-&gt;[创建 Worker](如图)<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703396996483_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703396996483_d41d8cd98f00b204e9800998ecf8427e.png" /><br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703397051051_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703397051051_d41d8cd98f00b204e9800998ecf8427e.png" /></li> <li>随便填一个名称,点击 [部署](如图)</li> </ol> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703397134262_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703397134262_d41d8cd98f00b204e9800998ecf8427e.png" /></p> <h4 id="第二步-2"><a class="anchor" href="#第二步-2">#</a> 第二步</h4> <ol> <li>在创建完成的页面点击 [编辑代码](如图)<img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703397288998_d41d8cd98f00b204e9800998ecf8427e.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/23/12/24/1703397288998_d41d8cd98f00b204e9800998ecf8427e.png" /></li> <li>将以下代码直接粘贴进代码框:</li> </ol> <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><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&#x27;use strict&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * static files (404.html, sw.js, conf.js)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">ASSET_URL</span> = <span class="string">&#x27;https://cdn.jsdelivr.net&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">JS_VER</span> = <span class="number">10</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">MAX_RETRY</span> = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/** <span class="doctag">@type</span> &#123;<span class="type">RequestInit</span>&#125; */</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">PREFLIGHT_INIT</span> = &#123;</span><br><span class="line"> <span class="attr">status</span>: <span class="number">204</span>,</span><br><span class="line"> <span class="attr">headers</span>: <span class="keyword">new</span> <span class="title class_">Headers</span>(&#123;</span><br><span class="line"> <span class="string">&#x27;access-control-allow-origin&#x27;</span>: <span class="string">&#x27;*&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;access-control-allow-methods&#x27;</span>: <span class="string">&#x27;GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;access-control-max-age&#x27;</span>: <span class="string">&#x27;1728000&#x27;</span>,</span><br><span class="line"> &#125;),</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">any</span>&#125; <span class="variable">body</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">number</span>&#125; <span class="variable">status</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">Object&lt;string, string&gt;</span>&#125; <span class="variable">headers</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">makeRes</span>(<span class="params">body, status = <span class="number">200</span>, headers = &#123;&#125;</span>) &#123;</span><br><span class="line"> headers[<span class="string">&#x27;--ver&#x27;</span>] = <span class="variable constant_">JS_VER</span></span><br><span class="line"> headers[<span class="string">&#x27;access-control-allow-origin&#x27;</span>] = <span class="string">&#x27;*&#x27;</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(body, &#123;status, headers&#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; urlStr </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">newUrl</span>(<span class="params">urlStr</span>) &#123;</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title function_">URL</span>(urlStr)</span><br><span class="line"> &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="title function_">addEventListener</span>(<span class="string">&#x27;fetch&#x27;</span>, <span class="function"><span class="params">e</span> =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> ret = <span class="title function_">fetchHandler</span>(e)</span><br><span class="line"> .<span class="title function_">catch</span>(<span class="function"><span class="params">err</span> =&gt;</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;cfworker error:\n&#x27;</span> + err.<span class="property">stack</span>, <span class="number">502</span>))</span><br><span class="line"> e.<span class="title function_">respondWith</span>(ret)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">FetchEvent</span>&#125; e </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">fetchHandler</span>(<span class="params">e</span>) &#123;</span><br><span class="line"> <span class="keyword">const</span> req = e.<span class="property">request</span></span><br><span class="line"> <span class="keyword">const</span> urlStr = req.<span class="property">url</span></span><br><span class="line"> <span class="keyword">const</span> urlObj = <span class="keyword">new</span> <span class="title function_">URL</span>(urlStr)</span><br><span class="line"> <span class="keyword">const</span> path = urlObj.<span class="property">href</span>.<span class="title function_">substr</span>(urlObj.<span class="property">origin</span>.<span class="property">length</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (urlObj.<span class="property">protocol</span> === <span class="string">&#x27;http:&#x27;</span>) &#123;</span><br><span class="line"> urlObj.<span class="property">protocol</span> = <span class="string">&#x27;https:&#x27;</span></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;&#x27;</span>, <span class="number">301</span>, &#123;</span><br><span class="line"> <span class="string">&#x27;strict-transport-security&#x27;</span>: <span class="string">&#x27;max-age=99999999; includeSubDomains; preload&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;location&#x27;</span>: urlObj.<span class="property">href</span>,</span><br><span class="line"> &#125;)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (path.<span class="title function_">startsWith</span>(<span class="string">&#x27;/http/&#x27;</span>)) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">httpHandler</span>(req, path.<span class="title function_">substr</span>(<span class="number">6</span>))</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">switch</span> (path) &#123;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">&#x27;/http&#x27;</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;请更新 cfworker 到最新版本!&#x27;</span>)</span><br><span class="line"> <span class="keyword">case</span> <span class="string">&#x27;/ws&#x27;</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;not support&#x27;</span>, <span class="number">400</span>)</span><br><span class="line"> <span class="keyword">case</span> <span class="string">&#x27;/works&#x27;</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;it works&#x27;</span>)</span><br><span class="line"> <span class="attr">default</span>:</span><br><span class="line"> <span class="comment">// static files</span></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">fetch</span>(<span class="variable constant_">ASSET_URL</span> + path)</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">Request</span>&#125; <span class="variable">req</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; <span class="variable">pathname</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">httpHandler</span>(<span class="params">req, pathname</span>) &#123;</span><br><span class="line"> <span class="keyword">const</span> reqHdrRaw = req.<span class="property">headers</span></span><br><span class="line"> <span class="keyword">if</span> (reqHdrRaw.<span class="title function_">has</span>(<span class="string">&#x27;x-jsproxy&#x27;</span>)) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="title class_">Response</span>.<span class="title function_">error</span>()</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// preflight</span></span><br><span class="line"> <span class="keyword">if</span> (req.<span class="property">method</span> === <span class="string">&#x27;OPTIONS&#x27;</span> &amp;&amp;</span><br><span class="line"> reqHdrRaw.<span class="title function_">has</span>(<span class="string">&#x27;access-control-request-headers&#x27;</span>)</span><br><span class="line"> ) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(<span class="literal">null</span>, <span class="variable constant_">PREFLIGHT_INIT</span>)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> acehOld = <span class="literal">false</span></span><br><span class="line"> <span class="keyword">let</span> rawSvr = <span class="string">&#x27;&#x27;</span></span><br><span class="line"> <span class="keyword">let</span> rawLen = <span class="string">&#x27;&#x27;</span></span><br><span class="line"> <span class="keyword">let</span> rawEtag = <span class="string">&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> reqHdrNew = <span class="keyword">new</span> <span class="title class_">Headers</span>(reqHdrRaw)</span><br><span class="line"> reqHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;x-jsproxy&#x27;</span>, <span class="string">&#x27;1&#x27;</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 此处逻辑和 http-dec-req-hdr.lua 大致相同</span></span><br><span class="line"> <span class="comment">// https://github.com/EtherDream/jsproxy/blob/master/lua/http-dec-req-hdr.lua</span></span><br><span class="line"> <span class="keyword">const</span> refer = reqHdrNew.<span class="title function_">get</span>(<span class="string">&#x27;referer&#x27;</span>)</span><br><span class="line"> <span class="keyword">const</span> query = refer.<span class="title function_">substr</span>(refer.<span class="title function_">indexOf</span>(<span class="string">&#x27;?&#x27;</span>) + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">if</span> (!query) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;missing params&#x27;</span>, <span class="number">403</span>)</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">const</span> param = <span class="keyword">new</span> <span class="title class_">URLSearchParams</span>(query)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">const</span> [k, v] <span class="keyword">of</span> <span class="title class_">Object</span>.<span class="title function_">entries</span>(param)) &#123;</span><br><span class="line"> <span class="keyword">if</span> (k.<span class="title function_">substr</span>(<span class="number">0</span>, <span class="number">2</span>) === <span class="string">&#x27;--&#x27;</span>) &#123;</span><br><span class="line"> <span class="comment">// 系统信息</span></span><br><span class="line"> <span class="keyword">switch</span> (k.<span class="title function_">substr</span>(<span class="number">2</span>)) &#123;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">&#x27;aceh&#x27;</span>:</span><br><span class="line"> acehOld = <span class="literal">true</span></span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">&#x27;raw-info&#x27;</span>:</span><br><span class="line"> [rawSvr, rawLen, rawEtag] = v.<span class="title function_">split</span>(<span class="string">&#x27;|&#x27;</span>)</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> &#125;</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// 还原 HTTP 请求头</span></span><br><span class="line"> <span class="keyword">if</span> (v) &#123;</span><br><span class="line"> reqHdrNew.<span class="title function_">set</span>(k, v)</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> reqHdrNew.<span class="title function_">delete</span>(k)</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!param.<span class="title function_">has</span>(<span class="string">&#x27;referer&#x27;</span>)) &#123;</span><br><span class="line"> reqHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;referer&#x27;</span>)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// cfworker 会把路径中的 `//` 合并成 `/`</span></span><br><span class="line"> <span class="keyword">const</span> urlStr = pathname.<span class="title function_">replace</span>(<span class="regexp">/^(https?):\/+/</span>, <span class="string">&#x27;$1://&#x27;</span>)</span><br><span class="line"> <span class="keyword">const</span> urlObj = <span class="title function_">newUrl</span>(urlStr)</span><br><span class="line"> <span class="keyword">if</span> (!urlObj) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(<span class="string">&#x27;invalid proxy url: &#x27;</span> + urlStr, <span class="number">403</span>)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** <span class="doctag">@type</span> &#123;<span class="type">RequestInit</span>&#125; */</span></span><br><span class="line"> <span class="keyword">const</span> reqInit = &#123;</span><br><span class="line"> <span class="attr">method</span>: req.<span class="property">method</span>,</span><br><span class="line"> <span class="attr">headers</span>: reqHdrNew,</span><br><span class="line"> <span class="attr">redirect</span>: <span class="string">&#x27;manual&#x27;</span>,</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (req.<span class="property">method</span> === <span class="string">&#x27;POST&#x27;</span>) &#123;</span><br><span class="line"> reqInit.<span class="property">body</span> = req.<span class="property">body</span></span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">proxy</span>(urlObj, reqInit, acehOld, rawLen, <span class="number">0</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">URL</span>&#125; urlObj </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">RequestInit</span>&#125; reqInit </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">number</span>&#125; retryTimes </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">proxy</span>(<span class="params">urlObj, reqInit, acehOld, rawLen, retryTimes</span>) &#123;</span><br><span class="line"> <span class="keyword">const</span> res = <span class="keyword">await</span> <span class="title function_">fetch</span>(urlObj.<span class="property">href</span>, reqInit)</span><br><span class="line"> <span class="keyword">const</span> resHdrOld = res.<span class="property">headers</span></span><br><span class="line"> <span class="keyword">const</span> resHdrNew = <span class="keyword">new</span> <span class="title class_">Headers</span>(resHdrOld)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> expose = <span class="string">&#x27;*&#x27;</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">const</span> [k, v] <span class="keyword">of</span> resHdrOld.<span class="title function_">entries</span>()) &#123;</span><br><span class="line"> <span class="keyword">if</span> (k === <span class="string">&#x27;access-control-allow-origin&#x27;</span> ||</span><br><span class="line"> k === <span class="string">&#x27;access-control-expose-headers&#x27;</span> ||</span><br><span class="line"> k === <span class="string">&#x27;location&#x27;</span> ||</span><br><span class="line"> k === <span class="string">&#x27;set-cookie&#x27;</span></span><br><span class="line"> ) &#123;</span><br><span class="line"> <span class="keyword">const</span> x = <span class="string">&#x27;--&#x27;</span> + k</span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(x, v)</span><br><span class="line"> <span class="keyword">if</span> (acehOld) &#123;</span><br><span class="line"> expose = expose + <span class="string">&#x27;,&#x27;</span> + x</span><br><span class="line"> &#125;</span><br><span class="line"> resHdrNew.<span class="title function_">delete</span>(k)</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (acehOld &amp;&amp;</span><br><span class="line"> k !== <span class="string">&#x27;cache-control&#x27;</span> &amp;&amp;</span><br><span class="line"> k !== <span class="string">&#x27;content-language&#x27;</span> &amp;&amp;</span><br><span class="line"> k !== <span class="string">&#x27;content-type&#x27;</span> &amp;&amp;</span><br><span class="line"> k !== <span class="string">&#x27;expires&#x27;</span> &amp;&amp;</span><br><span class="line"> k !== <span class="string">&#x27;last-modified&#x27;</span> &amp;&amp;</span><br><span class="line"> k !== <span class="string">&#x27;pragma&#x27;</span></span><br><span class="line"> ) &#123;</span><br><span class="line"> expose = expose + <span class="string">&#x27;,&#x27;</span> + k</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (acehOld) &#123;</span><br><span class="line"> expose = expose + <span class="string">&#x27;,--s&#x27;</span></span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;--t&#x27;</span>, <span class="string">&#x27;1&#x27;</span>)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// verify</span></span><br><span class="line"> <span class="keyword">if</span> (rawLen) &#123;</span><br><span class="line"> <span class="keyword">const</span> newLen = resHdrOld.<span class="title function_">get</span>(<span class="string">&#x27;content-length&#x27;</span>) || <span class="string">&#x27;&#x27;</span></span><br><span class="line"> <span class="keyword">const</span> badLen = (rawLen !== newLen)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (badLen) &#123;</span><br><span class="line"> <span class="keyword">if</span> (retryTimes &lt; <span class="variable constant_">MAX_RETRY</span>) &#123;</span><br><span class="line"> urlObj = <span class="keyword">await</span> <span class="title function_">parseYtVideoRedir</span>(urlObj, newLen, res)</span><br><span class="line"> <span class="keyword">if</span> (urlObj) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">proxy</span>(urlObj, reqInit, acehOld, rawLen, retryTimes + <span class="number">1</span>)</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">makeRes</span>(res.<span class="property">body</span>, <span class="number">400</span>, &#123;</span><br><span class="line"> <span class="string">&#x27;--error&#x27;</span>: <span class="string">`bad len: <span class="subst">$&#123;newLen&#125;</span>, except: <span class="subst">$&#123;rawLen&#125;</span>`</span>,</span><br><span class="line"> <span class="string">&#x27;access-control-expose-headers&#x27;</span>: <span class="string">&#x27;--error&#x27;</span>,</span><br><span class="line"> &#125;)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (retryTimes &gt; <span class="number">1</span>) &#123;</span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;--retry&#x27;</span>, retryTimes)</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> status = res.<span class="property">status</span></span><br><span class="line"></span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;access-control-expose-headers&#x27;</span>, expose)</span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;access-control-allow-origin&#x27;</span>, <span class="string">&#x27;*&#x27;</span>)</span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;--s&#x27;</span>, status)</span><br><span class="line"> resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;--ver&#x27;</span>, <span class="variable constant_">JS_VER</span>)</span><br><span class="line"></span><br><span class="line"> resHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;content-security-policy&#x27;</span>)</span><br><span class="line"> resHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;content-security-policy-report-only&#x27;</span>)</span><br><span class="line"> resHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;clear-site-data&#x27;</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (status === <span class="number">301</span> ||</span><br><span class="line"> status === <span class="number">302</span> ||</span><br><span class="line"> status === <span class="number">303</span> ||</span><br><span class="line"> status === <span class="number">307</span> ||</span><br><span class="line"> status === <span class="number">308</span></span><br><span class="line"> ) &#123;</span><br><span class="line"> status = status + <span class="number">10</span></span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(res.<span class="property">body</span>, &#123;</span><br><span class="line"> status,</span><br><span class="line"> <span class="attr">headers</span>: resHdrNew,</span><br><span class="line"> &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">URL</span>&#125; urlObj </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">isYtUrl</span>(<span class="params">urlObj</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> urlObj.<span class="property">host</span>.<span class="title function_">endsWith</span>(<span class="string">&#x27;.googlevideo.com&#x27;</span>) &amp;&amp;</span><br><span class="line"> urlObj.<span class="property">pathname</span>.<span class="title function_">startsWith</span>(<span class="string">&#x27;/videoplayback&#x27;</span>)</span><br><span class="line"> )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">URL</span>&#125; urlObj </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">number</span>&#125; newLen </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">Response</span>&#125; res </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">parseYtVideoRedir</span>(<span class="params">urlObj, newLen, res</span>) &#123;</span><br><span class="line"> <span class="keyword">if</span> (newLen &gt; <span class="number">2000</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!<span class="title function_">isYtUrl</span>(urlObj)) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="keyword">const</span> data = <span class="keyword">await</span> res.<span class="title function_">text</span>()</span><br><span class="line"> urlObj = <span class="keyword">new</span> <span class="title function_">URL</span>(data)</span><br><span class="line"> &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!<span class="title function_">isYtUrl</span>(urlObj)) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> urlObj</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>3. 点击 [保存并部署]。</p> <h4 id="第三步-2"><a class="anchor" href="#第三步-2">#</a> 第三步</h4> <p>回到 [概述],点击你刚才创建的项目,点击 [触发器],点击 [添加自定义域],填入一个你账户中的域名或其子域名,点击 [添加自定义域],完成搭建。</p> <h2 id="方法三使用deno-playground搭建"><a class="anchor" href="#方法三使用deno-playground搭建">#</a> 方法三:使用 Deno Playground 搭建</h2> <h3 id="优点-3"><a class="anchor" href="#优点-3">#</a> 优点:</h3> <ol> <li>配置十分简单,加速范围广</li> <li>无需备案,加速效果较好 (如图)<br /> 加速前:<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_ee2ba28d08999e625e9e68716f43db68.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_ee2ba28d08999e625e9e68716f43db68.png" /><br /> 加速后:<br /> <img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_dc2d54ac2088cec188556bc6e5582c9a.png" alt="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_dc2d54ac2088cec188556bc6e5582c9a.png" title="加速后" /></li> <li>免费额度多,每月 1000000 次请求,100G 流量</li> <li>只要 DNS 解析就行,不用像 Cloudflare 一样需要修改域名 NS</li> </ol> <h3 id="缺点-3"><a class="anchor" href="#缺点-3">#</a> 缺点:</h3> <ol> <li>部分地区访问较慢</li> <li>没有攻击防护和其他安全功能,存在被攻击或刷流量的风险</li> <li>官方自带的域名被墙,需要自备域名</li> </ol> <h3 id="推荐指数-3"><a class="anchor" href="#推荐指数-3">#</a> 推荐指数:⭐⭐⭐⭐⭐</h3> <h3 id="搭建方法-3"><a class="anchor" href="#搭建方法-3">#</a> 搭建方法</h3> <h4 id="第一步-3"><a class="anchor" href="#第一步-3">#</a> 第一步</h4> <ol> <li> <p>登录后,在主页右上角点击 [New Playground]</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_df83a1d70d519c100210e71c5aec864d.png" alt="" /></p> </li> <li> <p>进入代码编辑页面:</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_6b286fe6d87f51dc041d9bf86b27acd7.png" alt="" /><br /> 如果你没有进入此页面,也可以在主页找到你创建的项目,点击 [Playground] 进入编辑</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_d8d0b8aecb44e3d7631f209870cf5a88.png" alt="" /></p> </li> </ol> <h4 id="第二步-3"><a class="anchor" href="#第二步-3">#</a> 第二步</h4> <p>将以下代码直接粘贴进代码框:</p> <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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="variable constant_">HOST</span> = <span class="string">&quot;fastly.jsdelivr.net&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="title class_">Deno</span>.<span class="title function_">serve</span>(<span class="title function_">async</span> (request) =&gt; &#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> url = <span class="keyword">new</span> <span class="title function_">URL</span>(request.<span class="property">url</span>);</span><br><span class="line"></span><br><span class="line">url.<span class="property">host</span> = <span class="variable constant_">HOST</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> newRequest = <span class="keyword">new</span> <span class="title class_">Request</span>(url.<span class="title function_">toString</span>(), &#123;</span><br><span class="line"></span><br><span class="line"><span class="attr">headers</span>: request.<span class="property">headers</span>,</span><br><span class="line"></span><br><span class="line"><span class="attr">method</span>: request.<span class="property">method</span>,</span><br><span class="line"></span><br><span class="line"><span class="attr">body</span>: request.<span class="property">body</span>,</span><br><span class="line"></span><br><span class="line"><span class="attr">redirect</span>: <span class="string">&quot;follow&quot;</span>,</span><br><span class="line"></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">await</span> <span class="title function_">fetch</span>(newRequest);</span><br><span class="line"></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p> <p>3. 点击 [Save &amp; Deploy]。</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_413cb7fc502499db25d9dcdbbfc72fc8.png" alt="" /></p> <h4 id="第三步-3"><a class="anchor" href="#第三步-3">#</a> 第三步</h4> <p>回到你的项目管理页面,点击 [Settings],点击 [Domains],再点击 [Add Domain],填入一个你的域名或其子域名,点击 [Setup], 按照指示完成 DNS 解析后,点击 [Validate], 并点击自动配置证书,完成搭建。(下方有示例图)</p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_ebbd1ba342ad1fff1c83ec3404755559.png" alt="" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_d9c4095ac6c21865fc773e2bcca5e5f6.png" alt="" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_9fda6e5f7ae41060e59b3cc092bc552d.png" alt="" /></p> <p><img data-src="https://upcdn.jdjwzx233.cn/upload/Qexo/25/5/4/image_80297be1451d4fb7c0e47e581267e4f0.png" alt="" /></p> <h2 id="方法四使用nginx"><a class="anchor" href="#方法四使用nginx">#</a> 方法四:使用 nginx</h2> <h3 id="优点简单"><a class="anchor" href="#优点简单">#</a> 优点:简单</h3> <h3 id="缺点-4"><a class="anchor" href="#缺点-4">#</a> 缺点:</h3> <p>加速范围不广,速度受到服务器性能和速度限制。</p> <h3 id="推荐指数-4"><a class="anchor" href="#推荐指数-4">#</a> 推荐指数:⭐⭐⭐</h3> <p>新建一个网站,然后把下面内容覆盖到 nginx 配置文件</p> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line"></span><br><span class="line"> listen 80;</span><br><span class="line"></span><br><span class="line"> listen 443 ssl http2;</span><br><span class="line"></span><br><span class="line"> # 请更改为你的证书路径</span><br><span class="line"> ssl_certificate fullchain.pem;</span><br><span class="line"> ssl_certificate_key privkey.pem;</span><br><span class="line"></span><br><span class="line"> # 请更改为你的镜像域名</span><br><span class="line"> server_name jsd.ucbk.cn;</span><br><span class="line"></span><br><span class="line"> location / &#123;</span><br><span class="line"> proxy_pass https://cdn.jsdelivr.net;</span><br><span class="line"> proxy_set_header Host $proxy_host;</span><br><span class="line"> proxy_set_header Accept-Encoding &#x27;&#x27;;</span><br><span class="line"> proxy_ssl_server_name on;</span><br><span class="line"> proxy_ssl_name $proxy_host;</span><br><span class="line"> proxy_redirect / /;</span><br><span class="line"> # Proxy Cache</span><br><span class="line"> proxy_cache jsdelivr;</span><br><span class="line"> proxy_cache_lock on;</span><br><span class="line"> proxy_cache_lock_timeout 15s;</span><br><span class="line"> proxy_cache_use_stale updating;</span><br><span class="line"> proxy_cache_background_update on;</span><br><span class="line"> proxy_cache_key $host$request_uri;</span><br><span class="line"> proxy_cache_valid 200 301 302 30d;</span><br><span class="line"> proxy_cache_valid 500 501 502 503 15s;</span><br><span class="line"> proxy_cache_valid any 5m;</span><br><span class="line"> # Replace Domain</span><br><span class="line"> sub_filter_once off;</span><br><span class="line"> sub_filter_types application/javascript application/json text/xml text/css;</span><br><span class="line"> sub_filter &#x27;$proxy_host&#x27; &#x27;$host&#x27;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"># 缓存路径请根据需要更改</span><br><span class="line">proxy_cache_path /var/tmp/nginx/jsdelivr levels=1:2 use_temp_path=off keys_zone=jsdelivr:300m inactive=30d max_size=30g;</span><br></pre></td></tr></table></figure></p> <p>之后直接把网站涉及到 <code>cdn.jsdelivr.net</code> 都改成你自己的就可以了,如果不想改的话直接在你网站 nginx 配置中加以下内容就可以了</p> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sub_filter_once off;</span><br><span class="line">sub_filter_types application/javascript application/json text/xml text/css;</span><br><span class="line">sub_filter &#x27;cdn.jsdelivr.net&#x27; &#x27;jsd.ucbk.cn&#x27;;</span><br></pre></td></tr></table></figure></p> <h2 id="结尾"><a class="anchor" href="#结尾">#</a> 结尾</h2> <p>除了上述的服务之外,还有其他同样优秀的云服务商可以用于搭建镜像,如腾讯云、阿里云等等,但都存在一个致命的问题:需要备案。希望本文提供的方法可以帮到你,你同样也可以将这个方法用在其他网站的镜像上 (只需要修改一下代码就行)</p> <p>博主已经搭建了一个镜像站:</p> <p><span class="exturl" data-url="aHR0cHM6Ly9teXN0aWNnbG93LmRwZG5zLm9yZw==">mysticglow.dpdns.org</span></p> <p>这个镜像站目前还没被墙,如有需要的,可以拿去使用,这个镜像站每个月只有 100 万次请求数和 100G 的流量,如果可以的话请自行搭建,不会或懒得搭建的可以使用本站的 (๑・ᴗ・๑)♡</p> <p>非常感谢你能看到这里,如有什么问题欢迎在评论区中提出!<br /> 如果你觉得我的博客不错的话,可以赞助我 (・̀ ω・́)✧:</p> <p><a href="https://jdjwzx233.cn/support" title="赞助我吧,要饿死了QWQ">https://jdjwzx233.cn/support</a>。</p>

2023/12/23
阅读更多

Edge在保留数据的情况下退出微软账户登录

<p>现在,越来越多的人使用 Edge 浏览器来进行网络浏览,但有时候您可能需要退出微软账户登录。问题是,当您退出时,您是否会失去本地存储设备上的数据?本文将解答您的疑惑,告诉您如何在退出微软账户前保留本地数据。</p> <h2 id="正文"><a class="anchor" href="#正文">#</a> 正文</h2> <p>当我们无法登录账户时,如果要在 Edge 中退出微软账户登录,可能需要进入该账户的主页才能退出,否则只能使用删除该用户配置才可退出,但这会导致数据丢失,并使一些平台需要重新登录,非常的不方便。</p> <p>但是,我们可以使用一些其他的方法保留数据退出登录。</p> <p>在 Windows 的资源管理器中,找到你的用户数据文件夹 (正常情况都在这里)。</p> <p><code>C:\Users\用户名\AppData\Local\Microsoft\Edge\User Data</code></p> <p>一般来说,你的数据都存储在 Default 文件夹中,如图:</p> <p><img data-src="https://images.jdjwzx233.cn/upload/Qexo/2023/6/26/image_901d395526eefaf6e30a26fdc9a90d16.png" alt="https://images.jdjwzx233.cn/upload/Qexo/2023/6/26/image_901d395526eefaf6e30a26fdc9a90d16.png" /></p> <p>但是有时候你使用了其他用户配置,那么你的数据可能在 <code>Profile+数字</code> 文件夹中,这个要根据你的实际情况进行选择。</p> <div class="note danger"> <p>注意!以下操作可能会导致数据丢失,请提前备份好相关数据,再进行操作!</p> </div> <p>当你找到自己的数据文件夹后,你需要关闭 Edge 浏览器,注意!要到 <code>任务管理器</code> 中关闭,直接关闭是无效的。</p> <p>关闭后,你需要备份这个文件夹,完成后,你就可以开始进行退出登录的操作了。</p> <p>在你的文件夹中,找到这几个文件,如图:</p> <p><img data-src="https://images.jdjwzx233.cn/upload/Qexo/2023/6/25/image_4a0ce70e5fa19687d509e4752fdb97af.png" alt="https://image.jdjwzx233.cn/upload/Qexo/2023/6/25/image_4a0ce70e5fa19687d509e4752fdb97af.png" /></p> <div class="note warning"> <p>以下操作可能会使你保存的密码全部丢失,请提前到设置中导出密码,再进行本操作,导入导出密码的教程放在文章结尾。</p> </div> <p>然后删除 <code>Preferences</code> , <code>Login Data-journal</code> , <code>Login Data</code> 这三个文件。回到浏览器后,你会发现,你的数据还在,但你的账户被退出了。</p> <p>在登录你的微软账号后,你就可以导入原来的密码,完成这步后,那么恭喜你,你已经成功完成了退出微软账户保留本地数据的操作!</p> <h2 id="转移数据"><a class="anchor" href="#转移数据">#</a> 转移数据</h2> <p>本方法同样适用于转移数据,你只需要将需要转移的用户文件夹中的内容,复制替换掉新的用户文件夹中的内容即可,在此操作之前,你需要备份被替换的用户文件夹中 <code>Preferences</code> , <code>Login Data-journal</code> , <code>Login Data</code> 这三个文件,在完成数据转移后,再移动回来,这样,你就完成了数据转移。</p> <h3 id="导出或导入密码"><a class="anchor" href="#导出或导入密码">#</a> 导出或导入密码</h3> <p>首先,打开 <code>Edge://settings/passwords</code> 或者你可以打开 <code>设置</code> -&gt; <code>个人资料</code> -&gt; <code>密码</code> 。</p> <p>然后,在这个地方点击右边的三个点,如图:</p> <p><img data-src="https://images.jdjwzx233.cn/upload/Qexo/2023/6/26/image_1c76ad526b021903d93f8f1a5a944e60.png" alt="https://images.jdjwzx233.cn/upload/Qexo/2023/6/26/image_1c76ad526b021903d93f8f1a5a944e60.png" /></p> <p>选择 <code>导出密码</code> ,在进行这一步时,你可能需要验证你的身份,按照步骤来就行。</p> <p>最后,将你的密码保存到一个安全的地方,后面导入密码时,同样也是在此地方进行。<br /> 如果你觉得我的博客不错的话,可以赞助我 (・̀ ω・́)✧:<a href="https://jdjwzx233.cn/support">https://jdjwzx233.cn/support</a>。</p>

2023/6/25
阅读更多

优秀作文分享——人间烟雨,感谢有你

<p>烟雨迷蒙,如同人生。回首往事,最难忘却的莫过于与你相遇时的情景了吧!—— 题记</p> <p>烟雨中的你是否还记得那一抹清丽的身影?这个女孩子很特别,她不像其他小姑娘一样喜欢花裙子和洋娃娃,而更爱穿着布鞋踏遍青石板路上的每一处角落。</p> <p>只因为从前年幼无知的我们都曾经问过彼此:“妈妈说下雨天地面湿滑会摔跤,可以光脚走吗?” 看到大家齐刷刷摇头后便兴高采烈地脱掉了凉鞋,赤足跑进水坑或泥泞里玩耍去了…… 渐渐长大后才明白当初母亲微笑背后的苦涩心酸,也终于理解了你对我们所谓 “放养式教育” 的坚持。</p> <p>多么希望能够再次见到你啊!但愿岁月静好,现世安稳。 在我眼里,你就是仙女姐姐般美好纯洁的存在,你总是用温柔细腻的手抚摸着我们受伤的心灵,告诉我们要勇敢、乐观地活出精彩。</p> <p>即使偶尔发脾气,嘴巴也依旧甜甜软软的。我想你应该永远是那副没什么烦恼的模样吧,虽然我们之间隔着千山万水,但我始终觉得你离我并不遥远。尽管我们素未谋面,甚至连声音都听不真切,但仿佛冥冥之中早已注定,我们将会成为最熟悉的陌生人。</p> <p>直到今日我仍深信缘分二字,命运让我们相识又让我们重逢,这种感觉实在太奇妙了。</p> <p>“有朋自远方来,不亦乐乎”。古人诚不欺我,每当收到你寄来的贺卡,打开它时内心的欣喜溢于言表;翻阅它时脑海中浮现的画面似电影般闪过;合起它时鼻尖萦绕的香味久久挥散不去… 待我读懂了你的文字,品尝了你送给我的巧克力糖果,体验了你讲述的动人故事,享受了你赠予我的珍贵礼物,聆听了你传授的宝贵经验,我恍然顿悟原来我们的相遇竟是命中注定。如若不是在茫茫人海中邂逅,怎会碰撞出绚烂火花?倘若不是被你治愈了伤痛,怎会触及到柔软的内心?谢谢你,带给我的点滴暖意;谢谢你,陪伴我度过的漫长旅程;谢谢你,让我学会了坦然释怀;谢谢你,令我变得越来越优秀。</p> <p>烟雨朦胧,梦境斑驳,轻捻指尖,满目芬芳。烟雨中的你,是否还记得我呢?我期盼着,下一场烟雨,我们能再次相约。</p>

2023/1/28
阅读更多

优秀作文分享——从未走远

<p>我们从未走远,只是你没发现而已。—— 题记</p> <p>一个人的心中有多少秘密?谁也无法知道,就像这世界上永远都会存在着许多令人费解之谜一样,它总是让那些充满智慧与灵感的人去猜测、探索和研究。但他们却始终得不到真正的答案。或许,每当夜深人静时,思绪便开始飞扬了吧!</p> <p>于是,所谓的诗情画意,便油然而生;所谓的浪漫气息,亦由此而来…… 于是乎,古往今来,凡大家名流,皆如痴似醉地沉浸其间。对于爱情,更是乐此不疲,因为美丽的故事总能打动人心,给予读者以无限遐想空间。 “最好不相见,免得我牵念”,唐朝才子元稹写下了千古绝唱《离思》。王维用笔墨将红豆寄托出相思之苦,李商隐则借芭蕉抒怀别恨。屈原哀叹自己遭谗被疏,伍子胥含泪鞭尸,苏轼愁断肝肠,陆游悲痛欲绝。</p> <p>明月照亮了黑暗,星光点缀了寂寞,文字带来了希望,纸张承载了梦想。文学作品里蕴藏着太多的内涵,需要细细揣摩,慢慢体味。<br /> 尽管岁月悠长,风尘渐起,惟愿历史的车轮碾过后,还留下几颗闪烁的珍珠供后人欣赏玩味。蓦然回首,青春年华早已逝去,伴随成长的足迹踏遍万水千山。可惜韶华易老,昔日容颜不再。 曾经沧海难为水,除却巫山不是云。纵使身处闹市,又怎敌得过高山流水遇知音的旷达胸襟呢?</p> <p>虽说花开堪折直须折,莫待无花空折枝。然而人非草木孰能无情?面对眼前的诱惑,恐怕很难把持住自己,甚至迷失方向。尤其是看惯了灯红酒绿的繁华景象,听够了莺歌燕舞的靡靡之音,享受惯了富贵荣华的锦衣玉食,接触多了形形色色的社会百态,岂能不贪恋权势金钱?试问:哪位君主甘愿做平民百姓?即使退一步讲,倘若抛弃了功名利禄,选择归隐田园,那么就必定淡泊名利吗?显然并非如此。</p> <p>陶渊明辞官归隐,采菊东篱下,悠然见南山,依旧钟情于 “结庐在人境,而无车马喧” 的闲适恬淡。周敦颐厌恶官场,宁愿隐居西湖孤山,仍保持清白廉洁的节操。欧阳修贬谪滁州,饱尝艰辛困顿,仍坚守信念,矢志不渝,毫不改变初衷。… 数不胜数,比比皆是。</p>

2023/1/28
阅读更多

优秀作文分享——我,在浙里

<h2 id="第一篇"><a class="anchor" href="#第一篇">#</a> 第一篇:</h2> <p>浙江,是一片神奇美丽的土地;浙江,孕育了中华民族灿烂悠久的文明;浙江,承载着数以亿计的浙商走向世界!</p> <p>“三十功名尘与土,八千里路云和月”。一首《满江红》道出了岳飞壮志难酬、报国无门的悲愤心情。但他没有被挫折所压倒,反而更加坚定自己的信念 —— 收复失地,还于旧都。在历史上留下了浓墨重彩的一笔。</p> <p>“位卑未敢忘忧国”。身为汉臣却始终忠心耿耿,宁死也要捍卫祖国领土完整。我想到了周恩来总理。他曾说过:“为中华崛起而读书!” 就是凭借这种强烈的爱国精神,才使得那么多仁人志士投入革命洪流,推翻黑暗统治,建立新中国!</p> <p>“先天下之忧而忧,后天下之乐而乐”。范仲淹从小便怀抱远大理想,立志成为像孔子一般博学多识、胸怀天下苍生的圣贤。正因此,他能够舍弃高官厚禄,毅然决然地辞职回乡,开启了著名的 “庆历新政”。虽然最终因保守势力太强而失败,但其忧国忧民的思想却永垂青史。</p> <p>“居庙堂之高则忧其君,处江湖之远则忧其民”。范仲淹两度遭贬,依然关注百姓疾苦,体恤黎民百姓。在他看来,只有让老百姓安居乐业,社会才能稳定发展。</p> <p>古人云:“读万卷书不如行千里路。” 不错,纸上谈兵并非真英雄。真正的勇者应当深入实践,躬亲实干。“宝剑锋从磨砺出,梅花香自苦寒来”。鲁迅先生把握住了知识分子的特点,用手中的笔作武器,唤醒麻木的国民。他写杂文,抨击封建制度的弊端,揭露军阀混战的罪恶;他写小说,描绘人民群众受压迫、受剥削的惨状,表现对劳动人民的同情和热爱。鲁迅先生用自己犀利的笔尖戳破假面具,撕去画皮,将丑陋的灵魂暴露给世人。他的每篇杂文犹如匕首,刺痛敌人的心脏。鲁迅先生毫不畏惧,奋斗一生,为后人树立了榜样。</p> <p>我们生活在这样一个伟大的时代,感谢科技进步带来的方便快捷。我们拥有丰富的物质财富,可以享受电影院、健身房等娱乐设施。但是,别忘记,今日的幸福生活离不开前辈们披荆斩棘的努力拼搏。我相信,在党的领导下,我们必将创造属于我们的辉煌!</p> <h2 id="第二篇"><a class="anchor" href="#第二篇">#</a> 第二篇:</h2> <p>浙里,我在这里。我来自浙南的温州,因为那儿有最美丽的海滨城市 —— 厦门;也许你会问:“怎么没有听说过‘东方夏威夷’呢?” 不错,它就是福建省第二大岛 —— 平潭县。而我们今天要去游览的则是被称之为 “小上海” 的浙江省会 --- 杭州。</p> <p>浙江是一个人杰地灵的好地方,孕育了无数名扬四海的文化巨匠和商业奇才,还造就了灿若星辰的艺术瑰宝!古代中国有四大发明,其中三项便产生于此,可见她对世界所做出的贡献之伟大啊!</p> <p>如果说北京是帝王将相聚集的地方,那么杭州绝对是富家子弟云集的场所。想当年,乾隆皇帝下江南时曾到过此处,并留下了千古佳句:“江南忆,最忆是杭州”。由此可以看出,杭州是多么令人向往与憧憬呀! “日出江花红胜火,春来江水绿如蓝”,从诗中描绘的情境可知,春季的杭州正值桃李芬芳,鸟语花香的好时节。但作者却只用了两句话概括了整个杭州的特点,让读者更加感受到了杭州的魅力与神韵。或许,每个人都有属于他(她)心目中的杭州吧!</p> <p>杭州西湖景色秀丽、山清水秀,素有 “人间天堂” 的美誉。尤其是湖中央的三座小岛 - - 小瀛洲、湖心亭和阮公墩,各具风姿。</p> <p>小瀛洲面积较大,岛上遍植花木,环境幽静。湖心亭是西湖中赏荷观鱼的最佳处,岛上建筑精巧别致,有水中仙子的雅号。阮公墩虽然面积比前两个小岛略小些,但却十分别致,登高远眺,西湖全景尽收眼底…… 傍晚,夕阳斜照在西湖上,映着波光粼粼的湖面,闪烁着金光,仿佛给湖面铺上了一层碎金似的,煞是耀眼夺目。微风吹拂着柳树,使它轻轻摇摆起来,像是姑娘们甩动长发跳舞一般,婀娜多姿,楚楚动人。夜幕降临后,月亮升空,皎洁的月光倾泻而下,洒落在湖面上,泛起阵阵银白色的涟漪,宛如仙女散花,又犹如牛郎织女隔河相望,真是妙趣横生!倘若遇到皓月当空,繁星满天的夜晚,坐在船头仰望苍穹,定能领悟到苏轼《水调歌头》中所写道的 “欲把西湖比西子,淡妆浓抹总相宜” 的意蕴吧!</p>

2023/1/26
阅读更多

将ChatGPT部署到网站上

<p>ChatGPT 是一个用于自然语言对话的预训练语言模型。要将 ChatGPT 部署到网站上,你需要执行以下步骤:</p> <ol> <li>下载 ChatGPT 模型:你可以从 Hugging Face 的 Transformers 库中下载 ChatGPT 模型。</li> <li>使用 Python 的 Flask 库创建一个 Web 应用程序。Flask 是一种轻量级的 Web 应用框架,可以让你快速构建 Web 应用程序。</li> <li>在 Web 应用中加载 ChatGPT 模型:在 Web 应用程序中,你可以使用 Transformers 库中的 <code>AutoModelWithLMHead</code> 类加载 ChatGPT 模型。</li> <li>创建一个 HTML 表单,允许用户输入对话文本。</li> <li>使用 ChatGPT 模型对用户输入的文本进行响应:当用户提交表单时,你可以使用 ChatGPT 模型的 <code>generate</code> 方法生成响应文本。</li> </ol> <p>以下是一个简单的例子,展示了如何使用 Flask 和 ChatGPT 构建一个简单的 Web 应用程序:</p> <p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask, render_template, request</span><br><span class="line"><span class="keyword">from</span> transformers <span class="keyword">import</span> AutoModelWithLMHead, AutoTokenizer</span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加载ChatGPT模型</span></span><br><span class="line">model = AutoModelWithLMHead.from_pretrained(<span class="string">&quot;microsoft/DialoGPT-small&quot;</span>)</span><br><span class="line">tokenizer = AutoTokenizer.from_pretrained(<span class="string">&quot;microsoft/DialoGPT-small&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">&quot;/&quot;</span>, methods=[<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;POST&quot;</span>]</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">index</span>():</span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">&quot;POST&quot;</span>:</span><br><span class="line"> <span class="comment"># 获取用户输入的文本</span></span><br><span class="line"> input_text = request.form[<span class="string">&quot;input_text&quot;</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 使用ChatGPT模型生成响应文本</span></span><br><span class="line"> prompt = (input_text, <span class="string">&quot;&quot;</span>)</span><br><span class="line"> response = model.generate(prompt, max_length=<span class="number">1024</span>, do_sample=<span class="literal">True</span>, temperature=<span class="number">0.7</span>)</span><br><span class="line"> response_text = tokenizer.decode(response[<span class="number">0</span>], skip_special_tokens=<span class="literal">True</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">&quot;index.html&quot;</span>, response_text=response_text)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">&quot;index.html&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line"> app.run()</span><br></pre></td></tr></table></figure></p> <p>在这段代码中,我们使用了 Flask 的 <code>render_template</code> 函数来渲染一个 HTML 模板,并将响应文本传递给模板。我们还使用了 Transformers 库中的 <code>AutoTokenizer</code> 类来将响应文本解码为可读的文本。</p> <p>下面是一个简单的 HTML 模板,你可以使用它来显示用户输入和 ChatGPT 响应:</p> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">title</span>&gt;</span>ChatGPT Demo<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">form</span> <span class="attr">method</span>=<span class="string">&quot;POST&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">label</span>&gt;</span>输入文本:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;input_text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;输入文本&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span>&gt;</span>发送<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"> &#123;% if response_text %&#125;</span><br><span class="line"> <span class="tag">&lt;<span class="name">p</span>&gt;</span>响应文本:&#123;&#123; response_text &#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"> &#123;% endif %&#125;</span><br><span class="line"> <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></p> <p>在这个 HTML 模板中,我们创建了一个表单,允许用户输入对话文本。当用户提交表单时,Web 应用程序会使用 ChatGPT 模型生成响应文本,并使用 Flask 的 <code>render_template</code> 函数将响应文本传递给 HTML 模板。</p> <p>要运行这个 Web 应用程序,你需要安装 Flask 和 Transformers 库,然后运行代码:</p> <p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pip install flask transformers</span><br><span class="line">python app.py</span><br></pre></td></tr></table></figure></p> <p>然后,你就可以在浏览器中访问<span class="exturl" data-url="aHR0cDovL2xvY2FsaG9zdDo1MDAwLw=="> http://localhost:5000/</span> 来使用这个 Web 应用程序了。</p> <p>要在上述代码的基础上创建一个更美观的界面,你可以使用 HTML、CSS 和 JavaScript 来设计界面,并使用 AJAX 技术在用户输入文本后异步获取 ChatGPT 响应。</p> <p>下面是一个示例代码,展示了如何使用这些技术创建一个类似聊天系统的界面:</p> <p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">title</span>&gt;</span>ChatGPT Demo<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"> <span class="comment">&lt;!-- 引入Bootstrap框架 --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">&quot;stylesheet&quot;</span> <span class="attr">href</span>=<span class="string">&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css&quot;</span> <span class="attr">integrity</span>=<span class="string">&quot;sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk&quot;</span> <span class="attr">crossorigin</span>=<span class="string">&quot;anonymous&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"> <span class="comment">&lt;!-- 创建聊天窗口 --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;container mt-5&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card-header&quot;</span>&gt;</span></span><br><span class="line"> 聊天窗口</span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card-body p-0&quot;</span> <span class="attr">id</span>=<span class="string">&quot;messages&quot;</span>&gt;</span></span><br><span class="line"> <span class="comment">&lt;!-- 显示聊天记录 --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;row mb-2&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;col-md-2&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;col-md-10 text-right&quot;</span>&gt;</span></span><br><span class="line"> 你好,我是ChatGPT,有什么想聊的?</span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="comment">&lt;!-- 创建输入框 --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;card-footer&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">form</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;form-group&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">class</span>=<span class="string">&quot;form-control&quot;</span> <span class="attr">id</span>=<span class="string">&quot;input_text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;输入文本&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span> <span class="attr">class</span>=<span class="string">&quot;btn btn-primary&quot;</span> <span class="attr">id</span>=<span class="string">&quot;send_button&quot;</span>&gt;</span>发送<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">&lt;!-- 引入jQuery库 --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://code.jquery.com/jquery-3.5.1.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"> <span class="comment">&lt;!-- 设置AJAX请求 --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> $(<span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> $(<span class="string">&quot;form&quot;</span>).<span class="title function_">submit</span>(<span class="keyword">function</span>(<span class="params">event</span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> event.<span class="title function_">preventDefault</span>();</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 获取用户输入的文本</span></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">var</span> input_text = $(<span class="string">&quot;#input_text&quot;</span>).<span class="title function_">val</span>();</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 将文本添加到聊天记录中</span></span></span><br><span class="line"><span class="language-javascript"> $(<span class="string">&quot;#messages&quot;</span>).<span class="title function_">append</span>(</span></span><br><span class="line"><span class="language-javascript"> <span class="string">&#x27;&lt;div class=&quot;row mb-2&quot;&gt;&lt;div class=&quot;col-md-2&quot;&gt;&lt;/div&gt;&lt;div class=&quot;col-md-10&quot;&gt;&#x27;</span> + input_text + <span class="string">&#x27;&lt;/div&gt;&lt;/div&gt;&#x27;</span></span></span><br><span class="line"><span class="language-javascript"> );</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 发送AJAX请求</span></span></span><br><span class="line"><span class="language-javascript"> $.<span class="title function_">ajax</span>(&#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">type</span>: <span class="string">&quot;POST&quot;</span>,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">url</span>: <span class="string">&quot;/chat&quot;</span>,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="string">&quot;input_text&quot;</span>: input_text</span></span><br><span class="line"><span class="language-javascript"> &#125;,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">success</span>: <span class="keyword">function</span>(<span class="params">response</span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="comment">// 将GPT的回复添加到聊天记录中</span></span></span><br><span class="line"><span class="language-javascript"> $(<span class="string">&quot;#messages&quot;</span>).<span class="title function_">append</span>(</span></span><br><span class="line"><span class="language-javascript"> <span class="string">&#x27;&lt;div class=&quot;row mb-2&quot;&gt;&lt;div class=&quot;col-md-10 text-left&quot;&gt;&#x27;</span> + response + <span class="string">&#x27;&lt;/div&gt;&lt;div class=&quot;col-md-2&quot;&gt;&lt;/div&gt;&lt;/div&gt;&#x27;</span></span></span><br><span class="line"><span class="language-javascript"> );</span></span><br><span class="line"><span class="language-javascript"> &#125;</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br><span class="line"></span><br><span class="line"> </span><br><span class="line"></span><br></pre></td></tr></table></figure></p> <p>上面的代码是一个基于 HTML 和 jQuery 的聊天系统模板,使用了 Bootstrap 框架进行布局。</p> <ul> <li> <p>HTML 部分:</p> <ul> <li>页面中包含一个聊天窗口,其中有一个卡片(card),卡片中包含聊天记录(card-body)和输入框(card-footer)。</li> <li>聊天记录中默认显示一条消息:“你好,我是 ChatGPT,有什么想聊的?”</li> <li>输入框中包含一个文本输入框(input)和一个发送按钮(button)。</li> </ul> </li> <li> <p>jQuery 部分:</p> <ul> <li>页面加载完成后,通过 jQuery 监听表单提交事件(submit)。当表单提交时,jQuery 会触发一个回调函数,这个回调函数中的代码会被执行。</li> <li>当用户在输入框中输入文本并点击发送按钮时,表单提交事件(submit)被触发。</li> <li>在表单提交事件的回调函数中,首先使用 <code>event.preventDefault()</code> 阻止默认的表单提交行为。</li> <li>然后使用 <code>$(&quot;#input_text&quot;).val()</code> 获取用户输入的文本。</li> <li>接着使用 <code>$(&quot;#messages&quot;).append()</code> 将文本添加到聊天记录中。</li> <li>最后,使用 jQuery 的 AJAX 功能发送一个 POST 请求到服务器,将用户输入的文本作为请求参数。</li> <li>当服务器返回响应时,将服务器返回的内容添加到聊天记录中。</li> <li>最后,清空文本输入框,准备下一次聊天。</li> </ul> </li> <li> <p>整个流程如下:</p> <ol> <li>用户在文本输入框中输入文本,点击发送按钮。</li> <li>jQuery 监听到表单提交事件,阻止默认的表单提交行为。</li> <li>获取用户输入的文本。</li> <li>将文本添加到聊天记录中。</li> <li>发送 AJAX 请求,将用户输入的文本作为请求参数。</li> <li>服务器返回响应,将响应的内容添加到聊天记录中。</li> <li>清空文本输入框,准备下一次聊天。</li> </ol> <p>这个 HTML 模板只是个简单的框架,具体的逻辑实现还需要你在服务器端进行开发。</p> <p>感谢您阅读这篇文章,希望能帮助到您。在这篇文章中,我们介绍了如何将 ChatGPT 部署到网站上,并使用 jQuery 和 Bootstrap 构建聊天系统的界面。如果您有任何疑问或建议,欢迎在评论区留言。最后,如果这篇文章对您有所帮助,希望能给个打赏鼓励一下作者。<br /> 如果你觉得我的博客不错的话,可以赞助我 (・̀ ω・́)✧:<a href="https://jdjwzx233.cn/support">https://jdjwzx233.cn/support</a>。</p> </li> </ul>

2022/12/24
阅读更多

远程桌面控制器-用c++实现

<p>写一个远程桌面控制器是一个非常复杂的任务,需要熟悉许多网络协议、图像处理技术以及用户界面设计等知识。这里给出的是一个基本的框架,你可以在此基础上进行扩展和完善。</p> <p>首先,我们需要用到一些库来帮助我们实现远程桌面控制器。在这里,我们假设你使用的是 Windows 系统,并使用了以下几个库:</p> <ul> <li>WinSock:用于实现网络通信。</li> <li>GDI+:用于处理图像。</li> <li>MFC:用于创建图形用户界面。</li> </ul> <p>下面是使用这些库编写远程桌面控制器的基本步骤:</p> <ol> <li>创建一个 MFC 应用程序。</li> <li>使用 WinSock 库创建一个网络连接。</li> <li>使用 GDI+ 库获取远程桌面的屏幕截图。</li> <li>将屏幕截图显示在 MFC 窗口中。</li> <li>为用户提供一组控制命令,例如鼠标移动、鼠标单击、键盘输入等。</li> <li>使用 WinSock 库将用户的控制命令发送到远程桌面。</li> </ol> <p>下面是使用这些库编写远程桌面控制器的示例代码:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;winsock2.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;gdiplus.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;afxwin.h&gt;</span> <span class="comment">// 包含 MFC 的头文件</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> Gdiplus;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个 Socket 类,用于封装网络通信相关的操作</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Socket</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> WSADATA m_wsaData;</span><br><span class="line"> SOCKET m_sock;</span><br><span class="line"> sockaddr_in m_serverAddr;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="built_in">Socket</span>() : <span class="built_in">m_sock</span>(INVALID_SOCKET) &#123;&#125;</span><br><span class="line"> <span class="comment">// 初始化 WinSock 库</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Init</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">WSAStartup</span>(<span class="built_in">MAKEWORD</span>(<span class="number">2</span>, <span class="number">2</span>), &amp;m_wsaData) != <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建套接字</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Create</span><span class="params">(<span class="type">int</span> af, <span class="type">int</span> type, <span class="type">int</span> protocol)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_sock = <span class="built_in">socket</span>(af, type, protocol);</span><br><span class="line"> <span class="keyword">if</span> (m_sock == INVALID_SOCKET)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 连接到服务器</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Connect</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* ip, <span class="type">unsigned</span> <span class="type">short</span> port)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_serverAddr.sin_family = AF_INET;</span><br><span class="line"> m_serverAddr.sin_port = <span class="built_in">htons</span>(port);</span><br><span class="line"> m_serverAddr.sin_addr.S_un.S_addr = <span class="built_in">inet_addr</span>(ip);</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">connect</span>(m_sock, (sockaddr*)&amp;m_serverAddr, <span class="built_in">sizeof</span>(m_serverAddr)) == SOCKET_ERROR)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送数据</span></span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">Send</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* buf, <span class="type">int</span> len)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">send</span>(m_sock, buf, len, <span class="number">0</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 接收数据</span></span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">Receive</span><span class="params">(<span class="type">char</span>* buf, <span class="type">int</span> len)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">recv</span>(m_sock, buf, len, <span class="number">0</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 关闭套接字</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Close</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="built_in">closesocket</span>(m_sock);</span><br><span class="line"> m_sock = INVALID_SOCKET;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 清理 WinSock 库</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Cleanup</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="built_in">WSACleanup</span>();</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个 RemoteDesktop 类,用于控制远程桌面</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RemoteDesktop</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> Socket m_socket; <span class="comment">// 用于网络通信的套接字</span></span><br><span class="line"> Image* m_image; <span class="comment">// 当前屏幕截图</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="built_in">RemoteDesktop</span>() : <span class="built_in">m_image</span>(<span class="literal">NULL</span>) &#123;&#125;</span><br><span class="line"> <span class="comment">// 连接到远续桌面服务器</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Connect</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* ip, <span class="type">unsigned</span> <span class="type">short</span> port)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Init</span>())</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Create</span>(AF_INET, SOCK_STREAM, IPPROTO_TCP))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Connect</span>(ip, port))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 断开与远程桌面服务器的连接</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Disconnect</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_socket.<span class="built_in">Close</span>();</span><br><span class="line"> m_socket.<span class="built_in">Cleanup</span>();</span><br><span class="line"> <span class="keyword">delete</span> m_image;</span><br><span class="line"> m_image = <span class="literal">NULL</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 获取远程桌面的屏幕截图</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">GetScreenshot</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 先发送获取屏幕截图的命令</span></span><br><span class="line"> <span class="type">const</span> <span class="type">char</span>* cmd = <span class="string">&quot;screenshot&quot;</span>;</span><br><span class="line"> m_socket.<span class="built_in">Send</span>(cmd, <span class="built_in">strlen</span>(cmd));</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 接收屏幕截图的大小</span></span><br><span class="line"> <span class="type">int</span> size;</span><br><span class="line"> m_socket.<span class="built_in">Receive</span>((<span class="type">char</span>*)&amp;size, <span class="built_in">sizeof</span>(size));</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 分配内存空间,准备接收屏幕截图的数据</span></span><br><span class="line"> <span class="type">char</span>* data = <span class="keyword">new</span> <span class="type">char</span>[size];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 接收屏幕截图的数据</span></span><br><span class="line"> <span class="type">int</span> bytesReceived = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (bytesReceived &lt; size)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="type">int</span> count = m_socket.<span class="built_in">Receive</span>(data + bytesReceived, size - bytesReceived);</span><br><span class="line"> <span class="keyword">if</span> (count &lt;= <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">delete</span>[] data;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> bytesReceived += count;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将接收到的数据转换为 GDI+ 图像</span></span><br><span class="line"> <span class="keyword">delete</span> m_image;</span><br><span class="line"> m_image = <span class="keyword">new</span> <span class="built_in">Image</span>(data, size);</span><br><span class="line"> <span class="keyword">delete</span>[] data;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 获取当前屏幕截图</span></span><br><span class="line"> <span class="function">Image* <span class="title">GetImage</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> m_image;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送鼠标移动命令</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">MoveMouse</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 封装命令格式,发送命令</span></span><br><span class="line"> <span class="type">const</span> <span class="type">char</span>* cmd = <span class="string">&quot;mouse move&quot;</span>;</span><br><span class="line"> m_socket.<span class="built_in">Send</span>(cmd, <span class="built_in">strlen</span>(cmd));</span><br><span class="line"> m_socket.<span class="built_in">Send</span>((<span class="type">char</span>*)&amp;x, <span class="built_in">sizeof</span>(x));</span><br><span class="line"> m_socket.<span class="built_in">Send</span>((<span class="type">char</span>*)&amp;y, <span class="built_in">sizeof</span>(y));</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送鼠标单击命令</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">ClickMouse</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 封装命令格式,发送命令</span></span><br><span class="line"> <span class="type">const</span> <span class="type">char</span>* cmd = <span class="string">&quot;mouse click&quot;</span>;</span><br><span class="line"> m_socket.<span class="built_in">Send</span>(cmd, <span class="built_in">strlen</span>(cmd));</span><br><span class="line"> m_socket.<span class="built_in">Send</span>((<span class="type">char</span>*)&amp;x, <span class="built_in">sizeof</span>(x));</span><br><span class="line"> m_socket.<span class="built_in">Send</span>((<span class="type">char</span>*)&amp;y, <span class="built_in">sizeof</span>(y));</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送键盘输入命令</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">InputKey</span><span class="params">(<span class="type">int</span> keyCode)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 封装命令格式,发送命令</span></span><br><span class="line"> <span class="type">const</span> <span class="type">char</span>* cmd = <span class="string">&quot;key input&quot;</span>;</span><br><span class="line"> m_socket.<span class="built_in">Send</span>(cmd, <span class="built_in">strlen</span>(cmd));</span><br><span class="line"> m_socket.<span class="built_in">Send</span>((<span class="type">char</span>*)&amp;keyCode, <span class="built_in">sizeof</span>(keyCode));</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个 RemoteDesktopDialog 类,用于显示远程桌面的界面</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RemoteDesktopDialog</span> : <span class="keyword">public</span> CDialog</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> RemoteDesktop m_rd; <span class="comment">// 用于控制远程桌面的对象</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="comment">// 使用 MFC 对话框的基本操作</span></span><br><span class="line"> <span class="built_in">RemoteDesktopDialog</span>() : <span class="built_in">CDialog</span>(IDD_DIALOG1) &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line"> <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">DoDataExchange</span><span class="params">(CDataExchange* pDX)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> CDialog::<span class="built_in">DoDataExchange</span>(pDX);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="comment">// 连接到远程桌面服务器</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Connect</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* ip, <span class="type">unsigned</span> <span class="type">short</span> port)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> m_rd.<span class="built_in">Connect</span>(ip, port);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 断开与远程桌面服务器的连接</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Disconnect</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_rd.<span class="built_in">Disconnect</span>();</span><br><span class="line"> &#125;</span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line"> <span class="comment">// 绘制远程桌面的界面</span></span><br><span class="line"> <span class="function">afx_msg <span class="type">void</span> <span class="title">OnPaint</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="function">CPaintDC <span class="title">dc</span><span class="params">(<span class="keyword">this</span>)</span></span>; <span class="comment">// 用于绘制的设备上下文</span></span><br><span class="line"> CRect rect;</span><br><span class="line"> <span class="built_in">GetClientRect</span>(&amp;rect); <span class="comment">// 获取对话框的客户区域</span></span><br><span class="line"> <span class="comment">// 获取屏幕截图,并绘制到界面上</span></span><br><span class="line"> Image* image = m_rd.<span class="built_in">GetImage</span>();</span><br><span class="line"> <span class="keyword">if</span> (image != <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="function">Graphics <span class="title">graphics</span><span class="params">(dc)</span></span>;</span><br><span class="line"> graphics.<span class="built_in">DrawImage</span>(image, rect);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 处理鼠标移动事件</span></span><br><span class="line"> <span class="function">afx_msg <span class="type">void</span> <span class="title">OnMouseMove</span><span class="params">(UINT nFlags, CPoint point)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_rd.<span class="built_in">MoveMouse</span>(point.x, point.y);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 处理鼠标单击事件</span></span><br><span class="line"> <span class="function">afx_msg <span class="type">void</span> <span class="title">OnLButtonDown</span><span class="params">(UINT nFlags, CPoint point)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_rd.<span class="built_in">ClickMouse</span>(point.x, point.y);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 处理键盘输入事件</span></span><br><span class="line"> <span class="function">afx_msg <span class="type">void</span> <span class="title">OnKeyDown</span><span class="params">(UINT nChar, UINT nRepCnt, UINT nFlags)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_rd.<span class="built_in">InputKey</span>(nChar);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="built_in">DECLARE_MESSAGE_MAP</span>()</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="built_in">BEGIN_MESSAGE_MAP</span>(RemoteDesktopDialog, CDialog)</span><br><span class="line"> <span class="built_in">ON_WM_PAINT</span>()</span><br><span class="line"> <span class="built_in">ON_WM_MOUSEMOVE</span>()</span><br><span class="line"> <span class="built_in">ON_WM_LBUTTONDOWN</span>()</span><br><span class="line"> <span class="built_in">ON_WM_KEYDOWN</span>()</span><br><span class="line"><span class="built_in">END_MESSAGE_MAP</span>()</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="comment">// 初始化 GDI+</span></span><br><span class="line"> GdiplusStartupInput gdiplusStartupInput;</span><br><span class="line"> ULONG_PTR gdiplusToken;</span><br><span class="line"> <span class="built_in">GdiplusStartup</span>(&amp;gdiplusToken, &amp;gdiplusStartupInput, <span class="literal">NULL</span>);</span><br><span class="line"> <span class="comment">// 创建对话框并运行</span></span><br><span class="line"> RemoteDesktopDialog dlg;</span><br><span class="line"> dlg.<span class="built_in">DoModal</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 清理 GDI+</span></span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></p> <p>在这段代码中,我们定义了三个类:Socket、RemoteDesktop 和 RemoteDesktopDialog。Socket 类封装了网络通信的相关操作,RemoteDesktop 类用于控制远程桌面,RemoteDesktopDialog 类用于显示远程桌面的界面。</p> <p>使用这个远程桌面控制器的流程如下:</p> <ol> <li>调用 Socket 类的 Init 函数初始化 WinSock 库。</li> <li>调用 Socket 类的 Create 函数创建一个套接字。</li> <li>调用 Socket 类的 Connect 函数连接到远程桌面服务器。</li> <li>调用 RemoteDesktop 类的 GetScreenshot 函数获取远程桌面的屏幕截图。</li> <li>调用 RemoteDesktop 类的 MoveMouse、ClickMouse 或 InputKey 函数发送控制命令。</li> <li>重复步骤 4 和 5,实时更新远程桌面的屏幕截图并发送控制命令。</li> <li>当远程桌面控制结束时,调用 RemoteDesktop 类的 Disconnect 函数断开与远程桌面服务器的连接,并调用 Socket 类的 Cleanup 函数清理 WinSock 库。</li> </ol> <p>需要注意的是,这段代码使用了 MFC 库来绘制界面,因此需要在 Visual Studio 中创建一个 MFC 应用程序,并在对话框资源中添加一个对话框。然后将上面的代码放入主窗口类的 .cpp 文件中,并在 .h 文件中声明相应的消息映射函数。</p> <p>以下是服务端代码:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;Windows.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;GdiPlus.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;winsock2.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">pragma</span> comment(lib, <span class="string">&quot;gdiplus.lib&quot;</span>)</span></span><br><span class="line"><span class="meta">#<span class="keyword">pragma</span> comment(lib, <span class="string">&quot;ws2_32.lib&quot;</span>)</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> Gdiplus;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个 Socket 类,用于封装网络通信相关的操作</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Socket</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> WSADATA m_wsaData;</span><br><span class="line"> SOCKET m_sock;</span><br><span class="line"> sockaddr_in m_serverAddr;</span><br><span class="line"> sockaddr_in m_clientAddr;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="built_in">Socket</span>() : <span class="built_in">m_sock</span>(INVALID_SOCKET) &#123;&#125;</span><br><span class="line"> <span class="comment">// 初始化 WinSock 库</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Init</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">WSAStartup</span>(<span class="built_in">MAKEWORD</span>(<span class="number">2</span>, <span class="number">2</span>), &amp;m_wsaData) != <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建套接字</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Create</span><span class="params">(<span class="type">int</span> af, <span class="type">int</span> type, <span class="type">int</span> protocol)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> m_sock = <span class="built_in">socket</span>(af, type, protocol);</span><br><span class="line"> <span class="keyword">if</span> (m_sock == INVALID_SOCKET)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 绑定套接字到本地地址和端口</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Bind</span><span class="params">(<span class="type">unsigned</span> <span class="type">short</span> port)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="built_in">memset</span>(&amp;m_serverAddr, <span class="number">0</span>, <span class="built_in">sizeof</span>(m_serverAddr));</span><br><span class="line"> m_serverAddr.sin_family = AF_INET;</span><br><span class="line"> m_serverAddr.sin_addr.s_addr = <span class="built_in">htonl</span>(INADDR_ANY);</span><br><span class="line"> m_serverAddr.sin_port = <span class="built_in">htons</span>(port);</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">bind</span>(m_sock, (sockaddr*)&amp;m_serverAddr, <span class="built_in">sizeof</span>(m_serverAddr)) == SOCKET_ERROR)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 监听套接字</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Listen</span><span class="params">(<span class="type">int</span> backlog)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">listen</span>(m_sock, backlog) == SOCKET_ERROR)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 接受客户端的连接</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Accept</span><span class="params">(Socket&amp; client)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="type">int</span> addrLen = <span class="built_in">sizeof</span>(m_clientAddr);</span><br><span class="line"> client.m_sock = <span class="built_in">accept</span>(m_sock, (sockaddr*)&amp;m_clientAddr, &amp;addrLen);</span><br><span class="line"> <span class="keyword">if</span> (client.m_sock == INVALID_SOCKET)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 接收数据</span></span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">Receive</span><span class="params">(<span class="type">char</span>* buffer, <span class="type">int</span> len)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">recv</span>(m_sock, buffer, len, <span class="number">0</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送数据</span></span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">Send</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* buffer, <span class="type">int</span> len)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">send</span>(m_sock, buffer, len, <span class="number">0</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 关闭套接字</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Close</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="built_in">closesocket</span>(m_sock);</span><br><span class="line"> m_sock = INVALID_SOCKET;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 清理 WinSock 库</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Cleanup</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="built_in">WSACleanup</span>();</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个 RemoteDesktopServer 类,用于提供远程桌面服务</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RemoteDesktopServer</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> Socket m_socket; <span class="comment">// 用于网络通信的套接字</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="comment">// 初始化远程桌面服务器</span></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Init</span><span class="params">(<span class="type">unsigned</span> <span class="type">short</span> port)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Init</span>())</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Create</span>(AF_INET, SOCK_STREAM, IPPROTO_TCP))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Bind</span>(port))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Listen</span>(<span class="number">10</span>))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 运行远程桌面服务器</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">Run</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 不断循环,接受客户端的连接</span></span><br><span class="line"> <span class="keyword">while</span> (<span class="literal">true</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> Socket client;</span><br><span class="line"> <span class="keyword">if</span> (!m_socket.<span class="built_in">Accept</span>(client))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 为客户端创建一个线程,用于处理客户端的请求</span></span><br><span class="line"> HANDLE hThread = <span class="built_in">CreateThread</span>(<span class="literal">NULL</span>, <span class="number">0</span>, ClientThreadProc, &amp;client, <span class="number">0</span>, <span class="literal">NULL</span>);</span><br><span class="line"> <span class="keyword">if</span> (hThread == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> client.<span class="built_in">Close</span>();</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="built_in">CloseHandle</span>(hThread);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> <span class="comment">// 客户端线程的回调函数,用于处理客户端的请求</span></span><br><span class="line"> <span class="function"><span class="type">static</span> DWORD WINAPI <span class="title">ClientThreadProc</span><span class="params">(LPVOID lpParam)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> Socket* pClient = (Socket*)lpParam;</span><br><span class="line"> <span class="comment">// 不断循环,处理客户端的请求</span></span><br><span class="line"> <span class="keyword">while</span> (<span class="literal">true</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="comment">// 接收客户端的命令</span></span><br><span class="line"> <span class="type">char</span> cmd[<span class="number">256</span>];</span><br><span class="line"> <span class="type">int</span> len = pClient-&gt;<span class="built_in">Receive</span>(cmd, <span class="built_in">sizeof</span>(cmd));</span><br><span class="line"> <span class="keyword">if</span> (len &lt;= <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 根据命令类型执行相应的操作</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(cmd, <span class="string">&quot;screenshot&quot;</span>) == <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="comment">// 处理屏幕截图请求</span></span><br><span class="line"> <span class="built_in">HandleScreenshotRequest</span>(*pClient);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(cmd, <span class="string">&quot;mouse move&quot;</span>) == <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="comment">// 处理鼠标移动请求</span></span><br><span class="line"> <span class="type">int</span> x, y;</span><br><span class="line"> pClient-&gt;<span class="built_in">Receive</span>((<span class="type">char</span>*)&amp;x, <span class="built_in">sizeof</span>(x));</span><br><span class="line"> pClient-&gt;<span class="built_in">Receive</span>((<span class="type">char</span>*)&amp;y, <span class="built_in">sizeof</span>(y));</span><br><span class="line"> <span class="built_in">HandleMouseMoveRequest</span>(x, y);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(cmd, <span class="string">&quot;mouse click&quot;</span>) == <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="comment">// 处理鼠标单击请求</span></span><br><span class="line"> <span class="type">int</span> x, y;</span><br><span class="line"> pClient-&gt;<span class="built_in">Receive</span>((<span class="type">char</span>*)&amp;x, <span class="built_in">sizeof</span>(x));</span><br><span class="line"> pClient-&gt;<span class="built_in">Receive</span>((<span class="type">char</span>*)&amp;y, <span class="built_in">sizeof</span>(y));</span><br><span class="line"> <span class="built_in">HandleMouseClickRequest</span>(x, y);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(cmd, <span class="string">&quot;key input&quot;</span>) == <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="comment">// 处理键盘输入请求</span></span><br><span class="line"> <span class="type">char</span> key;</span><br><span class="line"> pClient-&gt;<span class="built_in">Receive</span>(&amp;key, <span class="built_in">sizeof</span>(key));</span><br><span class="line"> <span class="built_in">HandleKeyInputRequest</span>(key);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 关闭客户端的套接字</span></span><br><span class="line"> pClient-&gt;<span class="built_in">Close</span>();</span><br><span class="line"> <span class="keyword">delete</span> pClient;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 处理屏幕截图请求</span></span><br><span class="line"> <span class="function"><span class="type">static</span> <span class="type">void</span> <span class="title">HandleScreenshotRequest</span><span class="params">(Socket&amp; client)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 获取屏幕的宽高</span></span><br><span class="line"> <span class="type">int</span> width = <span class="built_in">GetSystemMetrics</span>(SM_CXSCREEN);</span><br><span class="line"> <span class="type">int</span> height = <span class="built_in">GetSystemMetrics</span>(SM_CYSCREEN);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建内存 DC</span></span><br><span class="line"> HDC hdcMem = <span class="built_in">CreateCompatibleDC</span>(<span class="literal">NULL</span>);</span><br><span class="line"> <span class="keyword">if</span> (hdcMem == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建位图</span></span><br><span class="line"> HBITMAP hbm = <span class="built_in">CreateCompatibleBitmap</span>(<span class="built_in">GetDC</span>(<span class="literal">NULL</span>), width, height);</span><br><span class="line"> <span class="keyword">if</span> (hbm == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将位图选入内存 DC</span></span><br><span class="line"> HBITMAP hbmOld = (HBITMAP)<span class="built_in">SelectObject</span>(hdcMem, hbm);</span><br><span class="line"> <span class="keyword">if</span> (hbmOld == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbm);</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将屏幕拷贝到内存 DC</span></span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">BitBlt</span>(hdcMem, <span class="number">0</span>, <span class="number">0</span>, width, height, <span class="built_in">GetDC</span>(<span class="literal">NULL</span>), <span class="number">0</span>, <span class="number">0</span>, SRCCOPY))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">SelectObject</span>(hdcMem, hbmOld);</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbm);</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将内存 DC 的图像保存到缓冲区</span></span><br><span class="line"> BITMAPINFOHEADER bih;</span><br><span class="line"> <span class="built_in">memset</span>(&amp;bih, <span class="number">0</span>, <span class="built_in">sizeof</span>(bih));</span><br><span class="line"> bih.biSize = <span class="built_in">sizeof</span>(bih);</span><br><span class="line"> bih.biWidth = width;</span><br><span class="line"> bih.biHeight = -height;</span><br><span class="line"> bih.biPlanes = <span class="number">1</span>;</span><br><span class="line"> bih.biBitCount = <span class="number">24</span>;</span><br><span class="line"> bih.biCompression = BI_RGB;</span><br><span class="line"> BYTE* pBuf = <span class="literal">NULL</span>;</span><br><span class="line"> HBITMAP hbmDib = <span class="built_in">CreateDIBSection</span>(hdcMem, (BITMAPINFO*)&amp;bih, DIB_RGB_COLORS, (<span class="type">void</span>**)&amp;pBuf, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">if</span> (hbmDib == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">SelectObject</span>(hdcMem, hbmOld);</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbm);</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 将内存 DC 的图像复制到位图中</span></span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">SelectObject</span>(hdcMem, hbmDib))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbmDib);</span><br><span class="line"> <span class="built_in">SelectObject</span>(hdcMem, hbmOld);</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbm);</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 将位图的图像转换为 JPEG 格式并发送到客户端</span></span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">SendScreenshot</span>(client, pBuf, width, height))</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbmDib);</span><br><span class="line"> <span class="built_in">SelectObject</span>(hdcMem, hbmOld);</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbm);</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 清理资源</span></span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbmDib);</span><br><span class="line"> <span class="built_in">SelectObject</span>(hdcMem, hbmOld);</span><br><span class="line"> <span class="built_in">DeleteObject</span>(hbm);</span><br><span class="line"> <span class="built_in">DeleteDC</span>(hdcMem);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将位图的图像转换为 JPEG 格式并发送到客户端</span></span><br><span class="line"> <span class="function"><span class="type">static</span> <span class="type">bool</span> <span class="title">SendScreenshot</span><span class="params">(Socket&amp; client, BYTE* pBuf, <span class="type">int</span> width, <span class="type">int</span> height)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 初始化 GDI+</span></span><br><span class="line"> GdiplusStartupInput gdiplusStartupInput;</span><br><span class="line"> ULONG_PTR gdiplusToken;</span><br><span class="line"> <span class="built_in">GdiplusStartup</span>(&amp;gdiplusToken, &amp;gdiplusStartupInput, <span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将位图的图像转换为 JPEG 格式</span></span><br><span class="line"> <span class="function">Bitmap <span class="title">bmp</span><span class="params">(width, height, width * <span class="number">3</span>, PixelFormat24bppRGB, pBuf)</span></span>;</span><br><span class="line"> CLSID clsid;</span><br><span class="line"> <span class="built_in">GetEncoderClsid</span>(<span class="string">L&quot;image/jpeg&quot;</span>, &amp;clsid);</span><br><span class="line"> IStream* pStream = <span class="literal">NULL</span>;</span><br><span class="line"> bmp.<span class="built_in">Save</span>(<span class="string">L&quot;screenshot.jpg&quot;</span>, &amp;clsid, <span class="literal">NULL</span>);</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">CreateStreamOnHGlobal</span>(<span class="literal">NULL</span>, TRUE, &amp;pStream) != S_OK)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> bmp.<span class="built_in">Save</span>(pStream, &amp;clsid, <span class="literal">NULL</span>);</span><br><span class="line"> HGLOBAL hGlobal = <span class="literal">NULL</span>; <span class="comment">// 修改为 HGLOBAL 类型</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">GetHGlobalFromStream</span>(pStream, &amp;hGlobal) != S_OK) <span class="comment">// 修改为 HGLOBAL 类型</span></span><br><span class="line"> &#123;</span><br><span class="line"> pStream-&gt;<span class="built_in">Release</span>();</span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> ULONG cbSize = <span class="built_in">GlobalSize</span>(hGlobal); <span class="comment">// 修改为 HGLOBAL 类型</span></span><br><span class="line"> BYTE* pJpegBuf = (BYTE*)<span class="built_in">GlobalLock</span>(hGlobal); <span class="comment">// 修改为 HGLOBAL 类型</span></span><br><span class="line"> <span class="keyword">if</span> (pJpegBuf == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> pStream-&gt;<span class="built_in">Release</span>();</span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> LARGE_INTEGER li;</span><br><span class="line"> li.QuadPart = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (pStream-&gt;<span class="built_in">Seek</span>(li, STREAM_SEEK_SET, <span class="literal">NULL</span>) != S_OK)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">GlobalFree</span>(pJpegBuf);</span><br><span class="line"> pStream-&gt;<span class="built_in">Release</span>();</span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (pStream-&gt;<span class="built_in">Read</span>(pJpegBuf, cbSize, <span class="literal">NULL</span>) != S_OK)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">GlobalFree</span>(pJpegBuf);</span><br><span class="line"> pStream-&gt;<span class="built_in">Release</span>();</span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> pStream-&gt;<span class="built_in">Release</span>();</span><br><span class="line"> <span class="built_in">GdiplusShutdown</span>(gdiplusToken);</span><br><span class="line"> <span class="comment">// 将 JPEG 数据的长度发送到客户端</span></span><br><span class="line"> <span class="keyword">if</span> (client.<span class="built_in">Send</span>((<span class="type">char</span>*)&amp;cbSize, <span class="built_in">sizeof</span>(cbSize)) &lt;= <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">GlobalFree</span>(pJpegBuf);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将 JPEG 数据发送到客户端</span></span><br><span class="line"> <span class="keyword">if</span> (client.<span class="built_in">Send</span>((<span class="type">char</span>*)pJpegBuf, cbSize) &lt;= <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="built_in">GlobalFree</span>(pJpegBuf);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 清理资源</span></span><br><span class="line"> <span class="built_in">GlobalFree</span>(pJpegBuf);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 获取图像编码器的 CLSID</span></span><br><span class="line"> <span class="function"><span class="type">static</span> <span class="type">void</span> <span class="title">GetEncoderClsid</span><span class="params">(<span class="type">const</span> WCHAR* format, CLSID* pClsid)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> UINT num = <span class="number">0</span>, size = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">GetImageEncodersSize</span>(&amp;num, &amp;size);</span><br><span class="line"> <span class="keyword">if</span> (size == <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)<span class="built_in">malloc</span>(size);</span><br><span class="line"> <span class="keyword">if</span> (pImageCodecInfo == <span class="literal">NULL</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="built_in">GetImageEncoders</span>(num, size, pImageCodecInfo);</span><br><span class="line"> <span class="keyword">for</span> (UINT i = <span class="number">0</span>; i &lt; num; ++i)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">wcscmp</span>(pImageCodecInfo[i].MimeType, format) == <span class="number">0</span>)</span><br><span class="line"> &#123;</span><br><span class="line"> *pClsid = pImageCodecInfo[i].Clsid;</span><br><span class="line"> <span class="built_in">free</span>(pImageCodecInfo);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="built_in">free</span>(pImageCodecInfo);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 处理鼠标移动请求</span></span><br><span class="line"> <span class="function"><span class="type">static</span> <span class="type">void</span> <span class="title">HandleMouseMoveRequest</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 获取屏幕的宽高</span></span><br><span class="line"> <span class="type">int</span> width = <span class="built_in">GetSystemMetrics</span>(SM_CXSCREEN);</span><br><span class="line"> <span class="type">int</span> height = <span class="built_in">GetSystemMetrics</span>(SM_CYSCREEN);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 计算相对于屏幕的坐标</span></span><br><span class="line"> <span class="type">double</span> fx = (<span class="type">double</span>)x / <span class="number">65535.0</span>;</span><br><span class="line"> <span class="comment">// 移动鼠标</span></span><br><span class="line"> <span class="built_in">SetCursorPos</span>(x, y);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 处理鼠标单击请求</span></span><br><span class="line"> <span class="function"><span class="type">static</span> <span class="type">void</span> <span class="title">HandleMouseClickRequest</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 获取屏幕的宽高</span></span><br><span class="line"> <span class="type">int</span> width = <span class="built_in">GetSystemMetrics</span>(SM_CXSCREEN);</span><br><span class="line"> <span class="type">int</span> height = <span class="built_in">GetSystemMetrics</span>(SM_CYSCREEN);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 计算相对于屏幕的坐标</span></span><br><span class="line"> <span class="type">double</span> fx = (<span class="type">double</span>)x / <span class="number">65535.0</span>;</span><br><span class="line"> <span class="type">double</span> fy = (<span class="type">double</span>)y / <span class="number">65535.0</span>;</span><br><span class="line"> <span class="type">int</span> cx = (<span class="type">int</span>)(fx * width);</span><br><span class="line"> <span class="type">int</span> cy = (<span class="type">int</span>)(fy * height);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 移动鼠标</span></span><br><span class="line"> <span class="built_in">SetCursorPos</span>(cx, cy);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送鼠标左键单击消息</span></span><br><span class="line"> INPUT input;</span><br><span class="line"> <span class="built_in">memset</span>(&amp;input, <span class="number">0</span>, <span class="built_in">sizeof</span>(input));</span><br><span class="line"> input.type = INPUT_MOUSE;</span><br><span class="line"> input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;</span><br><span class="line"> <span class="built_in">SendInput</span>(<span class="number">1</span>, &amp;input, <span class="built_in">sizeof</span>(input));</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 处理键盘输入请求</span></span><br><span class="line"> <span class="function"><span class="type">static</span> <span class="type">void</span> <span class="title">HandleKeyInputRequest</span><span class="params">(<span class="type">char</span> key)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="comment">// 获取键盘的输入模式</span></span><br><span class="line"> HKL layout = <span class="built_in">GetKeyboardLayout</span>(<span class="number">0</span>);</span><br><span class="line"> UINT vk = <span class="built_in">MapVirtualKeyExA</span>(<span class="built_in">VkKeyScanExA</span>(key, layout), <span class="number">0</span>, layout);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送键盘输入消息</span></span><br><span class="line"> INPUT input;</span><br><span class="line"> <span class="built_in">memset</span>(&amp;input, <span class="number">0</span>, <span class="built_in">sizeof</span>(input));</span><br><span class="line"> input.type = INPUT_KEYBOARD;</span><br><span class="line"> input.ki.wVk = vk;</span><br><span class="line"> <span class="built_in">SendInput</span>(<span class="number">1</span>, &amp;input, <span class="built_in">sizeof</span>(input));</span><br><span class="line"> &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> Socket m_socket; <span class="comment">// 监听套接字</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> RemoteDesktopServer server;</span><br><span class="line"> <span class="keyword">if</span> (!server.<span class="built_in">Init</span>(<span class="number">5555</span>))</span><br><span class="line"> &#123;</span><br><span class="line"> cout&lt;&lt;<span class="string">&quot;启动服务器失败!&quot;</span>&lt;&lt;endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> server.<span class="built_in">Run</span>();</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure></p> <p>希望这些代码能帮到你!</p>

2022/12/23
阅读更多

用c++写图像界面软件(QT)

<p><strong>在 C++ 中编写图形界面软件的方法有很多种,下面介绍一种使用 Qt 库来编写图形界面软件的方法。</strong></p> <p>首先,需要安装 Qt 开发环境。你可以在 Qt 官网下载安装包,并按照安装说明进行安装。<br /> 然后,在 Qt Creator 中创建一个新的项目。在项目向导中,选择 “应用程序”,并选择 “控件” 作为模板。这会创建一个有一个窗口和几个控件(按钮、标签等)的基本图形界面应用程序。<br /> 现在,你可以开始在界面中添加各种控件,例如图片、文本框、复选框等。可以使用 Qt Designer 工具来设计界面。</p> <p>在设计界面时,你可以使用拖放控件的方式,将控件放到界面上。然后,你可以使用属性编辑器来设置控件的各种属性,例如大小、颜色、字体等。</p> <p>在代码中,你可以使用信号和槽机制来连接界面中的控件和应用程序的功能。例如,可以让按钮的单击信号连接到一个槽函数,从而在按钮被单击时执行特定的操作。</p> <hr /> <p>下面是一个简单的示例代码,显示了如何使用 Qt 创建一个带有一个按钮的窗口,并在按钮被单击时弹出对话框:</p> <p><figure class="highlight cpp"><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 class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QPushButton&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QMessageBox&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function">QPushButton <span class="title">button</span><span class="params">(<span class="string">&quot;Click me&quot;</span>)</span></span>;</span><br><span class="line"> QObject::<span class="built_in">connect</span>(&amp;button, &amp;QPushButton::clicked, []() &#123;</span><br><span class="line"> QMessageBox::<span class="built_in">information</span>(<span class="literal">nullptr</span>, <span class="string">&quot;Title&quot;</span>, <span class="string">&quot;Hello, World!&quot;</span>);</span><br><span class="line"> &#125;);</span><br><span class="line"> button.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <hr /> <p>接下来,我们来看如何在代码中添加菜单栏。</p> <p>首先,在界面设计器中添加一个菜单栏控件。然后,在代码中使用 <code>QMenuBar</code> 类创建一个菜单栏对象,并将其添加到窗口中。</p> <p>接下来,你可以使用 <code>QMenu</code> 类创建菜单,并添加到菜单栏中。你还可以使用 <code>QAction</code> 类创建菜单项,并添加到菜单中。</p> <p>例如,下面的代码演示了如何创建一个带有 “文件” 菜单的菜单栏,其中包含 “打开” 和 “保存” 两个菜单项:</p> <p><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QMainWindow&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QMenuBar&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QMenu&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QAction&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> QMainWindow window;</span><br><span class="line"> window.<span class="built_in">setWindowTitle</span>(<span class="string">&quot;My App&quot;</span>);</span><br><span class="line"></span><br><span class="line"> QMenuBar *menuBar = <span class="keyword">new</span> <span class="built_in">QMenuBar</span>(&amp;window);</span><br><span class="line"> QMenu *fileMenu = <span class="keyword">new</span> <span class="built_in">QMenu</span>(<span class="string">&quot;File&quot;</span>, menuBar);</span><br><span class="line"> QAction *openAction = <span class="keyword">new</span> <span class="built_in">QAction</span>(<span class="string">&quot;Open&quot;</span>, fileMenu);</span><br><span class="line"> QAction *saveAction = <span class="keyword">new</span> <span class="built_in">QAction</span>(<span class="string">&quot;Save&quot;</span>, fileMenu);</span><br><span class="line"> fileMenu-&gt;<span class="built_in">addAction</span>(openAction);</span><br><span class="line"> fileMenu-&gt;<span class="built_in">addAction</span>(saveAction);</span><br><span class="line"> menuBar-&gt;<span class="built_in">addMenu</span>(fileMenu);</span><br><span class="line"> window.<span class="built_in">setMenuBar</span>(menuBar);</span><br><span class="line"></span><br><span class="line"> window.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <hr /> <p>为了在图形界面软件中显示图片,你可以使用 Qt 中的 <code>QLabel</code> 控件。</p> <p>首先,在界面设计器中添加一个 <code>QLabel</code> 控件。然后,在代码中,你可以使用 <code>QLabel</code> 类的 <code>setPixmap</code> 方法来设置要显示的图片。</p> <p>例如,下面的代码演示了如何在图形界面中显示一张名为 “image.png” 的图片:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QLabel&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QPixmap&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> QLabel label;</span><br><span class="line"> <span class="function">QPixmap <span class="title">pixmap</span><span class="params">(<span class="string">&quot;image.png&quot;</span>)</span></span>;</span><br><span class="line"> label.<span class="built_in">setPixmap</span>(pixmap);</span><br><span class="line"> label.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>注意,在使用 <code>QLabel</code> 显示图片时,需要使用 <code>QPixmap</code> 类来加载图片文件。</p> <hr /> <p>如果你想要在图形界面中显示动态图像,你可以使用 Qt 中的 <code>QMovie</code> 类。 <code>QMovie</code> 类可以用来播放 GIF 动画。</p> <p>例如,下面的代码演示了如何在图形界面中播放名为 “animation.gif” 的 GIF 动画:</p> <p><figure class="highlight cpp"><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 class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QLabel&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QMovie&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> QLabel label;</span><br><span class="line"> <span class="function">QMovie <span class="title">movie</span><span class="params">(<span class="string">&quot;animation.gif&quot;</span>)</span></span>;</span><br><span class="line"> label.<span class="built_in">setMovie</span>(&amp;movie);</span><br><span class="line"> movie.<span class="built_in">start</span>();</span><br><span class="line"> label.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <hr /> <p>现在,我们来看如何在图形界面软件中添加图表。</p> <p>首先,你需要在界面设计器中添加一个图表控件。Qt 中有多种图表控件可供选择,包括柱状图、折线图、饼图等。</p> <p>然后,你可以使用 <code>QChart</code> 类创建图表对象,并使用 <code>QAbstractSeries</code> 类的子类(例如 <code>QLineSeries</code> 、 <code>QBarSeries</code> 等)创建数据序列。你还可以使用 <code>QValueAxis</code> 类创建坐标轴,并将它们添加到图表中。</p> <p>例如,下面的代码演示了如何创建一个带有两个数据序列的柱状图:</p> <p><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QChart&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QChartView&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QBarSeries&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QBarSet&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QValueAxis&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> QBarSet *set1 = <span class="keyword">new</span> <span class="built_in">QBarSet</span>(<span class="string">&quot;Data 1&quot;</span>);</span><br><span class="line"> *set1 &lt;&lt; <span class="number">1</span> &lt;&lt; <span class="number">2</span> &lt;&lt; <span class="number">3</span> &lt;&lt; <span class="number">4</span> &lt;&lt; <span class="number">5</span>;</span><br><span class="line"> QBarSet *set2 = <span class="keyword">new</span> <span class="built_in">QBarSet</span>(<span class="string">&quot;Data 2&quot;</span>);</span><br><span class="line"> *set2 &lt;&lt; <span class="number">5</span> &lt;&lt; <span class="number">4</span> &lt;&lt; <span class="number">3</span> &lt;&lt; <span class="number">2</span> &lt;&lt; <span class="number">1</span>;</span><br><span class="line"> QBarSeries *series = <span class="keyword">new</span> <span class="built_in">QBarSeries</span>();</span><br><span class="line"> series-&gt;<span class="built_in">append</span>(set1);</span><br><span class="line"> series-&gt;<span class="built_in">append</span>(set2);</span><br><span class="line"> QChart *chart = <span class="keyword">new</span> <span class="built_in">QChart</span>();</span><br><span class="line"> chart-&gt;<span class="built_in">addSeries</span>(series);</span><br><span class="line"> chart-&gt;<span class="built_in">setTitle</span>(<span class="string">&quot;Example Chart&quot;</span>);</span><br><span class="line"> QValueAxis *axisX = <span class="keyword">new</span> <span class="built_in">QValueAxis</span>();</span><br><span class="line"> axisX-&gt;<span class="built_in">setRange</span>(<span class="number">0</span>, <span class="number">6</span>);</span><br><span class="line"> axisX-&gt;<span class="built_in">setLabelFormat</span>(<span class="string">&quot;%g&quot;</span>);</span><br><span class="line"> chart-&gt;<span class="built_in">addAxis</span>(axisX, Qt::AlignBottom);</span><br><span class="line"> series-&gt;<span class="built_in">attachAxis</span>(axisX);</span><br><span class="line"> QValueAxis *axisY = <span class="keyword">new</span> <span class="built_in">QValueAxis</span>();</span><br><span class="line"> axisY-&gt;<span class="built_in">setRange</span>(<span class="number">0</span>, <span class="number">6</span>);</span><br><span class="line"> axisY-&gt;<span class="built_in">setTitleText</span>(<span class="string">&quot;Y-axis&quot;</span>);</span><br><span class="line"> chart-&gt;<span class="built_in">addAxis</span>(axisY, Qt::AlignLeft);</span><br><span class="line"> series-&gt;<span class="built_in">attachAxis</span>(axisY);</span><br><span class="line"></span><br><span class="line"> <span class="function">QChartView <span class="title">chartView</span><span class="params">(chart)</span></span>;</span><br><span class="line"> chartView.<span class="built_in">setRenderHint</span>(QPainter::Antialiasing);</span><br><span class="line"> chartView.<span class="built_in">resize</span>(<span class="number">400</span>, <span class="number">300</span>);</span><br><span class="line"> chartView.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>在这段代码中,我们首先创建了两个数据序列(使用 <code>QBarSet</code> 类),然后将它们添加到一个 <code>QBarSeries</code> 对象中。接着,我们创建了一个 <code>QChart</code> 对象,并将数据序列添加到图表中。最后,我们创建了两个坐标轴(使用 <code>QValueAxis</code> 类),并将它们添加到图表中。</p> <hr /> <p>接下来,让我们来看如何在图形界面软件中添加交互式图表。</p> <p>为了实现交互式图表,你可以使用 Qt 中的 <code>QChartView</code> 类。 <code>QChartView</code> 类提供了一些内置的交互工具,包括缩放、拖拽、轴调整等。</p> <p>要使用 <code>QChartView</code> 类,你需要先创建一个 <code>QChart</code> 对象,然后将其传递给 <code>QChartView</code> 的构造函数。例如,下面的代码演示了如何创建一个交互式的折线图:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QChart&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QChartView&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QLineSeries&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QValueAxis&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> QLineSeries *series = <span class="keyword">new</span> <span class="built_in">QLineSeries</span>();</span><br><span class="line"> *series &lt;&lt; <span class="built_in">QPointF</span>(<span class="number">0</span>, <span class="number">0</span>) &lt;&lt; <span class="built_in">QPointF</span>(<span class="number">1</span>, <span class="number">1</span>) &lt;&lt; <span class="built_in">QPointF</span>(<span class="number">2</span>, <span class="number">4</span>) &lt;&lt; <span class="built_in">QPointF</span>(<span class="number">3</span>, <span class="number">9</span>);</span><br><span class="line"> QChart *chart = <span class="keyword">new</span> <span class="built_in">QChart</span>();</span><br><span class="line"> chart-&gt;<span class="built_in">addSeries</span>(series);</span><br><span class="line"> chart-&gt;<span class="built_in">setTitle</span>(<span class="string">&quot;Simple line chart example&quot;</span>);</span><br><span class="line"> chart-&gt;<span class="built_in">createDefaultAxes</span>();</span><br><span class="line"> <span class="function">QChartView <span class="title">chartView</span><span class="params">(chart)</span></span>;</span><br><span class="line"> chartView.<span class="built_in">setRenderHint</span>(QPainter::Antialiasing);</span><br><span class="line"> chartView.<span class="built_in">resize</span>(<span class="number">400</span>, <span class="number">300</span>);</span><br><span class="line"> chartView.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>在这段代码中,我们首先创建了一个数据序列(使用 <code>QLineSeries</code> 类),然后将它添加到一个 <code>QChart</code> 对象中。接着,我们调用 <code>QChart</code> 类的 <code>createDefaultAxes</code> 方法来创建默认的坐标轴。最后,我们创建了一个 <code>QChartView</code> 对象,并将图表传递给它。</p> <hr /> <p>接下来,让我们来看如何在图形界面软件中使用 OpenCV 读取和显示图像。</p> <p>首先,你需要安装 OpenCV 库。在 Windows 上,你可以使用 vcpkg 工具安装 OpenCV。在 Linux 上,你可以使用包管理器安装 OpenCV。</p> <p>然后,你需要在 Qt 工程中添加 OpenCV 的头文件和库文件。具体方法可以参考 Qt 文档。</p> <p>接着,你就可以使用 OpenCV 的 <code>cv::Mat</code> 类来读取和显示图像了。例如,下面的代码演示了如何使用 OpenCV 读取名为 “image.png” 的图片并在图形界面中显示:</p> <p><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QLabel&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;opencv2/opencv.hpp&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> cv::Mat image = cv::<span class="built_in">imread</span>(<span class="string">&quot;image.png&quot;</span>);</span><br><span class="line"> QImage qimage = <span class="built_in">QImage</span>((<span class="type">const</span> <span class="type">unsigned</span> <span class="type">char</span>*)(image.data),</span><br><span class="line"> image.cols, image.rows, image.step, QImage::Format_RGB888);</span><br><span class="line"> QLabel label;</span><br><span class="line"> label.<span class="built_in">setPixmap</span>(QPixmap::<span class="built_in">fromImage</span>(qimage));</span><br><span class="line"> label.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>在这段代码中,我们使用 OpenCV 的 <code>imread</code> 函数读取图片,然后将图片数据转换为 <code>QImage</code> 对象。最后,我们使用 <code>QLabel</code> 类显示图片。</p> <hr /> <p>注意,如果你想要在图形界面软件中显示动态图像,你可以使用 Qt 中的 <code>QTimer</code> 类来实现。</p> <p>例如,下面的代码演示了如何使用 OpenCV 读取视频并在图形界面中显示:</p> <p><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QApplication&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QLabel&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;QTimer&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;opencv2/opencv.hpp&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="function">QApplication <span class="title">app</span><span class="params">(argc, argv)</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function">cv::VideoCapture <span class="title">capture</span><span class="params">(<span class="string">&quot;video.mp4&quot;</span>)</span></span>;</span><br><span class="line"> QLabel label;</span><br><span class="line"> QTimer timer;</span><br><span class="line"> QObject::<span class="built_in">connect</span>(&amp;timer, &amp;QTimer::timeout, [&amp;]() &#123;</span><br><span class="line"> cv::Mat frame;</span><br><span class="line"> capture &gt;&gt; frame;</span><br><span class="line"> <span class="keyword">if</span> (frame.<span class="built_in">empty</span>()) &#123;</span><br><span class="line"> capture.<span class="built_in">set</span>(cv::CAP_PROP_POS_AVI_RATIO, <span class="number">0</span>);</span><br><span class="line"> capture &gt;&gt; frame;</span><br><span class="line"> &#125;</span><br><span class="line"> QImage qimage = <span class="built_in">QImage</span>((<span class="type">const</span> <span class="type">unsigned</span> <span class="type">char</span>*)(frame.data),</span><br><span class="line"> frame.cols, frame.rows, frame.step, QImage::Format_RGB888);</span><br><span class="line"> label.<span class="built_in">setPixmap</span>(QPixmap::<span class="built_in">fromImage</span>(qimage));</span><br><span class="line"> &#125;);</span><br><span class="line"> timer.<span class="built_in">start</span>(<span class="number">1000</span> / <span class="number">30</span>);</span><br><span class="line"> label.<span class="built_in">show</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app.<span class="built_in">exec</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>在这段代码中,我们使用 OpenCV 的 <code>VideoCapture</code> 类读取视频,然后使用 <code>QTimer</code> 类定时获取视频帧并更新图像。注意,我们使用 <code>QImage</code> 类将视频帧转换为图像,并使用 <code>QLabel</code> 类显示图像。</p> <p>这是一个简单的示例,你还可以自己添加更多的功能,例如暂停、快进、播放速度调整等。</p> <hr /> <p><strong>希望这些信息对你有帮助!如果喜欢的话,可以在下方打赏作者哦</strong></p>

2022/12/22
阅读更多

C++中常用的排序算法

<p>在 C++ 中,常用的排序算法包括:</p> <ol> <li>冒泡排序(Bubble Sort)</li> </ol> <p>冒泡排序是一种简单的排序算法,它通过重复地遍历要排序的数列并比较相邻的两个数来排序。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">bubbleSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n - <span class="number">1</span>; i++) &#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; n - i - <span class="number">1</span>; j++) &#123;</span><br><span class="line"> <span class="keyword">if</span> (arr[j] &gt; arr[j + <span class="number">1</span>]) &#123;</span><br><span class="line"> <span class="type">int</span> temp = arr[j];</span><br><span class="line"> arr[j] = arr[j + <span class="number">1</span>];</span><br><span class="line"> arr[j + <span class="number">1</span>] = temp;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <ol start="2"> <li>选择排序(Selection Sort)</li> </ol> <p>选择排序是一种简单的排序算法,它通过遍历数列来找到最小值并将其放到数列的起始位置,然后再从剩余未排序的数列中继续寻找最小值并放到已排序的数列末尾,以此类推直到所有数列排序完毕。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><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="function"><span class="type">void</span> <span class="title">selectionSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n - <span class="number">1</span>; i++) &#123;</span><br><span class="line"> <span class="type">int</span> minIndex = i;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = i + <span class="number">1</span>; j &lt; n; j++) &#123;</span><br><span class="line"> <span class="keyword">if</span> (arr[j] &lt; arr[minIndex]) &#123;</span><br><span class="line"> minIndex = j;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="type">int</span> temp = arr[i];</span><br><span class="line"> arr[i] = arr[minIndex];</span><br><span class="line"> arr[minIndex] = temp;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <ol start="3"> <li>插入排序(Insertion Sort)</li> </ol> <p>插入排序是一种简单的排序算法,它通过将数列分成已排序和未排序两部分,然后从未排序的数列中取出第一个数,并插入到已排序的数列中的适当位置,使得已排序的数列仍然有序。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">insertionSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt; n; i++) &#123;</span><br><span class="line"> <span class="type">int</span> key = arr[i];</span><br><span class="line"> <span class="type">int</span> j = i - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (j &gt;= <span class="number">0</span> &amp;&amp; arr[j] &gt; key) &#123;</span><br><span class="line"> arr[j + <span class="number">1</span>] = arr[j];</span><br><span class="line"> j--;</span><br><span class="line"> &#125;</span><br><span class="line"> arr[j + <span class="number">1</span>] = key;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <ol start="4"> <li>归并排序(Merge Sort)</li> </ol> <p>归并排序是一种分治算法,它通过递归地将数列分成两半,然后将两半分别排序,最后将两半合并起来得到最终的排序结果。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">merge</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> left[], <span class="type">int</span> leftSize, <span class="type">int</span> right[], <span class="type">int</span> rightSize)</span> </span>&#123;</span><br><span class="line"> <span class="type">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>, k = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (i &lt; leftSize &amp;&amp; j &lt; rightSize) &#123;</span><br><span class="line"> <span class="keyword">if</span> (left[i] &lt; right[j]) &#123;</span><br><span class="line"> arr[k++] = left[i++];</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> arr[k++] = right[j++];</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">while</span> (i &lt; leftSize) &#123;</span><br><span class="line"> arr[k++] = left[i++];</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">while</span> (j &lt; rightSize) &#123;</span><br><span class="line"> arr[k++] = right[j++];</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">mergeSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (n &lt; <span class="number">2</span>) <span class="keyword">return</span>;</span><br><span class="line"> <span class="type">int</span> mid = n / <span class="number">2</span>;</span><br><span class="line"> <span class="type">int</span> left[mid];</span><br><span class="line"> <span class="type">int</span> right[n - mid];</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; mid; i++) &#123;</span><br><span class="line"> left[i] = arr[i];</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = mid; i &lt; n; i++) &#123;</span><br><span class="line"> right[i - mid] = arr[i];</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="built_in">mergeSort</span>(left, mid);</span><br><span class="line"> <span class="built_in">mergeSort</span>(right, n - mid);</span><br><span class="line"> <span class="built_in">merge</span>(arr, left, mid, right, n - mid);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <ol start="5"> <li>快速排序(Quick Sort)</li> </ol> <p>快速排序是一种分治算法,它通过选择一个基准元素,将数列分成两部分,使得左边的所有元素都小于基准元素,右边的所有元素都大于基准元素,然后递归地对两部分进行快速排序,最终得到有序的数列。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">partition</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> low, <span class="type">int</span> high)</span> </span>&#123;</span><br><span class="line"> <span class="type">int</span> pivot = arr[high];</span><br><span class="line"> <span class="type">int</span> i = low - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = low; j &lt;= high - <span class="number">1</span>; j++) &#123;</span><br><span class="line"> <span class="keyword">if</span> (arr[j] &lt; pivot) &#123;</span><br><span class="line"> i++;</span><br><span class="line"> <span class="type">int</span> temp = arr[i];</span><br><span class="line"> arr[i] = arr[j];</span><br><span class="line"> arr[j] = temp;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="type">int</span> temp = arr[i + <span class="number">1</span>];</span><br><span class="line"> arr[i + <span class="number">1</span>] = arr[high];</span><br><span class="line"> arr[high] = temp;</span><br><span class="line"> <span class="keyword">return</span> i + <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">quickSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> low, <span class="type">int</span> high)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (low &lt; high) &#123;</span><br><span class="line"> <span class="type">int</span> pi = <span class="built_in">partition</span>(arr, low, high);</span><br><span class="line"> <span class="built_in">quickSort</span>(arr, low, pi - <span class="number">1</span>);</span><br><span class="line"> <span class="built_in">quickSort</span>(arr, pi + <span class="number">1</span>, high);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <p>这些排序算法的时间复杂度各不相同,在不同情况下可能会有所差异。你可以根据自己的需要来选择适合的排序算法。<br /> 除了以上几种常用的排序算法之外,还有其他一些不太常用的排序算法,例如:</p> <ol start="6"> <li>希尔排序(Shell Sort)</li> </ol> <p>希尔排序是一种插入排序的变种,它通过设置一个间隔来将数列划分成若干个小的数列,然后对每个小数列进行插入排序,最终得到有序的数列。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">shellSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> gap = n / <span class="number">2</span>; gap &gt; <span class="number">0</span>; gap /= <span class="number">2</span>) &#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = gap; i &lt; n; i++) &#123;</span><br><span class="line"> <span class="type">int</span> temp = arr[i];</span><br><span class="line"> <span class="type">int</span> j;</span><br><span class="line"> <span class="keyword">for</span> (j = i; j &gt;= gap &amp;&amp; arr[j - gap] &gt; temp; j -= gap) &#123;</span><br><span class="line"> arr[j] = arr[j - gap];</span><br><span class="line"> &#125;</span><br><span class="line"> arr[j] = temp;</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> <ol start="7"> <li>堆排序(Heap Sort)</li> </ol> <p>堆排序是一种选择排序的变种,它通过建立一个堆来选择最大(或最小)的元素并放到数列末尾,然后将剩余的数列重新建堆并继续选择最大(或最小)的元素,以此类推直到所有数列排序完毕。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">heapify</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n, <span class="type">int</span> i)</span> </span>&#123;</span><br><span class="line"> <span class="type">int</span> largest = i;</span><br><span class="line"> <span class="type">int</span> left = <span class="number">2</span> * i + <span class="number">1</span>;</span><br><span class="line"> <span class="type">int</span> right = <span class="number">2</span> * i + <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">if</span> (left &lt; n &amp;&amp; arr[left] &gt; arr[largest]) &#123;</span><br><span class="line"> largest = left;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (right &lt; n &amp;&amp; arr[right] &gt; arr[largest]) &#123;</span><br><span class="line"> largest = right;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (largest != i) &#123;</span><br><span class="line"> <span class="type">int</span> temp = arr[i];</span><br><span class="line"> arr[i] = arr[largest];</span><br><span class="line"> arr[largest] = temp;</span><br><span class="line"> <span class="built_in">heapify</span>(arr, n, largest);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">heapSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = n / <span class="number">2</span> - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line"><span class="built_in">heapify</span>(arr, n, i);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = n - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line"><span class="type">int</span> temp = arr[<span class="number">0</span>];</span><br><span class="line">arr[<span class="number">0</span>] = arr[i];</span><br><span class="line">arr[i] = temp;</span><br><span class="line"><span class="built_in">heapify</span>(arr, i, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p> <ol start="8"> <li>计数排序(Counting Sort)</li> </ol> <p>计数排序是一种非比较排序算法,它通过计算数列中每个数出现的次数来排序。它的时间复杂度为 O (n),因此在数据范围较小的情况下可以使用计数排序。</p> <p>代码如下:</p> <p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">countingSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n, <span class="type">int</span> maxValue)</span> </span>&#123;</span><br><span class="line"> <span class="type">int</span> counts[maxValue + <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt;= maxValue; i++) &#123;</span><br><span class="line"> counts[i] = <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line"> counts[arr[i]]++;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>; i &lt;= maxValue; i++) &#123;</span><br><span class="line"> <span class="keyword">while</span> (counts[i]-- &gt; <span class="number">0</span>) &#123;</span><br><span class="line"> arr[j++] = i;</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> <p>以上是 C++ 中的几种排序算法的代码,希望能帮到你。</p>

2022/12/22
阅读更多

《简爱》每章概括+赏析

<h1 id="每章概括"><a class="anchor" href="#每章概括">#</a> <strong>每章概括</strong>:</h1> <h2 id="第一章"><a class="anchor" href="#第一章">#</a> <strong>第一章:</strong></h2> <p><strong>简・爱的父亲是个穷牧师,当她还在幼年时,父母就染病双双去世。简・爱被送到盖茨海德庄园的舅母里德太太家抚养.</strong></p> <hr /> <h2 id="第二章"><a class="anchor" href="#第二章">#</a> <strong>第二章:</strong></h2> <p><strong>舅父里德先生在红房子中去世后,简爱过了 10 年受尽歧视和虐待的生活。一次,由于反抗表哥的殴打,简被关进了红房子。肉体上的痛苦和心灵上的屈辱和恐惧,使她大病了一场。</strong></p> <hr /> <h2 id="第三章"><a class="anchor" href="#第三章">#</a> <strong>第三章:</strong></h2> <p><strong>舅母把她视作眼中钉,并把她和自己的孩子隔离开来,并决定把她送进达罗沃德孤儿院。</strong></p> <hr /> <h2 id="第四章"><a class="anchor" href="#第四章">#</a> <strong>第四章:</strong></h2> <p><strong>由于她与舅母的对抗更加公开和坚决,里德太太加快了送简爱去孤儿院的脚步,为了赶走简爱,她在勃洛克赫斯特先生面前处处中伤简爱,毁坏简爱的名誉。</strong></p> <hr /> <h2 id="第五章"><a class="anchor" href="#第五章">#</a> <strong>第五章:</strong></h2> <p><strong>孤儿院教规严厉,生活艰苦,院长是个冷酷的伪君子。他用种种办法从精神和肉体上摧残孤儿。简爱吃不饱、穿不暖,继续受尽非人的折磨。</strong></p> <hr /> <h2 id="第六章"><a class="anchor" href="#第六章">#</a> <strong>第六章:</strong></h2> <p><strong>简・爱与孤儿海伦结成好友,教师潭泊尔小姐也很关心她。</strong></p> <hr /> <h2 id="第七章"><a class="anchor" href="#第七章">#</a> <strong>第七章:</strong></h2> <p><strong>简爱失手打碎了石板,被惩罚站在凳子上,当众受到羞辱,是海伦的微笑给了简爱力量。</strong></p> <hr /> <h2 id="第八章"><a class="anchor" href="#第八章">#</a> <strong>第八章:</strong></h2> <p><strong>伤心的简爱到学校下课时才从凳子上下来,悲愤不已,海伦给她端来咖啡和面包,并不断开导她。谭波小姐也来看望她,并与海伦谈古论今,使简爱佩服不已。</strong></p> <hr /> <h2 id="第九章"><a class="anchor" href="#第九章">#</a> <strong>第九章:</strong></h2> <p><strong>在孤儿院里一场传染性的斑疹伤寒,夺走了许多孤儿的生命,海伦就在这场伤寒中死去,这对简・爱 打击很大。</strong></p> <hr /> <h2 id="第十章"><a class="anchor" href="#第十章">#</a> <strong>第十章:</strong></h2> <p><strong>斑疹伤寒使孤儿院有了大规模的改善。简在新的环境下接受了六年的教育,并在这所学校任教两年。由于谭波尔儿小姐的离开,简厌倦了孤儿院里的生活,登广告谋求家庭教师的职业。</strong></p> <hr /> <h2 id="第十一章"><a class="anchor" href="#第十一章">#</a> <strong>第十一章:</strong></h2> <p><strong>桑菲尔德庄园的女管家聘用了她。偌大的宅第只有一个不到 10 岁的女孩阿黛拉・瓦朗,罗切斯特先生是她的保护人,她是简爱的学生。简爱来到了桑费尔德庄园,那里的一切很庄严和气派。</strong></p> <hr /> <h2 id="第十二章"><a class="anchor" href="#第十二章">#</a> <strong>第十二章:</strong></h2> <p><strong>一天黄昏,简・爱外出散步,邂逅刚从国外归来的主人,这是他们第一次见面。罗切斯特从受惊的马上摔了下来,简急忙上前去扶他,回到家后简才知道他便是庄园主罗切斯特。</strong></p> <hr /> <h2 id="第十三章"><a class="anchor" href="#第十三章">#</a> <strong>第十三章:</strong></h2> <p><strong>阿黛尔很不容易教,不专心,处处找借口去寻找罗伯斯特先生。罗伯斯特先生与简爱面对面交流,了解简爱的过去,并对简爱的画做出评价。</strong></p> <hr /> <h2 id="第十四章"><a class="anchor" href="#第十四章">#</a> <strong>第十四章:</strong></h2> <p><strong>她发现她的主人是个性格忧郁、喜怒无常的人,对她的态度时好时坏。整幢房子沉郁空旷。</strong></p> <hr /> <h2 id="第十五章"><a class="anchor" href="#第十五章">#</a> <strong>第十五章:</strong></h2> <p><strong>夜里,简・爱简被一阵奇怪的笑声惊醒,发现罗切斯特的房门开着,床上着了火,她叫醒罗切斯特并扑灭火。罗切斯特告诉简・爱三楼住着一个女栽缝格雷斯・普尔,她神经错乱,时常发出令人毛骨悚然的狂笑声,并要她对此事严守秘密。</strong></p> <hr /> <h2 id="第十六章"><a class="anchor" href="#第十六章">#</a> <strong>第十六章:</strong></h2> <p><strong>简爱苦思冥想理不清头绪,胡乱猜测缘由,想见到罗伯斯特先生又盼不到他。第十七章:罗切斯特回来后经常举行家宴,桑费尔德庄园上上下下开始忙碌起来。在一次家宴上他向一位名叫英格拉姆的漂亮小姐大献殷勤,简被召进客厅,却受到布兰奇母女的冷遇,她忍受屈辱,离开客厅。</strong></p> <hr /> <h2 id="第十八章"><a class="anchor" href="#第十八章">#</a> <strong>第十八章:</strong></h2> <p><strong>在宴会上罗切斯特坚持要简・爱也到客厅里去,客人们对简・爱的态度十分傲慢,而罗切斯特却邀请简・爱跳舞,此时罗切斯特已爱上简,而简也感觉到自己对罗切斯特产生感情。</strong></p> <hr /> <h2 id="第十九章"><a class="anchor" href="#第十九章">#</a> <strong>第十九章:</strong></h2> <p><strong>罗切斯特外出,家里来了一个蒙着盖头的吉卜赛人。当轮到给简・爱算命时,简・爱发现这个神秘的吉卜赛人就是罗切斯特,他想借此试探简对他的感情。</strong></p> <hr /> <h2 id="第二十章"><a class="anchor" href="#第二十章">#</a> <strong>第二十章:</strong></h2> <p><strong>庄园里又来了个名梅森的陌生人,当晚他被三楼的神秘女人咬伤了,简帮罗切斯特把他秘密送走。</strong></p> <hr /> <h2 id="第二十一章"><a class="anchor" href="#第二十一章">#</a> <strong>第二十一章:</strong></h2> <p><strong>不久,里德太太派人来找简,说她病危要见简一面。回到舅母家中,里德太太给她一封信,这封信是三年前简的叔父寄来的,向她打听侄女的消息,并把自己的遗产交给简・爱。里德太太谎称简在孤儿院病死了,直到临终前才良心发现把真相告诉简。</strong></p> <hr /> <h2 id="第二十二章"><a class="anchor" href="#第二十二章">#</a> <strong>第二十二章:</strong></h2> <p><strong>简爱又回到桑费尔德庄园感觉像回到家一样。人们都在猜测罗切斯特会向布兰奇小姐求婚。</strong></p> <hr /> <h2 id="第二十三章"><a class="anchor" href="#第二十三章">#</a> <strong>第二十三章:</strong></h2> <p><strong>罗切斯特向简爱求爱,简爱答应了,心里充满了幸福感。</strong></p> <hr /> <h2 id="第二十四章"><a class="anchor" href="#第二十四章">#</a> <strong>第二十四章:</strong></h2> <p><strong>罗切斯特与简爱筹备婚礼。罗伯斯特很宠简爱,简爱视罗贝斯特为她的整个世界,他是简爱的偶像。</strong></p> <hr /> <h2 id="第二十五章"><a class="anchor" href="#第二十五章">#</a> <strong>第二十五章:</strong></h2> <p><strong>婚礼前夜,简・爱从梦中惊醒,看到一个身材高大、面目可憎的女人正在戴她的婚纱,然后把婚纱的面罩撕成碎片。罗切斯特告诉她那不过是一个梦,第二天当简醒来时发现婚纱的面罩真的成了碎片。</strong></p> <hr /> <h2 id="第二十六章"><a class="anchor" href="#第二十六章">#</a> <strong>第二十六章:</strong></h2> <p><strong>婚礼如期举行,一位不速之客闯进了教堂,声称婚礼不能进行,他说罗切斯特 15 年前娶梅森先生的妹妹伯莎・梅森为妻。罗切斯特承认了这一事实,并领人们看被关在三楼的疯女人,那就是他的合法妻子。她有遗传性精神病史,就是她在罗彻斯特的房间放火,也是她撕碎简婚纱的面罩。</strong></p> <hr /> <h2 id="第二十七章"><a class="anchor" href="#第二十七章">#</a> <strong>第二十七章:</strong></h2> <p><strong>简爱经历一场严峻的考验,法律阻碍了他们的爱情,使两人陷入深深的痛苦之中。</strong></p> <hr /> <h2 id="第二十八章"><a class="anchor" href="#第二十八章">#</a> <strong>第二十八章:</strong></h2> <p><strong>在一个凄风苦雨之夜,简・爱悲痛欲绝地离开了桑费尔德庄园。她仅有的积蓄花光后风餐露宿,沿途乞讨,历尽磨难,最后晕倒在牧师圣约翰家门前,被圣约翰和他的两个妹妹救了。</strong></p> <hr /> <h2 id="第二十九章"><a class="anchor" href="#第二十九章">#</a> <strong>第二十九章:</strong></h2> <p><strong>简爱睡了三天三夜,终于清醒了过来,在圣约翰家人的照料下,渐渐恢复体力。简・爱被圣约翰收留并为她谋了一个乡村教师的职位。</strong></p> <hr /> <h2 id="第三十章"><a class="anchor" href="#第三十章">#</a> <strong>第三十章:</strong></h2> <p><strong>简爱渐渐熟悉了这里的一切。不久,简得知叔父去世并给她留下一笔遗产,同时还发现圣・约翰是她的表兄,简决定将财产平分。</strong></p> <hr /> <h2 id="三十一章"><a class="anchor" href="#三十一章">#</a> <strong>三十一章:</strong></h2> <p><strong>一座山村农舍成了简的家,她有二十名学生,其中能识字的只有三个,能写和算的一个也没有。简的责任就是要培育这种萌芽。黄昏时,简边望着日落的景象,一边自我安慰,这时候,圣约翰・里弗斯来了,询问简对第一天工作的感觉。</strong></p> <hr /> <h2 id="三十二章"><a class="anchor" href="#三十二章">#</a> <strong>三十二章:</strong></h2> <p><strong>简爱全心全意忠实地做乡村女教师的工作,渐渐成了那一带乡亲们喜欢的人,那段日子,简爱表面上很平静,但常常在梦中遇到罗伯斯特先生,心里焦躁不安。</strong></p> <hr /> <h2 id="三十三章"><a class="anchor" href="#三十三章">#</a> <strong>三十三章:</strong></h2> <p><strong>圣约翰是个狂热的教徒,准备去印度传教,临行前向简・爱求婚,但他坦率地告诉她,他要娶她并不是因为爱她,而是他需要一个很有教养的助手。</strong></p> <hr /> <h2 id="三十四章"><a class="anchor" href="#三十四章">#</a> <strong>三十四章:</strong></h2> <p><strong>简・爱觉得应该报答他的恩情,但迟迟不肯答应他。当夜,圣约翰在荒原上等待简・爱的答复,就在简・爱要作出决定的时候,她仿佛听到罗彻斯特在遥远的地方呼喊她的名字......</strong></p> <hr /> <h2 id="三十五章"><a class="anchor" href="#三十五章">#</a> <strong>三十五章:</strong></h2> <p><strong>圣约翰非常自信简爱会追随他,并不断地做出各种努力帮助简爱尽快下定决心与他结婚。简爱在圣师的感召下差点失去了抗争的勇气,在那一刻,简爱又感受到内心有一种声音在不断地呼唤她,使简爱无法抗拒,简爱明白自己应该如何选择了。</strong></p> <hr /> <h2 id="三十六章"><a class="anchor" href="#三十六章">#</a> <strong>三十六章:</strong></h2> <p><strong>心灵有所感应的简爱赶回到桑菲尔德庄园,那座宅子已成废墟,得知疯女人放火后坠楼身亡,罗切斯特也受伤致残,孤独地生活在几英里外的一个农场里。</strong></p> <hr /> <h2 id="三十七章"><a class="anchor" href="#三十七章">#</a> <strong>三十七章:</strong></h2> <p><strong>简・爱终于找到了罗伯斯特先生并大受震动,和他结了婚,得到了自己理想的幸福生活。</strong></p> <hr /> <h2 id="三十八章"><a class="anchor" href="#三十八章">#</a> <strong>三十八章:</strong></h2> <p><strong>两年之后,罗切斯特治好了一只眼睛,他看到了简・爱为他生的第一个孩子。</strong></p> <h1 id="赏析"><a class="anchor" href="#赏析">#</a> <strong>赏析:</strong></h1> <p><strong>这是一部以爱情为主题的小说,主人公简・爱是一个心地善良,善于思考的女性,她生活在社会的最低层,受尽磨难。她的生活草鱼令人同情,但她那倔强的性格和勇于追求平等幸福的精神更令人人们所赞赏。</strong></p> <p><strong>在里德太太家,10 岁的简面对舅母,表兄的歧视和虐待,已经表现出强烈的反抗情绪。在她的表兄殴打她的时候,她勇于回击,当舅母叫自己的孩子远离她的时候,她个、高喊 “他们不配和我在一起”,当她被囚禁在空房中的时候,想到自己所受的虐待,从内心发出了 “不公正” 的呐喊。在孤儿院,简的反抗性格更为鲜明,这和她的朋友海伦・朋斯忍耐顺从的性格形成了鲜明的对比。海伦・朋斯虽然遭受迫害却信奉 “爱你的仇人”,在宗教的麻痹下,没有仇恨,只有逆来顺受。而简对冷酷的校长和摧残她们的教师深恶痛绝。她对海伦说:“如果她用那根条子打我,我要从她手中夺过来,并且当面折断它。” 这充分表露了她的不甘和不向命运妥协的倔强性格。</strong></p> <p><strong>小说主要描写了简・爱与罗契斯特的爱情。简・爱的爱情观更加深化了她的个性。他认为爱情应该建立在平等基础上,而不应该取决于社会地位,财富和外貌上。只有男女相方能彼此相爱,这样才能得到真正的爱情。在追求个人的幸福时,简・爱表现出了异乎寻常的纯真,朴实的思想感情和一往无前的勇气。她并没有因为自己的仆人地位而放弃对幸福的追求,她的爱情是纯洁高尚的,她对罗契斯特的财富不屑一顾。她之所以钟情于他,只是因为他能平等待人。把她视为朋友,与她坦诚相见。对罗契斯特来说,简・爱犹如一股清新的风,使他精神为之一振。罗契斯特过去看惯了上层社会的冷酷和虚伪,简・爱的纯朴,善良和独立的个性重新唤起他对生活的追求和向往。因而他能真诚地在简面前表达他的善良的愿望和改过的决心。简爱是一部具有浓厚浪漫现实主义小说,整部作品以自叙形式写成。大量运用了心理描写是小说的一大特色。全书构思精巧,情节波澜起伏,给读者制造出一种阴森恐怖的气氛,而又不脱离一个中产阶级家庭的背景。作者还以行情的笔法描写了主人公之间的真挚爱情和自然风情,感情色彩丰富而强烈。这部优美,动人并带有神秘色彩的小说,至今仍保持着它独特的艺术魅力。</strong></p>

2022/12/19
阅读更多

初中历史纪年表(超级完整)

<p><img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_1.jpeg" alt="Junior_High_School_History_Chronology_1" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_2.jpeg" alt="Junior_High_School_History_Chronology_2" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_3.jpeg" alt="Junior_High_School_History_Chronology_3" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_4.jpeg" alt="Junior_High_School_History_Chronology_4" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_5.jpeg" alt="Junior_High_School_History_Chronology_5" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_6.jpeg" alt="Junior_High_School_History_Chronology_6" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_7.jpeg" alt="Junior_High_School_History_Chronology_7" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_8.jpeg" alt="Junior_High_School_History_Chronology_8" /><br /> <img data-src="/image/Junior_High_School_History_Chronology/Junior_High_School_History_Chronology_9.jpeg" alt="Junior_High_School_History_Chronology_9" /><br /> <div class="links"><div class="item" title="jdjwzx233" style="--block-color:#e9546b;"><a href="/download/Junior High School History Chronology.zip" class="image" data-background-image="/image/other/62fe0d5d77bf2.png"></a> <div class="info"> <a href="/download/Junior High School History Chronology.zip" class="title">一键下载所有图片(ZIP)</a> <p class="desc">一键下载所有图片(ZIP)</p> </div></div></div></p> <div class="note warning"> <p>图片转载于<span class="exturl" data-url="aHR0cHM6Ly93d3cuZG9jaW4uY29tL3AtNjY5OTA5NDY4Lmh0bWw/ZG9jZnJvbT1ycmVsYQ==">初中历史大事年表 - 豆丁网 (docin.com)</span>,侵删。</p> </div>

2022/9/21
阅读更多

初中世界历史年代尺(大事年表)

<p><img data-src="/image/chronology_of_major_events/chronology_of_major_events_1.jpeg" alt="chronology_of_major_events_1" /><br /> <img data-src="/image/chronology_of_major_events/chronology_of_major_events_2.jpeg" alt="chronology_of_major_events_2" /><br /> <img data-src="/image/chronology_of_major_events/chronology_of_major_events_3.jpeg" alt="chronology_of_major_events_3" /><br /> <img data-src="/image/chronology_of_major_events/chronology_of_major_events_4.jpeg" alt="chronology_of_major_events_4" /><br /> <div class="links"><div class="item" title="jdjwzx233" style="--block-color:#e9546b;"><a href="/download/Junior high school world history chronology (chronology of major events).zip" class="image" data-background-image="/image/other/62fe0d5d77bf2.png"></a> <div class="info"> <a href="/download/Junior high school world history chronology (chronology of major events).zip" class="title">一键下载所有图片(7Z)</a> <p class="desc">一键下载所有图片(7Z)</p> </div></div></div></p> <div class="note warning"> <p>图片转载于<span class="exturl" data-url="aHR0cHM6Ly93d3cuZG9jaW4uY29tL3AtMjY2NjU4Nzc3Ni5odG1s"> (完整版) 初中世界历史年代尺 (大事年表) - 豆丁网 (docin.com)</span>,侵删。</p> </div>

2022/9/21
阅读更多

《聊斋志异》译文与赏析

<h1 id="卷一"><a class="anchor" href="#卷一">#</a> 卷一</h1> <h2 id="瞳人语"><a class="anchor" href="#瞳人语">#</a> 瞳人语</h2> <h3 id="译文转自-瞳人语_百度百科-baiducom"><a class="anchor" href="#译文转自-瞳人语_百度百科-baiducom">#</a> 译文 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTclOUUlQjMlRTQlQkElQkElRTglQUYlQUQvNjQwMDc3Mg=="> 瞳人语_百度百科 (baidu.com)</span>)</h3> <p>书生方栋,在长安城里很有点名气,但他为人很轻佻,不守礼节。每在郊外遇到游玩的女子,就很不礼貌地尾随在后头。</p> <p>清明节的前一天,他偶然到城郊游玩,见到一辆小车子,挂着朱红色的穸帘,周着绣花簇锦的车帷,几位女婢骑着马跟在车后。其中一个婢女,骑着匹小马,容貌美丽极了。方栋稍向前凑近,偷眼一看,见车的帷幔拉开着,车里坐着一位十五六岁的女郎,她妆梳非常艳丽,真是生平从未见到过。方栋目光缭乱,神志昏昏,跟在车的前前后后,舍不得离开,这样跟着走了好几里。忽听车中女郎把婢女叫到车边,说:“给我把帘子放下来。哪里来的这么一个狂妄书生,频频地来偷看。” 婢女把穸帘放下,回过头愤怒地看着方栋说:“这是芙蓉城里七郎的新娘回娘家,不是一个乡下女子,随便让秀才偷看的。” 说完,就从车道上抓起一把土,朝着方栋扬去。</p> <p>方栋眯眼睁不开,刚刚用手擦试眼睛,女郎的车马已经远去了。他惊恐疑惑地回到家里,总觉得眼睛里不舒服。请人扒开眼睑一看,眼球上生出了一层薄膜。过了一宿,越发严重,眼泪不止地簌簌流下来。白色的翳膜渐渐大起来,又过了几天,就像个铜钱那么厚。右边的那个眼球上,起了如同螺旋状的厚翳膜,用各种药物医治,都不见效。这时,方栋心中懊悔极了,很愧悔自己作法不当。他听说佛家的《光明经》能消除灾难,就手拿一卷,请别人教诵。最初,读时心情很烦躁,时间久了,渐渐地就习惯了。一天早晚无别的事可作,只盘腿坐着捻珠诵经。就这样他持续了一年,什么杂乱的念头也没有了。忽然,听到左边眼睛中,有如小蝇的声音,说:“黑如漆,真难受死了。” 右边眼睛中应声说:“可以一同出去游玩一会儿,出出这口闷气。” 方栋渐渐觉得两鼻孔中,蠕蠕动弹,很痒,好像有东西从鼻孔里面爬出来。过了一段时间,又返回来,又从鼻孔进到眼眶里。它们又说:“好长时间没能看看园中的亭台了,那珍珠兰快要枯死了。”</p> <p>方栋生平很喜欢兰花,园中种植了许多兰花,以前自己常去灌水,自从两眼失明,长久没再过问。忽然听到这话,急忙问他的妻子:“兰花怎么弄得快干死了?” 妻子问方栋怎么知道的,方栋就把实情告诉妻子。妻子到花园中一看,果然兰花枯萎了。妻子感到惊异,静静躲在屋里看个究竟,见有小人从方栋的鼻子中出来,大小不如一粒豆子,转转悠悠地竟到门外去了,越走越远,接着就看不清了。一会儿,两个小人又挎着胳膊回来,飞到方栋的脸上,好像蜜蜂和蚂蚁回窝一样。就这样倒腾了二三天。</p> <p>方栋又听左眼中小人说:“这条隧道弯弯曲曲,来来去去很是不方便,还不如自己另开一个门。” 右眼睛中小人说:“我这里的洞壁太厚,要开门不太容易。” 左边的说:“我来试试看,若能开开,咱俩就住到一块算了。” 方栋接着感到左眼眶内隐隐地痛似抓裂一样。一会,睁开眼一看,突然屋里的桌椅等物看得很清楚。方栋很高兴地告诉妻子。妻子仔细查看,左眼中那层小脂膜破开一个小孔,露出亮晶晶的黑色眼球,才有半个胡椒粒那么大。过了一宿,那层翳膜全消退了。细细一看,竟然是两个瞳人。而右眼厚厚的翳膜,仍是老样子,这才知两个瞳人合居在一个眼眶里了。方栋虽然瞎了一只眼睛,但比以前两个眼睛时看东西更清楚。自这以后,他对自己的行为,就更检点约束了,乡亲们都称赞他的品德好。</p> <p>异史氏说:乡里有个士人,和两个朋友一起出去,途中看见一个少妇骑着毛驴出现 在他前头。戏谑的说道:“有美人啊!” 回头看了看两个朋友说:“追她!” 三人于是笑着跟从。等到追上一看,是他的儿媳。心里很羞愧丧气,不再说话。朋友假装不知道,评头论足十分猥亵。士人很尴尬忸怩,支支吾吾的说:“这是我长子媳妇啊!” 于是各自偷笑而止。轻薄的人往往自取其辱,真是很可笑啊!至于双眼被迷失明,又是鬼神的惨痛报应啊。芙蓉城主,不知道是何处神祇,难道不是菩萨现身吗?眼睛里的小瞳人,应是劈开一个小门,犯了错误,鬼神纵然凶恶,又何尝不允许别人改过自新呢!</p> <h3 id="解析转自-聊聊斋谈谈心-之瞳人语-简书-jianshucom"><a class="anchor" href="#解析转自-聊聊斋谈谈心-之瞳人语-简书-jianshucom">#</a> 解析 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly93d3cuamlhbnNodS5jb20vcC9hMjY3ZTZhYWEyN2M="> 聊聊斋,谈谈心 之《瞳人语》 - 简书 (jianshu.com)</span>)</h3> <p>这个故事大概说的是方栋这个浪子生性喜欢调戏美人,本来窈窕淑女,君子好逑嘛,但是在清明前一天却调戏错了对象,调戏了芙蓉城七郎子新妇,被惩罚了双眼生翳,右眼还起旋螺瞎了,而左眼成了双瞳。从此方栋浪子回头,变老实了,不再玩火,不再好色了。</p> <p>中国封建时期,等级制度特别讲究三纲五常,而三纲是指 “君为臣纲”、“父为子纲”、“夫为妻纲”。侍君如侍父,同样弑君如弑父,古时会经常称地方官为父母官,这就意味着君与臣、官与民之间是存在和父与子之间的一样的乱伦禁忌。就像文中那婢说 “此芙蓉城七郎子新妇归宁,非同田舍娘子,放教秀才胡觑!(这是芙蓉城主七儿子新娶的老婆回娘家,不是普通的村姑,你这穷秀才瞅啥!)”。且不说芙蓉城主是何方神仙,城主本来就是一城的父母官,父母官的儿媳妇当然是不能乱瞅的,不像村姑那样可以随便被调戏。方栋要受到的惩戒不是一般的长针眼,而要长翳,甚至起旋螺瞎了。但这也幸亏方栋只是用眼来 “欣赏”,没有上升到言语上的挑逗,才不会在清明时节丢了性命到地狱里受罚。</p> <p>古时的男性在俄底浦斯期都很难过得好,因为古时男性在俄期要处理的依然是二元关系,只是从之前的母子关系转移到了父子关系,而不是真正处理孩子、爸爸、妈妈的三元关系,这就会造成了古时男性面对女性时,总是在有着面对自己对妈妈的渴望,只要敢有任何猥琐的想法,内心会受到无意识中的古时乱伦禁忌惩罚。就好像文中方栋敢去窥视城主的儿媳妇,受到的惩罚是眼睛不能乱瞅,在方栋痛定思痛之后,左眼在意象中是象征着和爸爸的关系,变成了双瞳,意味着更加看清楚和遵守父性的权威,整个人变得更老实了,而右眼在意象中会是象征和妈妈的关系,起旋螺,变瞎了,意味着自己内心对于妈妈的任何企图都只能放在心深处,把兴趣转移到了自己的 “后花园”—— 妻子身上。</p> <p>不过,古人还是知道事情不能做得太绝了,老爸不能去抢儿子女人,一来显得太低能了,要去和儿子抢吃的,二来免得把儿子逼上绝路,儿子会造反的,就像文后的士人看到美人是自己的 “长男妇”,就变得垂头丧气。同时古时男性特别是有些文化的人,其实是有一定身份的人了,会在外面表现出风流成性,放荡不羁是时尚,他们是可以去调戏一下村姑或者青楼女子,满足或者发泄自己内心的性冲动,但却不敢真正去追求女性,更别说敢去接触父母官家里的女人,而婚姻永远是 “父母之命,媒妁之言”,自己能拥有的老婆只能是父母认可的。</p> <p>在精神分析当中会称乱伦禁忌或者冲动为俄底浦斯情结,翻译成大白话就是儿子要把爸爸干掉,就是为了抢老爸的女人,也就是妈妈来满足自己需求。当然这事情往往是不能成功的,儿子最终只能清醒地意识到,妈妈永远只能是爸爸的女人,是自己的妈妈,自己可以拥有真正属于自己的女人是需要在外面找,从而把自己的目光转移到了别的女人身上来满足自己性需求或者自己战胜了爸爸的幻想。</p> <p>但如果妈妈和儿子的连接太紧密的话,也就是儿子太过粘妈妈的话,儿子在俄期发现自己无法和爸爸抗衡后只是从这竞争关系中表面地撤退,但不代表儿子会放弃妈妈可以是自己女人的想法。儿子会无意识地不断去寻找不同女性,或者在别的女人身上寻找妈妈的影子,把别的女人当成自己妈妈来对待要求,或者用各种各样的方式继续待在妈妈身边和妈妈保持连接比如长大了依然待在家里啃老之类,这样只会对孩子的成长带来不利的影响,一直陷在了过去情结当中,无法走出来拥有自己的真正人生。</p> <h2 id="王六郎"><a class="anchor" href="#王六郎">#</a> 王六郎</h2> <h3 id="译文转自-王六郎清代蒲松龄创作的文言短篇小说_百度百科-baiducom"><a class="anchor" href="#译文转自-王六郎清代蒲松龄创作的文言短篇小说_百度百科-baiducom">#</a> 译文 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTclOEUlOEIlRTUlODUlQUQlRTklODMlOEUvNjM5ODY3OQ=="> 王六郎(清代蒲松龄创作的文言短篇小说)_百度百科 (baidu.com)</span>)</h3> <p>有个姓许的,家住淄川县城北,以打鱼为生。他每天傍晚总要带酒到河边去,边喝酒边打鱼。而喝酒前,又总是先斟上一盅祭奠一下,并祷告说:“河中的溺鬼,请来喝酒吧!” 这样便习以为常。其他人往往打鱼很少,而他每天都打满筐的鱼。一天傍晚,许某刚刚独自饮酒,见一少年走来,在他身边转来转去。许某让他同饮,少年也不推辞,二人便对饮起来。这一夜竟连一条鱼也未能打到,许某很有些丧气。少年起立躬身说:“我到下游为你赶鱼。” 说罢,朝下游飘然走去。一会儿,少年回来说:“大群鱼来了!” 果然听到有许多鱼吞吃饵食的声音。许某便撒网,一网捕了十数尾尺把长的大鱼。他非常高兴,对少年深表感谢。少年欲走,许送鱼给他,少年不要,并说:“屡次喝你的好酒,这点小事怎能提到感谢呢?如您不嫌麻烦,我将常来找您。” 许某说:“才相见一晚,怎说多次?你如愿来相助,我是求之不得,可我怎样报答你的情意呢?” 于是便问少年姓名。少年说:“我姓王,没有名字,你见面就叫我王六郎吧。” 说罢,便告辞而去。次日,许某将鱼卖掉,顺便多买了些酒。当晚,许某来到河边时,六郎早已先在等候,二人便开怀畅饮。饮几杯后,六郎便为许某赶鱼。</p> <p>就这样半年过去了。一天,六郎忽然对许说:“你我相识,情同手足,可是,咱们马上就要分别了。” 说得很是悲伤。许某甚为诧异,问六郎为何这样,六郎考虑再三,才说:“你我既然亲如兄弟,我说了你也不必惊讶。如今将要分别,无妨如实告知:我实际是一鬼,只因生前饮酒过量,醉后溺水而死,已经好几年了。以前你之所以捕到比别人更多的鱼,都是我暗中帮你驱赶,以此来酬谢奠酒之情。明 日我的期限已满,将有人来代替我,我将要投生于人间,你我相聚只有今晚了,所以我不能平静。” 许某听了起初十分害怕,然而,因为长期相处,不再恐怖,反而难过起来。于是,他满满斟了一杯酒捧在手中说:“六郎,我敬你这杯酒!望你饮了不要难过。你我从此不能相见,虽很伤心,但你由此解脱灾难,我应该祝贺你。不要悲伤,应该高兴才是!” 于是,二人继续畅饮。许问六郎:“何人来相替?” 六郎说:“兄长明 日可在河边阴处等候,正当午时,有一女子渡河,溺水而死,即是替我之人。” 二人听到村鸡鸣叫,方洒泪而别。次日,许在河边暗暗观看,会发生什么事情。中午时,果有一怀抱婴儿的妇女,到河边便坠入水中。婴儿被抛在岸上,举手蹬脚地啼哭。妇女几次浮上沉下,后竟又水淋淋地爬上河岸,坐在地上稍稍休息后,抱起婴儿走了。当许某看到妇女掉入水中时,很不忍心,想去相救,但一想这是六郎的替身,才打消救人的念头。当又看到妇人未溺死,心中怀疑六郎所言有些荒唐。当晚,许某仍到原地去打鱼,而六郎早已在那里,说:“如今又相聚了,可暂先不说分别的事。” 许某问六郎白天的事,六郎说:“本来那女子是替我的,但我怜她怀中婴儿,不忍心为了自己一人而伤两个人的性命。因此,我决定舍弃这个机会,但又不知何时再有替死的人。也许是你我缘分未尽啊。” 许某慨叹地说:“你这种仁慈之心,总可感动玉帝的。” 从此,二人一如既往,饮酒捕鱼。过了几天,六郎又来向许某告别,许以为又有替六郎之人。六郎说:“不是的,我前次之好心果然感动了玉帝,因而招我为招远县邬镇的土地神。明日要去赴任,如你不忘咱俩的交情,不要嫌路远,去招远看我。” 许某祝贺说:“贤弟行为正直而做了神,我感到十分欣慰。但人和神之间相隔遥远,即使我不怕路远,又怎样才能见到你呢?” 六郎说:“只管前往,不要顾虑。” 再三嘱咐而去。</p> <p>许某回到家,便要置办行装东下招远。他妻子笑着说:“这一去几百里路,即使有这个地方,恐怕和一个泥塑偶像也无法交谈。” 许某不听,终究去了招远。问当地居民,果然有个邬镇。他找到了邬镇,便住进一个客店,向主人打听土地祠在什么地方。主人惊异地说:“客人莫非姓许?” 许某说:“是的,但是您怎么知道?” 店主人又问:“客人莫非是淄川人?” 许某说:“是的,然则您又是怎么知道的?” 店主人并不回答,很快地走出去。过了一会,只见丈夫抱着小儿,大姑娘小媳妇在门外偷看,村里人纷纷到来,围看许某,如四面围墙一般。许某更为惊异。大家告诉他说:“前几夜,梦见神人来告知:有一个淄川姓许的人将来此地,可以给些资助。因而在此等候多时。” 许某甚为奇怪,便到土地祠祭祀六郎,祷告说:“自从与你分别后,睡梦中都铭记在心,为此远道而来赴昔日之约。又蒙你托梦告知村里人,心中十分感谢。很惭愧我没有厚礼可赠,只有一杯薄酒,如不嫌弃,当如过去在河边那样对饮一番。” 祷告毕,又烧了些纸钱。顷刻见到一阵旋风起于神座之后,旋转许久才散去。当夜,许某梦到六郎来到,衣冠楚楚的,与过去大不相同。六郎致谢道:“有劳你远道而来看望我,使我又欢喜又悲伤。但我如今有职务在身,不便与你相会,近在咫尺,却如远隔山河,心中十分凄怆。村中人有微薄的礼物相赠,就算代我酬谢一下旧日的好友。当你回去的时候,我必来相送。” 许某住了几天,打算回家,大家殷勤挽留,每天早晚都轮流作东道主为许某饯行。许坚决告辞,村中人争着送来许多礼物,为他充实行装。不到一天,送的礼物装满行囊,男女老少都聚集来送许出村。忽然刮起一阵旋风,跟随许某十馀里路。许对着旋风再拜说:“六郎珍重,不要远送了。你心怀仁爱,自然能为一方百姓造福,无需老朋友嘱咐了。” 旋风又盘旋许久,才离去。村中的人也都嗟叹着返回了。许某回到家里,家境稍稍宽裕些,便不再打鱼了。后来见到招远的人,向他们打听土地的情况,据说灵验得像传说的那样,远近闻名。</p> <p>异史氏说:“王六郎身在青云之中当神,还不忘记贫贱时的朋友,这就是他所以神异的原因。今 日坐在车里面的显贵,难道还认识那个戴着斗笠的人吗?我的乡里有一个退休了的人,家里非常贫穷。他有一个年小的时候就交往的朋友,如今做了显贵。他想要是投奔他去一定会得到周济照顾。于是竭尽全力置办行装,奔波了上千里路,结果非常失望的回来;他花光了行囊里所有的钱财并卖掉了坐骑,才能够回来。他的族弟是个很诙谐的人,作了一首《月令》来嘲讽这件事说:‘这个月,哥哥回来了,貂皮帽子也解下来了,车马伞盖也没有张开来,马也变成驴了,靴子这才没了声音。’念一下这个可以笑一笑。”</p> <h3 id="解析转自-王六郎人物分析主题现实意义高中语文聊斋_百度知道-baiducom"><a class="anchor" href="#解析转自-王六郎人物分析主题现实意义高中语文聊斋_百度知道-baiducom">#</a> 解析 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly96aGlkYW8uYmFpZHUuY29tL3F1ZXN0aW9uLzUzMTE1OTQyMi5odG1s"> 王六郎人物分析,主题,现实意义,高中语文,聊斋_百度知道 (baidu.com)</span>)</h3> <h4 id="人物分析"><a class="anchor" href="#人物分析">#</a> 人物分析:</h4> <p>因为渔夫经常 “饮则酹地”。所以王六郎要报答渔夫,使得 “他人渔,迄无所获,而许独满筐”。表现了他的知恩图报,重情义的性格特点。</p> <p>集中体现在王六郎放弃妇人代死这一部分。“果有妇人抱婴儿来,及河而堕。儿抛岸上,扬手掷足而啼。妇沉浮者屡矣,忽淋淋攀岸以出,藉地少息,抱儿径去。”</p> <p>在亭午时分,一名妇人怀抱婴儿前来,行至河畔,旋即失足坠入河中,在该妇人载沉载浮的奋力挣扎中,伴随着河岸幼儿扬手掷足的高声哭啼。结果是妇人没有沉下去,而是 “忽淋淋攀岸以出”,抱着儿子回去了。</p> <p>当晚,二人照常来到河边聚会。渔夫向他询问了这件怪事。王六郎回答说:“女子已相代矣;仆怜其抱中儿,代弟一人遂残二命,故舍之。” 作为一个溺死鬼,当有人做替身时,自己本可以投胎复生,重新做人,然而在这 “生死攸关”,他却甘愿放弃这个机会,而是把机会让给更需要生命的人 —— 手抱婴儿的妇女。这个故事的寓意是:人和鬼之间,只要讲诚信,也可以成为知己;</p> <h4 id="主题"><a class="anchor" href="#主题">#</a> 主题:</h4> <h5 id="知恩图报有情有义"><a class="anchor" href="#知恩图报有情有义">#</a> 知恩图报,有情有义。</h5> <h5 id="舍己救人-善良高尚"><a class="anchor" href="#舍己救人-善良高尚">#</a> 舍己救人、善良高尚。</h5> <h4 id="现实意义"><a class="anchor" href="#现实意义">#</a> 现实意义:</h4> <p>人和人之间,也应该注重诚信。</p> <h2 id="种梨"><a class="anchor" href="#种梨">#</a> 种梨</h2> <h3 id="译文转自-种梨清代小说家蒲松龄创作的文言短篇小说_百度百科-baiducom"><a class="anchor" href="#译文转自-种梨清代小说家蒲松龄创作的文言短篇小说_百度百科-baiducom">#</a> 译文 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTclQTclOEQlRTYlQTIlQTgvNzY1NjM2MQ=="> 种梨(清代小说家蒲松龄创作的文言短篇小说)_百度百科 (baidu.com)</span>)</h3> <p>有个乡下人,在集市上卖梨。梨的味道非常香甜,但价钱很贵。有个道士,戴着破道士帽,穿着破烂道袍,在车前伸手向乡下人乞讨。乡下人呵斥他,他也不走。乡下人生气了,大声地辱骂起来。道士说:“你这一车梨有好几百个,贫道只讨你一个,对你来说没多大损失,为什么还要发这么大的脾气呢?” 观看的人劝乡下人拿一个不好的梨给老道士,打发他走算了,乡下人坚决不肯。</p> <p>路旁店铺里的一个伙计,见他们吵得不成样子,就拿出钱买了一个梨,给了道士。道士拜谢,然后对着众人说:“出家人不知道吝惜东西。我有好梨,请大家品尝。” 有人问:“你既然有梨,为什么不吃自己的?” 道士说:“我是需要这个梨核做种子。” 于是捧着梨大口大口地吃了起来。道士吃完梨,把核放在手里,取下背在肩上的小铁铲,在地上挖了个几寸深的坑,然后放进梨核,盖上土,向旁边的人要点热水浇灌。有好事的人便到路边店铺中提来一壶滚开的水,道士接过开水浇进了坑里。大家都瞪着眼看着,见一棵嫩芽儿冒了出来,并渐渐长大,一会儿就长成了一棵枝繁叶茂的大树;转眼间开花、结果,又大又香的梨子挂满了枝头。道士从树上摘下梨子,分给围观的人吃,一会儿功夫就吃光了。然后,道士就用铁铲砍树,叮叮当当地砍了好长时间方才砍断。道士把满带枝叶的梨树扛在肩上,不慌不忙地走了。</p> <p>一开始,道士做戏法时,那个乡下人也杂在人群中,伸着脖子瞪着眼看,竟忘记了自己的营生。道士走了以后,他才回来去看顾他车上的梨,却已经一个也没有了。他这才恍然大悟,道士刚才分的梨子都是他的;再细细一看,一根车把没有了,碴口是新砍断的。乡下人心里非常气愤,急忙去追赶道士。转过一个墙角,见砍断的车把扔在墙角下,这才知道道士刚才砍的那棵梨树,就是他的车把,而道士却已经不知去向了。满集市上的人都笑得合不上嘴。</p> <p><span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTUlQkMlODIlRTUlOEYlQjIlRTYlQjAlOEYvNTAzNDg0Ng==">异史氏</span>评论:“乡人烦闷昏庸的样子,憨状可掬,十分痴傻,他受市人嘲笑,也是有道理的。我每每见到乡中富人,至亲好友向他乞米求助,就表现出一副气愤的样子,就计较说:‘(这)是好几天的物资开支了。’ 如果劝他救济危难的人,给孤独无靠的人饭吃,则又忿然,又计较说:‘这是十个人、五个人的饭量。’ 甚至连父子兄弟,也极微细的钱财也要彻底计较。(但是)一旦关乎荒淫烂赌,则整个囊袋家产也不吝啬;刀锯架在头颈上,连赎命也来不及。诸如此类的事,正是说之不尽;而(相对而言)愚蠢的乡下人的做法,又有什么值得奇怪的呢?”</p> <h3 id="赏析转自-种梨清代小说家蒲松龄创作的文言短篇小说_百度百科-baiducom"><a class="anchor" href="#赏析转自-种梨清代小说家蒲松龄创作的文言短篇小说_百度百科-baiducom">#</a> 赏析 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTclQTclOEQlRTYlQTIlQTgvNzY1NjM2MQ=="> 种梨(清代小说家蒲松龄创作的文言短篇小说)_百度百科 (baidu.com)</span>)</h3> <p>《种梨》所讲的故事只是一个风趣剧,轻松而幽默。说的是一个村夫在集市上卖梨,而一个道人万端乞讨而不得。其间一个伙计实在看不下去了,就买了一个送给道人,没想到道人吃毕,把核种于地下,霎时间便生芽、发展、开花、结果,于是道人遍送观者。而村夫待道人走后发现本身的一车梨已经子虚乌有,才突然觉悟大悟。然而,蒲松龄先生却在评价中说道:&quot;良友…… 父子兄弟,较尽锱铢。及至淫博迷心,则顷囊不吝;刀锯临颈,则赎命不遑。诸如此类,正不胜道……&quot; 其极重繁重和愤慨,使人足见先生对吝啬者之恨了。</p> <h2 id="劳山道士"><a class="anchor" href="#劳山道士">#</a> 劳山道士</h2> <h3 id="译文转自-崂山道士聊斋志异篇目_百度百科-baiducom"><a class="anchor" href="#译文转自-崂山道士聊斋志异篇目_百度百科-baiducom">#</a> 译文 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTUlQjQlODIlRTUlQjElQjElRTklODElOTMlRTUlQTMlQUIvMTYyNDg="> 崂山道士(《聊斋志异》篇目)_百度百科 (baidu.com)</span>)</h3> <p>县里有个姓王的书生,排行第七,是官宦之家的子弟,从小就羡慕道术。他听说崂山上仙人很多,就背上行李,前去寻仙访道。他登上一座山顶,看见一所道观,环境非常幽静。有一个<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTklODElOTMlRTUlQTMlQUIvMTU4MzM3NjE=">道士</span>坐在蒲团上,白头发垂到脖颈上,神情相貌清爽高超。王生上前见过礼并与他交谈起来,觉得道士讲的道理非常玄妙。便请求道士收他为徒,<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTklODElOTMlRTUlQTMlQUIvMTU4MzM3NjE=">道士</span>说:“恐怕你娇气懒惰惯了,不能吃苦。” 王生回答说:“我能吃苦。” 道士的徒弟很多,傍晚的时候都集拢来了。王生一一向他们行过见面礼,就留在道观中。</p> <p>第二天凌晨,<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTklODElOTMlRTUlQTMlQUIvMTU4MzM3NjE=">道士</span>把王生叫去,交给他一把斧头,让他随众道徒一起去砍柴。王生恭恭敬敬地答应了。过了一个月,王生的手脚都磨出了厚厚的老茧,他再也忍受不了这样的苦累,暗暗产生了回家的念头。</p> <p>有一天傍晚,他回到观里,看见两个客人与师傅共坐饮酒。天已经晚了,还没有点上蜡烛。师傅就剪了一张像镜子形状的纸,贴在墙上。一会儿,那纸变成一轮明月照亮室内,光芒四射。各位弟子都在周围奔走侍候一个客人说:“良宵美景,其乐无穷,不能不共同享受。” 于是,从桌上拿起酒壶,把酒分赏给众弟子,并且嘱咐可以尽情地畅饮。王生心里想,七八个人,一壶酒怎么能够喝?于是,各人寻杯觅碗,争先抢喝,惟恐壶里的酒干了。然而众人往来不断地倒,那壶里的酒竟一点儿也不少。王生心里非常纳闷。过了一会儿,一个客人说:“承蒙赐给我们月光来照明,但这样饮酒还是有些寂寞,为什么不叫嫦娥来呢?” 于是就把筷子向月亮中扔去。只见一个美女,从月光中飘出,起初不到一尺,等落到地上,便和平常人一样了。她扭动纤细的腰身、秀美的颈项,翩翩地跳起 “霓裳舞”。接着唱道:“神仙啊,你回到人间,而为什么把我幽禁在广寒宫!” 那歌声清脆悠扬,美妙如同吹奏箫管。唱完歌后,盘旋着飘然而起,跳到了桌子上,大家惊奇地观望之间,已还原为筷子。师傅与两位客人开怀大笑。又一位客人说:“今晚最高兴了,然而我已经快喝醉了,二位陪伴我到月宫里喝杯饯行酒好吗?” 于是三人移动席位,渐渐进入月宫中。众弟子仰望三个人,坐在月宫中饮酒,胡须眉毛全都看得清清楚楚,就像人照在镜子里的影子一样。过了一会儿,月亮的光渐渐暗淡下来,弟子点上蜡烛来,只见道士独自坐在那里,而客人已不知去向。桌子上菜肴果核还残存在那里。那墙上的月亮,只不过是一张像镜子一样的圆的纸罢了。道士问众弟子:“喝够了吗?” 大家回答说:“够了。” 道士说:“喝够了就早去睡觉,不要耽误了明天打柴。” 众弟子答应着退了出去。王生心里惊喜羡慕,回家的念头随即打消了。</p> <p>又过了一个月,王生实在忍受不了这种苦累,而道士还是连一个法术也不传授,他心里实在憋不住,就向道士辞行说:“弟子不远数百里来拜仙师学习,即使不能得到长生不老的法术,若能学习点小法术,也可安慰我求教的心情。如今过了两三个月,不过早上出去打柴,晚上回来睡觉。弟子在家中,从没吃过这种苦。” 道士笑着说:“我本来就说你不能吃苦,现果然如此。明天早晨就送你回去。” 王生说:“弟子在这里劳作了多日,请师傅稍微教我一点儿小法术,我这次来也算没白跑一趟。” 道士问:“你要求学点什么法术?王生说:“平常我见师傅所到之处,墙壁也不能阻挡,只要能学到这个法术,我就知足了。” 道士笑着答应了。于是就传授他秘诀,让他自己念完了,道士大声说:“进墙去!王生面对着墙不敢进去。道士又说:“你试着往里走。” 王生就从容地向前走,到了墙跟前,被墙挡住。道士说:“低头猛进,不要犹豫!” 王生果然离开墙数步,奔跑着冲过去,过墙时,像空虚无物;回头一看,身子果然在墙外了。王生非常高兴,回去拜谢了师傅。道士说:“回去后要洁持自爱,否则法术就不灵验。” 于是就给他些路费,打发他回去了。</p> <p>王生回到家里,自己夸耀遇到了仙道,坚固的墙壁也不能阻挡他。他的妻子不相信。王生便仿效起那天的一举一动,离墙数尺,奔跑着冲去,头撞到坚硬的墙上,猛然跌倒在地。妻子扶起他来一看,额头上鼓起大包,像个大鸡蛋一样。妻子讥笑他,王生又惭愧又气愤,骂老道士没安好心。</p> <p>异史氏说:听说王生这个故事的人没有不大笑的,殊不知世上的 “王生” 还真不少。现在有那么一个匹夫,喜欢别人阿谀奉承不喜欢忠言劝谏,于是那些阿谀迎奉的小人就呈上那些可以逞威扬暴的伎俩,来迎合他,并骗他说:靠着这个本事,就可以横行无阻了。一开始试验都小有灵验,于是就说天下之大,都可以像这样横行,真是一个不碰南墙不回头的人啊!</p> <h3 id="赏析转自-小说-戏剧崂山道士原文与赏析-中外经典-品诗文网-pinshiwencom"><a class="anchor" href="#赏析转自-小说-戏剧崂山道士原文与赏析-中外经典-品诗文网-pinshiwencom">#</a> 赏析 (转自 ---<span class="exturl" data-url="aHR0cHM6Ly93d3cucGluc2hpd2VuLmNvbS93YWl3ZW4vendqZC8yMDE5MDcyMDE1NDYyOS5odG1s">《小说、戏剧・崂山道士》原文与赏析 - 中外经典 - 品诗文网 (pinshiwen.com)</span>)</h3> <p>这篇小说以简洁轻快的笔调刻画出一位畏难怕苦,不求真知;浅尝辄止,轻浮健忘,学到一点皮毛就自炫自夸的王生。其结果只落得头撞南墙,一事无成,唯有头上的肿疱而已。王生的形象愈鲜明逼真,作品的讽刺意味也愈隽永深长。从而使形象的生动性和主题的深刻性,得到和谐的统一。</p> <p>《崂山道士》喜趣横生,极富艺术魅力,其成功的艺术经验有四:其一,从发展中显现人物自身的矛盾。凡古今引人入胜,而耐人寻味的佳作,几乎无例外地都是再现矛盾的艺术。可以说,艺术的魅力首先是矛盾的魅力,蒲松龄的高明在于他正是矛盾的发现者、把握者和再现者。《崂山道士》情节的喜剧性来自人物的悲剧性格。王生既想学道,又不肯吃苦;既想虔诚敬道,又不肯接道长的要求去做;既想炫耀自己,又无真本事;既想讨妻子的赞赏,又无自知之明。这样小说便从王生的主观意愿和实际能力大相径庭的矛盾中,透过一定事件的考验展现出人物的个性特征,使人物形象立体化,更加有血有肉。由此可见,审美对象也包括丑,它一经审美主体的把握,例如这篇讽刺小说对于客观存在的丑的把握,也就创造了对丑的反映的艺术美。</p> <p>其二,小说委婉有致地写出人物在不同情境下的各种心态。因王生自幼慕道,所以他赴数百里之外求师学道。当他刚到劳山时,见观宇 “甚幽”,道士 “神光爽迈”,便毅然拜师学道。但他从来未想过学道要付出艰辛的代价,足见王生无知。仅一个多月早出晚归的劳作他便打熬不住转念回家了,王生的心志不坚,自然不言而喻。一旦目睹了道士的真本领又想留下来,恨不得一吃成胖子,其好高鹜远的虚荣心又得以充分展现。再过上一个多月的劳苦生活,旧态复萌,又不想干了,临走前道士教以小技便心满意足了,只要装点、不求真知的浅薄心理昭然若揭。回家后,面对不懂道术的妻子,又是自我吹嘘,又是急不可待地当场表演,欺世盗名的心态和盘托出。如此,层次井然地揭示出王生在不同情境中的内在丑,从而使人物个性渐趋鲜明,作品的立意也愈加深刻。</p> <p>其三,巧用漫画式的夸张手法。作者准确地把握了王生在妻子面前表演时踌躇满志的心态,神形兼备地予以适度的夸张,王生碰壁后额上 “巨卵” 格外醒目,寥寥数笔极尽揶揄嘲讽之能事,不但渲染了喜剧气氛,而且使这位玩弄小术的王生自食其果。作品的讽刺效果也就自然而微妙地得以发挥,这正是作者炉火纯青的艺术功力所致。</p> <p>其四,寓深刻的哲理性于轻松的笑声之中。《崂山道士》既是讽刺小说,也是寓言故事。它具有亦庄亦谐,寓庄于谐的特点,饶有丰富的哲理性内蕴。王生既是一个具有独特性格的艺术形象,又是生活中随处可见的众生相,他那种自我吹嘘而又不自量的性格特征,必然导致碰壁的悲剧,正像篇末异史氏所言,“闻此事未有不笑者,而不知世之王生者正复不少。” 作者旨在借王生嘲讽世上所有王生的同类。古罗马贺拉修斯在他的名著 《诗艺》中说得好: “寓教于乐,既劝谕读者,又使他喜爱。”“教” 也就是某种哲理,其所以引起快感,启迪智慧,给人益处和乐趣,同时又对生活有帮助,正因为美是一种善。</p>

2022/8/23
阅读更多

《聊斋志异》简介及读后感

<h1 id="聊斋志异简介及读后感"><a class="anchor" href="#聊斋志异简介及读后感">#</a> 《聊斋志异》简介及读后感</h1> <h2 id="一-聊斋志异简介"><a class="anchor" href="#一-聊斋志异简介">#</a> <strong>一、《聊斋志异》简介</strong></h2> <p>《聊斋志异》是蒲松龄的代表作,在他 40 岁左右已基本完成,此后不断有所增补和修改。&quot;聊斋&quot; 是他的书屋名称,&quot;志&quot; 是记述的意思,&quot;异&quot; 指奇异的故事。全书有短篇小说 491 篇。题材非常广泛,内容极其丰富。多数作品通过谈狐说鬼的手法,对当时社会的腐败、黑暗进行了有力批判,在一定程度上揭露了社会矛盾,表达了人民的愿望。但其中也夹杂着一些封建伦理观念和因果报应的宿命论思想。《聊斋志异》的艺术成就很高。它成功的塑造了众多的艺术典型,人物形象鲜明生动,故事情节曲折离奇,结构布局严谨巧妙,文笔简练,描写细腻,堪称中国古典短篇小说的高峰。</p> <p>《聊斋志异》,是一部文言短篇小说集。有传奇、志怪、轶事等,诸体兼备,为中国文言小说集大成之作。内容十分广泛,多谈狐、魔、花、妖,以此来概括当时的社会关系,反映了 17 世纪中国的社会面貌。书中写的是一个花妖鬼狐的世界,既有对如漆墨黑的社会现实的不满,又有对怀才不遇、仕途难攀的不平;既有对贪宫污吏狼狈为奸的鞭笞,又有对勇于反抗,敢于复仇的平民的称赞;而数量最多、质量上乘、写得最美最动人的是那些人与狐妖、人与鬼神以及人与人之间的纯真爱情的篇章。</p> <p>《聊斋志异》是一部具有独特思想风貌和艺术风貌的文言短篇小说集。多数小说是通过幻想的形式谈狐说鬼,但内容却深深地扎根于现实生活的土壤之中,曲折地反映了蒲松龄所生活的时代的社会矛盾和人民的思想愿望,熔铸进了作家对生活的独特的感受和认识。</p> <h2 id="二-从题材内容来看聊斋志异中的作品大致可分为以下五类"><a class="anchor" href="#二-从题材内容来看聊斋志异中的作品大致可分为以下五类">#</a> <strong>二、从题材内容来看《聊斋志异》中的作品大致可分为以下五类:</strong></h2> <p>第一类,是反映社会黑暗,揭露和抨击封建统治阶级压迫、残害人民罪行的作品,如《促织》、《红玉》、《梦狼》、《梅女》、《续黄粱》、《窦氏》等;<br /> 第二类,是反对封建婚姻,批判封建礼教,歌颂青年男女纯真的爱情和争取自由幸福而斗争的作品,如《婴宁》、《青凤》、《阿绣》、《连城》、《青娥》、《鸦头》、《瑞云》等;<br /> 第三类,是揭露和批判科举考试制度的腐败和种种弊端的作品,如《叶生》、《于去恶》、《考弊司》、《贾奉雉》、《司文郎》、《王子安》、《三生》等;<br /> 第四类,是歌颂被压迫人民反抗斗争精神的作品,如《商三官》、《席方平》、《向杲》等;第五类,总结生活中的经验教训,教育人要诚实、乐于助人、吃苦耐劳、知过能改等等,带有道德训诫意义的作品,如《种梨》、《画皮》、《劳山道士》、《瞳人语》、《狼》三则等。</p> <p>《聊斋志异》在进步的思想内容中也夹杂着一些落后的成分,如封建伦理道德观念,鬼神迷信和因果报应思想,追求功名利禄的庸俗倾向等,是我们阅读时应注意分析批判的。</p> <p>郭沫若评价说:&quot;写鬼写妖高人一筹,刺贫刺虐入木三分&quot;</p> <h2 id="三-聊斋中的女性大致可分为四类"><a class="anchor" href="#三-聊斋中的女性大致可分为四类">#</a> 三、 <strong>《聊斋》中的女性大致可分为四类</strong></h2> <p><strong>第一类,是为数最多的勇于追求爱情,对爱情忠贞不渝的忠女,烈女,豪放女们</strong> 。</p> <p>如《青凤》,《婴宁》、《莲香》,《聂小倩》等。</p> <p>《青凤》:女主人公青凤是一狐女,如其他聊斋女性一样 &quot;世间无其丽&quot;,在与耿生相恋之初,她谨听叔训,&quot;不敢奉命&quot;。经过几番挣扎和几年痛苦的思念,在与耿生的一次意外相遇中,毅然决定离开家人的束缚与耿生共结连理。<br /> <strong>第二类,利用智慧战胜邪恶,为家人报仇,为民除害的复仇女神。</strong></p> <p>如《商三官》,《庚娘》,《云翠仙》等。</p> <p>《商三官》商三官是一个聪明美丽、有见识的女孩子。她的父亲商士禹因得罪地主史葵,被活活打死。三官立志替父报仇,于是改名换姓去戏班学戏,几年后随班子回到家乡,设法留在史家,当晚刺死了史葵。待风浪平息后,三官平安地回到家里。<br /> <strong>第三类,是拥有远见卓识,打破封建重农抑商思想的枷锁,成为商界的女强人。</strong></p> <p>如《黄英》,《小二》等。</p> <p>《小二》中 &quot;绝贤美&quot; 的女子赵小二就经营这样的手工作坊。她开的是琉璃厂,生产的灯样式新颖,其价格虽高,生意却出奇的好,而且她管治有方,赏罚分明,工人没有一个不服她的,丈夫只是一个工作上的帮手而已她已真正的独立不依的女人,不再是男性的附庸。<br /> <strong>第四类,是少数几位不堪封建制度重压走向极端的泼妇。</strong></p> <p>如《马介甫》中的尹氏。</p> <p>尹氏把丈夫管教得服服贴贴,无论她做什么事丈夫都是大气不敢出一口。她不仅虐待自己的丈夫,还逼得公爹出家当道士,还得弟死,侄儿差点丧命,丈夫的小妾怀孕,她动手打得 &quot;崩注胎堕&quot;。她固然心狠手辣,却从侧面反映男尊女卑社会对女性的摧残。</p> <h2 id="四-聊斋志异几大名篇的内容梗概"><a class="anchor" href="#四-聊斋志异几大名篇的内容梗概">#</a> <strong>四、《聊斋志异》几大名篇的内容梗概</strong></h2> <h3 id="画皮太原士子王生在一次早晨出行的道上遇到一个抱着包袱独自行走的女子-一问那女子自称是不堪大妇虐待而出逃的大家小妾-王生贪恋其姿色便将她带回家里安置在书斋中与其同居-妻子陈氏让他打发此女离开王生不听一日王生到了集市上一个道士吃惊地说他身上有邪气萦绕一定是遇到了妖邪-王生不信反以为道士是想借此混饭吃-他回到家欲进书斋不料门被堵上隔着窗缝往里一看只见一个青面狞鬼正在描画一张人皮随后将人皮穿在身上又化作美女-王生非常害怕找着道士求他相救-道士给他一个蝇拂让他挂在门外-王生回到家与妻子陈氏住在一处-一更时那化作美女的厉鬼将蝇拂弄碎径直到床前将王生的心摘去吃了-王生之弟二郎找来道士将化作老妇的厉鬼治死-陈氏听从道士的指点向一个疯癫的乞丐求救终于将王生救活"><a class="anchor" href="#画皮太原士子王生在一次早晨出行的道上遇到一个抱着包袱独自行走的女子-一问那女子自称是不堪大妇虐待而出逃的大家小妾-王生贪恋其姿色便将她带回家里安置在书斋中与其同居-妻子陈氏让他打发此女离开王生不听一日王生到了集市上一个道士吃惊地说他身上有邪气萦绕一定是遇到了妖邪-王生不信反以为道士是想借此混饭吃-他回到家欲进书斋不料门被堵上隔着窗缝往里一看只见一个青面狞鬼正在描画一张人皮随后将人皮穿在身上又化作美女-王生非常害怕找着道士求他相救-道士给他一个蝇拂让他挂在门外-王生回到家与妻子陈氏住在一处-一更时那化作美女的厉鬼将蝇拂弄碎径直到床前将王生的心摘去吃了-王生之弟二郎找来道士将化作老妇的厉鬼治死-陈氏听从道士的指点向一个疯癫的乞丐求救终于将王生救活">#</a> 《画皮》:太原士子王生,在一次早晨出行的道上,遇到一个抱着包袱独自行走的女子。一问,那女子自称是不堪大妇虐待而出逃的大家小妾。王生贪恋其姿色,便将她带回家里,安置在书斋中,与其同居。妻子陈氏让他打发此女离开,王生不听,一日,王生到了集市上,一个道士吃惊地说他身上有邪气萦绕,一定是遇到了妖邪。王生不信,反以为道士是想借此混饭吃。他回到家,欲进书斋,不料门被堵上,隔着窗缝往里一看,只见一个青面狞鬼,正在描画一张人皮,随后将人皮穿在身上,又化作美女。王生非常害怕,找着道士,求他相救。道士给他一个蝇拂,让他挂在门外。王生回到家,与妻子陈氏住在一处。一更时,那化作美女的厉鬼将蝇拂弄碎,径直到床前,将王生的心摘去吃了。王生之弟二郎找来道士,将化作老妇的厉鬼治死。陈氏听从道士的指点,向一个疯癫的乞丐求救,终于将王生救活。</h3> <h3 id="小翠浙江人王太常小时候一个比猫大的动物在雷鸣电闪时钻到他的身下-后来王太常中了进士并做了侍御-他膝下只有一子但是个傻子-一日一位妇人到他家并将自己的女儿小翠留给他做儿媳-小翠聪慧过人深得公婆喜爱但就是整日里和健儿子疯闹-有一个官员王给谏想诬告王侍御小翠扮成宰相亲临王侍御家让王给谏看到从此收起了诬告王侍御的恶念-一次王给谏到了王侍御家看到傻儿子扮成皇帝模样王给谏到了朝上告了王侍御谋反之罪-皇上验明不过是疯儿傻媳的玩闹后反倒将王给谏发配充军-王侍御觉出小翠不是寻常之人-一日傻公子洗澡小翠趁势捂死了他-等公子又活过来后傻病全好了-过了一年王侍御被王给谏的同党参奏被罢了官-他准备拿一只玉瓶送给朝廷的人好给自己找路子-谁知玉瓶被小翠打碎了公婆二人将小翠一顿大骂-小翠不堪忍受公婆的辱骂决定离开王侍御家-临走时告诉丈夫说自己是狐狸母亲因避雷灾曾受过王侍御的庇护送自己来报恩-小翠走后公子痛哭欲死王公夫妇也知自己铸成大错追悔莫及-两年后公子偶然又遇到小翠-但小翠不愿再回他的家-和公子在外国生活了一段时间后小翠的模样渐渐变了-小翠为公子找了个于家姑娘为妻自己便消失了-婚后公子发现于家女儿就是小翠的模样方才知道小翠模样变化的原因-她将自己变成于家姑娘的模样为的是公子见到于家女儿就像见到她以解公子对她的思念之情"><a class="anchor" href="#小翠浙江人王太常小时候一个比猫大的动物在雷鸣电闪时钻到他的身下-后来王太常中了进士并做了侍御-他膝下只有一子但是个傻子-一日一位妇人到他家并将自己的女儿小翠留给他做儿媳-小翠聪慧过人深得公婆喜爱但就是整日里和健儿子疯闹-有一个官员王给谏想诬告王侍御小翠扮成宰相亲临王侍御家让王给谏看到从此收起了诬告王侍御的恶念-一次王给谏到了王侍御家看到傻儿子扮成皇帝模样王给谏到了朝上告了王侍御谋反之罪-皇上验明不过是疯儿傻媳的玩闹后反倒将王给谏发配充军-王侍御觉出小翠不是寻常之人-一日傻公子洗澡小翠趁势捂死了他-等公子又活过来后傻病全好了-过了一年王侍御被王给谏的同党参奏被罢了官-他准备拿一只玉瓶送给朝廷的人好给自己找路子-谁知玉瓶被小翠打碎了公婆二人将小翠一顿大骂-小翠不堪忍受公婆的辱骂决定离开王侍御家-临走时告诉丈夫说自己是狐狸母亲因避雷灾曾受过王侍御的庇护送自己来报恩-小翠走后公子痛哭欲死王公夫妇也知自己铸成大错追悔莫及-两年后公子偶然又遇到小翠-但小翠不愿再回他的家-和公子在外国生活了一段时间后小翠的模样渐渐变了-小翠为公子找了个于家姑娘为妻自己便消失了-婚后公子发现于家女儿就是小翠的模样方才知道小翠模样变化的原因-她将自己变成于家姑娘的模样为的是公子见到于家女儿就像见到她以解公子对她的思念之情">#</a> 《小翠》:浙江人王太常小时候,一个比猫大的动物在雷鸣电闪时钻到他的身下。后来王太常中了进士,并做了侍御。他膝下只有一子,但是个傻子。一日一位妇人到他家,并将自己的女儿小翠留给他做儿媳。小翠聪慧过人,深得公婆喜爱,但就是整日里和健儿子疯闹。有一个官员王给谏想诬告王侍御,小翠扮成宰相亲临王侍御家,让王给谏看到,从此收起了诬告王侍御的恶念。一次王给谏到了王侍御家,看到傻儿子扮成皇帝模样,王给谏到了朝上告了王侍御谋反之罪。皇上验明不过是疯儿傻媳的玩闹后,反倒将王给谏发配充军。王侍御觉出小翠不是寻常之人。一日傻公子洗澡,小翠趁势捂死了他。等公子又活过来后,傻病全好了。过了一年,王侍御被王给谏的同党参奏被罢了官。他准备拿一只玉瓶送给朝廷的人,好给自己找路子。谁知玉瓶被小翠打碎了,公婆二人将小翠一顿大骂。小翠不堪忍受公婆的辱骂,决定离开王侍御家。临走时告诉丈夫,说自己是狐狸,母亲因避雷灾曾受过王侍御的庇护,送自己来报恩。小翠走后公子痛哭欲死,王公夫妇也知自己铸成大错,追悔莫及。两年后公子偶然又遇到小翠。但小翠不愿再回他的家。和公子在外国生活了一段时间后,小翠的模样渐渐变了。小翠为公子找了个于家姑娘为妻,自己便消失了。婚后公子发现于家女儿就是小翠的模样,方才知道小翠模样变化的原因。她将自己变成于家姑娘的模样,为的是公子见到于家女儿就像见到她,以解公子对她的思念之情。</h3> <h3 id="青凤故事的发展大约可以分为四个阶段-首先是耿去病初会青凤一见钟情第二次夜相见互诉衷情不料被青凤的叔叔撞破不欢而散第三层写第二年清明耿去病上坟得一狐提抱以归则青凤也于是同居生活得很幸福-最后写两年以后青凤的叔叔遭横难耿去病挺身救之由此如家人父子无复猜忌矣-故事首尾完具曲尽其妙-在封建社会里像这样曾经遭到家长反对后来终于得到谅解的恋爱和婚姻有是有的比较少见但有狐狸精的介入事情就好办一些了"><a class="anchor" href="#青凤故事的发展大约可以分为四个阶段-首先是耿去病初会青凤一见钟情第二次夜相见互诉衷情不料被青凤的叔叔撞破不欢而散第三层写第二年清明耿去病上坟得一狐提抱以归则青凤也于是同居生活得很幸福-最后写两年以后青凤的叔叔遭横难耿去病挺身救之由此如家人父子无复猜忌矣-故事首尾完具曲尽其妙-在封建社会里像这样曾经遭到家长反对后来终于得到谅解的恋爱和婚姻有是有的比较少见但有狐狸精的介入事情就好办一些了">#</a> 《青凤》:故事的发展大约可以分为四个阶段。首先是耿去病初会青凤,一见钟情;第二,次夜相见,互诉衷情,不料被青凤的叔叔撞破,不欢而散;第三层写第二年清明耿去病上坟,得一狐,提抱以归,则青凤也,于是同居,生活得很幸福。最后写两年以后青凤的叔叔遭横难,耿去病挺身救之,&quot;由此如家人父子,无复猜忌矣&quot;。故事首尾完具,曲尽其妙。在封建社会里,像这样曾经遭到家长反对后来终于得到谅解的恋爱和婚姻,有是有的,比较少见,但有狐狸精的介入,事情就好办一些了。</h3> <h3 id="促织国内风行都促织皇帝也喜欢于是官府把上交促织作为任务摊派下去-成名主人公也被摊派-官府要求的促织规定很高成名一时做不到合乎规格的促织非常着急-于是他老婆就去一个巫神那里问卜-巫神给了她一幅画上面画的野外的一座荒房什么的-成名觉得是指点捕捉促织的地点就按图索骥结果抓到一只非常好的促织他很高兴就把促织放起来准备第二天交上去-结果他的小儿子偷偷拿这只促织和别的小孩去玩让促织跑了-儿子知道这只促织对父亲的意义所以非常害怕就跳井自杀了-被人们就上来后没有死掉在昏迷中儿子就变成一只小小的促织-虽然这只促织很小但也没有办法成名也还是把它交了上去-谁知道这只小促织凶猛异常胜过了所有的优等促织甚至还咬破了公鸡的鸡冠-完成任务后儿子也醒了过来"><a class="anchor" href="#促织国内风行都促织皇帝也喜欢于是官府把上交促织作为任务摊派下去-成名主人公也被摊派-官府要求的促织规定很高成名一时做不到合乎规格的促织非常着急-于是他老婆就去一个巫神那里问卜-巫神给了她一幅画上面画的野外的一座荒房什么的-成名觉得是指点捕捉促织的地点就按图索骥结果抓到一只非常好的促织他很高兴就把促织放起来准备第二天交上去-结果他的小儿子偷偷拿这只促织和别的小孩去玩让促织跑了-儿子知道这只促织对父亲的意义所以非常害怕就跳井自杀了-被人们就上来后没有死掉在昏迷中儿子就变成一只小小的促织-虽然这只促织很小但也没有办法成名也还是把它交了上去-谁知道这只小促织凶猛异常胜过了所有的优等促织甚至还咬破了公鸡的鸡冠-完成任务后儿子也醒了过来">#</a> 《促织》:国内风行都促织,皇帝也喜欢,于是官府把上交促织作为任务摊派下去。成名(主人公)也被摊派。官府要求的促织规定很高,成名一时做不到合乎规格的促织,非常着急。于是他老婆就去一个巫神那里问卜。巫神给了她一幅画,上面画的野外的一座荒房什么的。成名觉得是指点捕捉促织的地点,就按图索骥,结果抓到一只非常好的促织,他很高兴,就把促织放起来,准备第二天交上去。结果他的小儿子,偷偷拿这只促织和别的小孩去玩,让促织跑了。儿子知道这只促织对父亲的意义,所以非常害怕,就跳井自杀了。被人们就上来后,没有死掉,在昏迷中,儿子就变成一只小小的促织。虽然这只促织很小,但也没有办法,成名也还是把它交了上去。谁知道,这只小促织凶猛异常,胜过了所有的优等促织,甚至还咬破了公鸡的鸡冠。完成任务后,儿子也醒了过来。</h3> <h3 id="席方平明朝末年河南监察御史席廉赈灾济民遭贪官秦士禄诬陷被朝廷斩首-其子席方平在古庙内为父亲守灵时半夜看到一妙龄少女出现在他面前-原来此女名小谢出身于书香门第被洛阳知府看中要纳为小妾她万般无奈只得以死抗争化作冤魂在她欲向巡抚秦士禄申冤时却看到秦正在徇私枉法贿赂钦差-而这正是陷害席方平之父的一幕-小谢得知席方平的遭遇同病相怜决心帮助他为父申冤-她带着席方平到阴曹地府去击鼓鸣冤不料判官-城隍-冥王等都是收到贿赂的贪官他们不问青红皂白对席方平施以火床烙身-利锯锯身等酷刑施刑的鬼役同情席方平手下留情没有锯到他的心脏才使他免于一死-气愤之中小谢带他到天庭告状仙界二郎神深受感动为他主持正义使大明皇帝了解了事实真相惩治了贪官污吏-席方平终于为父申冤昭雪-在这生死磨练中席方平与小谢两人产生了爱慕之情小谢也得以借尸还魂与席方平结成眷属"><a class="anchor" href="#席方平明朝末年河南监察御史席廉赈灾济民遭贪官秦士禄诬陷被朝廷斩首-其子席方平在古庙内为父亲守灵时半夜看到一妙龄少女出现在他面前-原来此女名小谢出身于书香门第被洛阳知府看中要纳为小妾她万般无奈只得以死抗争化作冤魂在她欲向巡抚秦士禄申冤时却看到秦正在徇私枉法贿赂钦差-而这正是陷害席方平之父的一幕-小谢得知席方平的遭遇同病相怜决心帮助他为父申冤-她带着席方平到阴曹地府去击鼓鸣冤不料判官-城隍-冥王等都是收到贿赂的贪官他们不问青红皂白对席方平施以火床烙身-利锯锯身等酷刑施刑的鬼役同情席方平手下留情没有锯到他的心脏才使他免于一死-气愤之中小谢带他到天庭告状仙界二郎神深受感动为他主持正义使大明皇帝了解了事实真相惩治了贪官污吏-席方平终于为父申冤昭雪-在这生死磨练中席方平与小谢两人产生了爱慕之情小谢也得以借尸还魂与席方平结成眷属">#</a> 《席方平》:明朝末年,河南监察御史席廉赈灾济民,遭贪官秦士禄诬陷,被朝廷斩首。其子席方平在古庙内为父亲守灵时,半夜看到一妙龄少女出现在他面前。原来,此女名小谢,出身于书香门第,被洛阳知府看中要纳为小妾,她万般无奈只得以死抗争,化作冤魂,在她欲向巡抚秦士禄申冤时,却看到秦正在徇私枉法,贿赂钦差。而这正是陷害席方平之父的一幕。小谢得知席方平的遭遇,同病相怜,决心帮助他为父申冤。她带着席方平到阴曹地府去击鼓鸣冤,不料,判官、城隍、冥王等都是收到贿赂的贪官,他们不问青红皂白,对席方平施以火床烙身、利锯锯身等酷刑,施刑的鬼役同情席方平,手下留情,没有锯到他的心脏,才使他免于一死。气愤之中,小谢带他到天庭告状,仙界二郎神深受感动,为他主持正义,使大明皇帝了解了事实真相,惩治了贪官污吏。席方平终于为父申冤昭雪。在这生死磨练中,席方平与小谢两人产生了爱慕之情,小谢也得以借尸还魂,与席方平结成眷属。</h3> <h3 id="梦狼官虎吏狼"><a class="anchor" href="#梦狼官虎吏狼">#</a> 《梦狼》&quot;官虎吏狼&quot;</h3> <p>白甲在外边做官,他的父亲白翁(白老头)挂念他。丁某,也就是能在阳间阴间来回走的人,带了白翁到白甲官衙,白翁先看到官衙门口有一头巨大的狼看门,吓得不敢进,丁某硬把他拉进去,白翁又看到官衙里到处都是狼,官衙的白骨已经堆成山。白甲看到父亲来了,很高兴,下令备饭,马上,有一头巨狼叼了一个人来。白翁吓得浑身发抖,问:这是做什么呀?白甲平淡地回答 &quot;用来当饭吃。&quot; 白翁很害怕,辞别了儿子就走,一群狼却挡住他不让走。</p> <p>白翁正在进退两难时,突然来了两个怒目圆睁的金甲猛士,金甲猛士捉住白甲,白甲扑地化成了巨齿獠牙的猛虎。一个金甲猛士要砍掉白甲的脑袋,另一个说,不着急,这是明年的事,先把他的牙敲了。白翁醒后写了封信,劝导白甲要廉政爱民,派小儿子到白甲那儿看看。小儿子到了白甲的官衙,发现哥哥的门牙全掉了,问:怎么回事?白甲说骑马摔的。再问,什么时间摔的?恰好是白翁做梦的那天。小儿子把父亲的信拿出来给白甲看,苦口婆心地劝告他。白甲不听。</p> <p>弟弟在官衙住了几天,发现行贿的人络绎不绝。官衙的人都在搜刮民脂民膏。弟弟流着眼泪劝告哥哥不要这样,要爱护老百姓,白甲不以为然地说:&quot;你是个乡下人,不知道做官有做官的妙诀,一个人能不能提拔,不决定于老百姓,而决定于上司。&quot; 没过多久,白甲升了大官,可是在他赴任的路上,一群老百姓把他杀了。过了一会,有人把白甲救起,说这个人是白老头的儿子,老头还不坏,不应该让他看到这惨状,把这人的脑袋给接上。但是把脑袋反着安上。</p> <p>白甲复活后,脑袋朝后,眼睛能看到自己的背,大家都不把他当人看待。让人自顾其后,是个意味深长的细节。</p> <h3 id="梦狼是带象征意味的小说县令化成吃人猛虎衙役是一群恶狼官衙以人为食吃得白骨如山比喻官场对百姓敲骨吸髓-官虎吏狼成为揭露封建社会黑暗现实的经典性概括"><a class="anchor" href="#梦狼是带象征意味的小说县令化成吃人猛虎衙役是一群恶狼官衙以人为食吃得白骨如山比喻官场对百姓敲骨吸髓-官虎吏狼成为揭露封建社会黑暗现实的经典性概括">#</a> 《梦狼》是带象征意味的小说,县令化成吃人猛虎,衙役是一群恶狼,官衙以人为食,吃得白骨如山,比喻官场对百姓敲骨吸髓。&quot;官虎吏狼&quot; 成为揭露封建社会黑暗现实的经典性概括。</h3> <h3 id="武技幼得名师指点学成一身武技自诩天下难对的武生想不到败在一卖艺女尼的五指之下股骨差点被削断"><a class="anchor" href="#武技幼得名师指点学成一身武技自诩天下难对的武生想不到败在一卖艺女尼的五指之下股骨差点被削断">#</a> 《武技》:幼得名师指点,学成一身武技,自诩天下难对的武生,想不到败在一卖艺女尼的五指之下,股骨差点被削断。</h3> <h3 id="胭脂说的是一个怀春美人胭脂在女友王氏怂恿下意图与意中人鄂生幽会-却想不到王氏之情人宿介早已垂涎胭脂夜晚竟冒充鄂生赴约幸胭脂不愿苟合宿介只抢得胭脂一只绣鞋就又到王氏住处可不料想鞋子竟掉在女友家窗外恰巧被屠户毛大拣去-毛大在窗下偷听了宿介自述的经过几天后翻墙入胭脂家但由于门户不熟悉误入胭脂父亲房间胭脂父亲发现后持刀来捉却反而被毛大杀死毛大在慌忙逃脱时将鞋子遗留在现场-这样胭脂认为是鄂生杀了父亲告到官府官府昏庸以鞋为证将鄂生抓来并屈打成招定成死罪-后来上级复案时调看犯人觉得鄂生不像杀人犯起疑便追问胭脂女友王氏才追出宿介曾冒充前来就抓来宿介又屈打成招定成死罪人们也称赞这位上司神明-可是宿介虽然放荡但颇有文才就向省府学官自己老师写了封申诉信-学官看了觉得确有疑点就请示主管重审又追查鞋子问题认定拾鞋人最可疑于是设谋定计捉到毛大案情才真相大白-真凶伏法鄂生-胭脂也终成眷属"><a class="anchor" href="#胭脂说的是一个怀春美人胭脂在女友王氏怂恿下意图与意中人鄂生幽会-却想不到王氏之情人宿介早已垂涎胭脂夜晚竟冒充鄂生赴约幸胭脂不愿苟合宿介只抢得胭脂一只绣鞋就又到王氏住处可不料想鞋子竟掉在女友家窗外恰巧被屠户毛大拣去-毛大在窗下偷听了宿介自述的经过几天后翻墙入胭脂家但由于门户不熟悉误入胭脂父亲房间胭脂父亲发现后持刀来捉却反而被毛大杀死毛大在慌忙逃脱时将鞋子遗留在现场-这样胭脂认为是鄂生杀了父亲告到官府官府昏庸以鞋为证将鄂生抓来并屈打成招定成死罪-后来上级复案时调看犯人觉得鄂生不像杀人犯起疑便追问胭脂女友王氏才追出宿介曾冒充前来就抓来宿介又屈打成招定成死罪人们也称赞这位上司神明-可是宿介虽然放荡但颇有文才就向省府学官自己老师写了封申诉信-学官看了觉得确有疑点就请示主管重审又追查鞋子问题认定拾鞋人最可疑于是设谋定计捉到毛大案情才真相大白-真凶伏法鄂生-胭脂也终成眷属">#</a> 《胭脂》说的是一个怀春美人胭脂,在女友王氏怂恿下,意图与意中人鄂生幽会。却想不到王氏之情人宿介早已垂涎胭脂,夜晚竟冒充鄂生赴约,幸胭脂不愿苟合,宿介只抢得胭脂一只绣鞋就又到王氏住处,可不料想鞋子竟掉在女友家窗外,恰巧被屠户毛大拣去。毛大在窗下偷听了宿介自述的经过,几天后,翻墙入胭脂家,但由于门户不熟悉,误入胭脂父亲房间,胭脂父亲发现后持刀来捉却反而被毛大杀死,毛大在慌忙逃脱时将鞋子遗留在现场。这样胭脂认为是鄂生杀了父亲,告到官府,官府昏庸,以鞋为证,将鄂生抓来并屈打成招,定成死罪。后来上级复案时,调看犯人,觉得鄂生不像杀人犯,起疑,便追问胭脂女友 —— 王氏,才追出宿介曾冒充前来,就抓来宿介,又屈打成招,定成死罪,人们也称赞这位上司神明。可是宿介虽然放荡,但颇有文才,就向省府学官(自己老师)写了封申诉信。学官看了觉得确有疑点,就请示主管重审,又追查鞋子问题,认定拾鞋人最可疑,于是设谋定计,捉到毛大,案情才真相大白。真凶伏法,鄂生、胭脂也终成眷属。</h3> <h3 id="田七郎说一位豪爽乡绅结交了很多朋友一天夜里梦见有人对他说你现在这些朋友都不理想只有-田七郎-才值得你交-他醒来就寻找田七郎知道七郎是个穷猎人-多次登门拜访为田母斥责不愿他俩亲近-后来田七郎为猎豹与人发生争执失手杀了人被抓进监狱这乡绅花了很多钱救出了田七郎以后交往田母也不再阻拦-一天乡绅家佣人调戏主人儿媳后逃到乡绅仇人家并造谣说儿媳与之私通-乡绅气极但无奈想找田七郎商议田七郎也不见了乡绅很奇怪-可是不久听说那坏佣人被人杀了抛尸荒野-乡绅估计是田七郎干的派人到家找他也找不到-乡绅仇人勾结官吏抓了乡绅而此时乡绅的朋友都散了谁也不来帮忙伸冤-一天县官正在和乡绅的仇人一起谈事突然来了个担柴人冲上大堂抽刀杀了乡绅仇人-县官乱中躲开了这人找不到县官就自刎而死-可是当县官出来验看凶手尸体时这尸体突然跳起一刀砍下县官的头这才又倒下了-这杀人者正是田七郎杀人以尸真是从古未见"><a class="anchor" href="#田七郎说一位豪爽乡绅结交了很多朋友一天夜里梦见有人对他说你现在这些朋友都不理想只有-田七郎-才值得你交-他醒来就寻找田七郎知道七郎是个穷猎人-多次登门拜访为田母斥责不愿他俩亲近-后来田七郎为猎豹与人发生争执失手杀了人被抓进监狱这乡绅花了很多钱救出了田七郎以后交往田母也不再阻拦-一天乡绅家佣人调戏主人儿媳后逃到乡绅仇人家并造谣说儿媳与之私通-乡绅气极但无奈想找田七郎商议田七郎也不见了乡绅很奇怪-可是不久听说那坏佣人被人杀了抛尸荒野-乡绅估计是田七郎干的派人到家找他也找不到-乡绅仇人勾结官吏抓了乡绅而此时乡绅的朋友都散了谁也不来帮忙伸冤-一天县官正在和乡绅的仇人一起谈事突然来了个担柴人冲上大堂抽刀杀了乡绅仇人-县官乱中躲开了这人找不到县官就自刎而死-可是当县官出来验看凶手尸体时这尸体突然跳起一刀砍下县官的头这才又倒下了-这杀人者正是田七郎杀人以尸真是从古未见">#</a> 《田七郎》,说一位豪爽乡绅结交了很多朋友,一天夜里,梦见有人对他说:你现在这些朋友,都不理想,只有 <strong>田七郎</strong> 才值得你交。他醒来就寻找田七郎,知道七郎是个穷猎人。多次登门拜访,为田母斥责,不愿他俩亲近。后来田七郎为猎豹与人发生争执,失手杀了人,被抓进监狱,这乡绅花了很多钱救出了田七郎,以后交往,田母也不再阻拦。一天乡绅家佣人调戏主人儿媳后逃到乡绅仇人家,并造谣说儿媳与之私通。乡绅气极,但无奈,想找田七郎商议,田七郎也不见了,乡绅很奇怪。可是不久,听说那坏佣人被人杀了,抛尸荒野。乡绅估计是田七郎干的,派人到家找他也找不到。乡绅仇人勾结官吏,抓了乡绅,而此时乡绅的朋友都散了,谁也不来帮忙伸冤。一天县官正在和乡绅的仇人一起谈事,突然来了个担柴人冲上大堂,抽刀杀了乡绅仇人。县官乱中躲开了,这人找不到县官就自刎而死。可是当县官出来验看凶手尸体时,这尸体突然跳起,一刀砍下县官的头,这才又倒下了。这杀人者正是田七郎,&quot;杀人以尸&quot;,真是从古未见。</h3> <h3 id="劳山道士则说的是一心术不正的-王生-想跟劳山道士学穿房过墙一无阻拦的法术-法师教他念好咒语后猛然向墙撞去就行了-王生学会后道士又说归宜洁持否则不验-王生下山回家后向妻子夸耀他学到过墙的本领了妻子让他试一下他念好咒语一头向墙撞去结果咚的一下倒在地上头上撞了个大包妻儿笑他他气得大骂法师没有良心"><a class="anchor" href="#劳山道士则说的是一心术不正的-王生-想跟劳山道士学穿房过墙一无阻拦的法术-法师教他念好咒语后猛然向墙撞去就行了-王生学会后道士又说归宜洁持否则不验-王生下山回家后向妻子夸耀他学到过墙的本领了妻子让他试一下他念好咒语一头向墙撞去结果咚的一下倒在地上头上撞了个大包妻儿笑他他气得大骂法师没有良心">#</a> 《劳山道士》则说的是一心术不正的 <strong>王生</strong> 想跟劳山道士学穿房过墙一无阻拦的法术。法师教他念好咒语后,猛然向墙撞去就行了。王生学会后,道士又说:&quot;归宜洁持,否则不验。&quot; 王生下山回家后,向妻子夸耀他学到过墙的本领了,妻子让他试一下,他念好咒语,一头向墙撞去,结果咚的一下,倒在地上,头上撞了个大包,妻儿笑他,他气得大骂法师没有良心。</h3> <h3 id="陆判说的是一位士子交上一个鬼判这鬼判为他妻子换了个美人头为他换了个聪明心"><a class="anchor" href="#陆判说的是一位士子交上一个鬼判这鬼判为他妻子换了个美人头为他换了个聪明心">#</a> 《陆判》说的是一位士子交上一个鬼判,这鬼判为他妻子换了个美人头,为他换了个聪明心。</h3> <h3 id="叶生写书生-叶生文章词赋冠绝当时可是时数限人文章憎命每次都考不中-幸而还有个做官的好友推荐但仍是考不中-而这位好友又要到别处为官想带他去一边教自己的孩子一边让叶生再考但叶生此时却生病了难以随行-眼看良机靠山皆要消失就焦虑而死可是魂灵却和这位好友一齐走了好友也不知是魂灵-又是几年好友儿子在良师叶生指导下考中了当了大官就帮助自己老师鬼魂也考中了又劝他衣锦还乡-叶生至家惊呆了妻儿又看到自己的棺材灵牌才知道自己已死随即扑地而灭-这个魂从知己不觉已死生不能中死才能中而中了后却又灭了-这些情节比范进中举还要丰富"><a class="anchor" href="#叶生写书生-叶生文章词赋冠绝当时可是时数限人文章憎命每次都考不中-幸而还有个做官的好友推荐但仍是考不中-而这位好友又要到别处为官想带他去一边教自己的孩子一边让叶生再考但叶生此时却生病了难以随行-眼看良机靠山皆要消失就焦虑而死可是魂灵却和这位好友一齐走了好友也不知是魂灵-又是几年好友儿子在良师叶生指导下考中了当了大官就帮助自己老师鬼魂也考中了又劝他衣锦还乡-叶生至家惊呆了妻儿又看到自己的棺材灵牌才知道自己已死随即扑地而灭-这个魂从知己不觉已死生不能中死才能中而中了后却又灭了-这些情节比范进中举还要丰富">#</a> 《叶生》,写书生 <strong>叶生</strong> &quot;文章词赋,冠绝当时&quot;,可是 &quot;时数限人,文章憎命&quot;,每次都考不中。幸而还有个做官的好友推荐,但仍是考不中。而这位好友,又要到别处为官,想带他去,一边教自己的孩子,一边让叶生再考,但叶生此时却生病了,难以随行。眼看良机靠山皆要消失,就焦虑而死,可是魂灵却和这位好友一齐走了,好友也不知是魂灵。又是几年,好友儿子在良师 &quot;叶生&quot; 指导下,考中了,当了大官,就帮助自己老师(鬼魂)也考中了,又劝他衣锦还乡。&quot;叶生&quot; 至家,惊呆了妻儿,又看到自己的棺材灵牌,才知道自己已死,随即扑地而灭。这个 &quot;魂从知己&quot; 不觉已死,生不能中,死才能中,而中了后,却又 &quot;灭&quot; 了。这些情节比《范进中举》还要丰富。</h3> <h3 id="红玉先写-红玉与冯生-燕好似乎可以结束了但为冯父发觉极力反对冯生只好遵父命决裂-而红玉却又另觅替身卫氏并极力促成冯卫结婚生子福儿琴瑟和谐似又可结束却又想不到一士豪要来夺妻逼得冯生父死妻亡只能抱儿外逃-家破人亡之际不想来一侠客杀了仇家官府抓了冯生指为杀人犯后又得侠客救助才被释放-到家时大仇虽报而只剩孤身何等凄凉想不到红玉又带着丢失的儿子来了又是破镜重圆-真是一会儿花好月圆一会儿花残月落一会乐上天堂一会悲入地狱-大起大落难有其匹"><a class="anchor" href="#红玉先写-红玉与冯生-燕好似乎可以结束了但为冯父发觉极力反对冯生只好遵父命决裂-而红玉却又另觅替身卫氏并极力促成冯卫结婚生子福儿琴瑟和谐似又可结束却又想不到一士豪要来夺妻逼得冯生父死妻亡只能抱儿外逃-家破人亡之际不想来一侠客杀了仇家官府抓了冯生指为杀人犯后又得侠客救助才被释放-到家时大仇虽报而只剩孤身何等凄凉想不到红玉又带着丢失的儿子来了又是破镜重圆-真是一会儿花好月圆一会儿花残月落一会乐上天堂一会悲入地狱-大起大落难有其匹">#</a> 《红玉》先写 <strong>红玉与冯生</strong> 燕好,似乎可以结束了,但为冯父发觉,极力反对,冯生只好遵父命决裂。而红玉却又另觅替身卫氏,并极力促成冯卫结婚,生子福儿,琴瑟和谐,似又可结束,却又想不到一士豪要来夺妻,逼得冯生父死妻亡,只能抱儿外逃。家破人亡之际不想来一侠客,杀了仇家,官府抓了冯生,指为杀人犯,后又得侠客救助,才被释放。到家时,大仇虽报,而只剩孤身,何等凄凉,想不到,红玉又带着丢失的儿子来了,又是破镜重圆。真是一会儿花好月圆,一会儿花残月落;一会乐上天堂,一会悲入地狱。大起大落,难有其匹。</h3> <h3 id="翩翩中讲了一个-浪子-离家出走喝吃嫖赌招摇弄得一身浓疮行乞回乡里为人不齿不敢回家-就凭这一点知耻之心得到仙女翩翩的救护帮他治好了病给他穿上了仙衣并和他结了婚生了孩子生活安定-回到故乡的家后再找翩翩找不到了"><a class="anchor" href="#翩翩中讲了一个-浪子-离家出走喝吃嫖赌招摇弄得一身浓疮行乞回乡里为人不齿不敢回家-就凭这一点知耻之心得到仙女翩翩的救护帮他治好了病给他穿上了仙衣并和他结了婚生了孩子生活安定-回到故乡的家后再找翩翩找不到了">#</a> 《翩翩》中讲了一个 <strong>浪子</strong> ,离家出走,喝吃嫖赌招摇,弄得一身浓疮,行乞回乡里,为人不齿,不敢回家。就凭这一点 &quot;知耻之心&quot;,得到仙女翩翩的救护,帮他治好了病,给他穿上了 &quot;仙衣&quot;,并和他结了婚,生了孩子,生活安定。回到故乡的家后,再找翩翩,找不到了。</h3> <h2 id="五-聊斋志异七大情事"><a class="anchor" href="#五-聊斋志异七大情事">#</a> <strong>五、《聊斋志异》七大情事</strong></h2> <h3 id="婴宁"><a class="anchor" href="#婴宁">#</a> 《婴宁》</h3> <p>书生 <strong>王子服</strong> 在元宵灯会偶遇佳人,他捡起姑娘丢落的梅花,相思成疾。表兄吴生诳他说女子是他的表妹,在西南三十里的山里。王子服一人入山寻找,见到佳人,不想竟是自己的姨妹,叫婴宁。婴宁本为狐产女子且随鬼母长大,全然不知道人间的礼数,憨纯无比。当子服向她求寝时,她竟然以 &quot;不惯与生人睡&quot; 相答,并将此事告诉鬼母。</p> <p>后来,婴宁和子服一起归家。王母和吴生都疑心是鬼,但见她成日爱花爱笑,不避太阳,就让她和子服结为夫妻。婚后还惩治了邻家的浪荡子。一天夜里,婴宁告诉子服她的生事,并求他迁其鬼母的坟与自己的生母和葬。</p> <p>又过了一年,婴宁生下一子。在娘怀里就不怕生人,和婴宁一样。</p> <h3 id="聂小倩"><a class="anchor" href="#聂小倩">#</a> 《聂小倩》</h3> <p>书生 <strong>宁采臣</strong> 为人豪爽,洁身自爱。</p> <p>一次他坐在金华一座庙里,同坐的还有一个叫燕赤霞的书生,有奇异的收妖的本领。一女鬼夜里前来勾引宁采臣,被他严词拒绝。第二天,有两个兰溪的过路人在隔壁离奇死了。当晚,女鬼又来,告诉他自己叫聂小倩,被恶鬼胁迫,求他帮助自己脱离苦海。宁采臣按小倩说的把她的尸骨迁到了里自家不远处。小倩随他回到家中。宁采臣妻死后,宁采臣娶小倩为妻。</p> <p>一天,小倩告诉宁采臣说金华的妖怪就要来寻仇了。于是,宁采臣拿出燕赤霞给他的辟邪的牛皮袋挂在床前。这时小倩已经有了人气,不再害怕辟邪的东西了。第二天晚上,妖怪果然来到,被收服在牛皮袋里化作了数斗清水。</p> <p>后聂小倩为宁采臣生得二子,皆有功名。</p> <h3 id="辛十四娘"><a class="anchor" href="#辛十四娘">#</a> 《辛十四娘》</h3> <p>明朝正德年间,一姓冯的书生清晨遇一娇艳动人的美人,傍晚时分见美人从一座破庙里出来又回去。于是冯生进去一探究竟,对一老头说明自己爱慕女子之心,并硬闯闺房被赶出。在回家的路上,又误入自己祖母的弟弟的鬼宅。鬼宅的老太太答应为外甥提亲。</p> <p>果然, <strong>冯生</strong> 和 <strong>十四娘</strong> 结成秦晋之好。</p> <p>后冯生几番得罪楚银台的公子被害下狱,在辛十四娘的努力下才得以脱险。但经此事后,十四娘对冯生很失望,看透尘缘。第二天容光大变,日渐衰老,半年后像一个八十岁的老太婆了。尽管冯生照顾的很好,还是一病不起,溘然逝去。留下丫头做了冯生的妻子。</p> <p>后来,老仆人在太华山见到辛十四娘骑着一头青骡子,对老仆人说 &quot;冯郎还好吗?回去告诉他,我已名列仙藉了。&quot;</p> <h3 id="香玉"><a class="anchor" href="#香玉">#</a> 《香玉》</h3> <p>一个姓 <strong>黄的书生</strong> 坐在崂山下清宫里读书。院里有几棵耐冬和几株牡丹。一天,黄生看见一穿白衣的女子在花丛中忽隐忽现,后来又看见一个穿红衣的。他对白衣姑娘顿生爱慕之心,写诗想念,不想,竟感化女郎成其好事。女郎告诉他自己叫香玉,红衣的叫绛雪。直到园里的一株牡丹被买走,才知香玉是花精。</p> <p><strong>黄生</strong> 得知牡丹枯萎死去,就作了 50 首情诗悼念香玉。</p> <p>终于感动花神,让香玉重生。在香玉柔弱生长的时候,绛雪就陪黄生读书。后来,香玉完全恢复,和黄生过上了夫妻一样的生活。</p> <p>10 年后,黄生死去。他死前说 &quot;我死了会变成牡丹花下的一株红色花芽,长五瓣叶子。&quot; 果然如他所说。</p> <p>3 年后,道士的徒弟把黄生化身的牡丹砍掉,随后,园里的耐冬和牡丹相继徇情而死。</p> <h3 id="公孙九娘"><a class="anchor" href="#公孙九娘">#</a> 《公孙九娘》</h3> <p>顺治年间,莱阳的书生到济南去祭拜自己的亲友,遇见死去的同县的朱生央求他给自己做媒,把同样是鬼的莱阳生的侄女嫁给他。 <strong>莱阳生</strong> 同意后,在侄女家,他邂逅了天仙一般的公孙九娘。由朱生牵红线,人鬼结合。</p> <p>一天,九娘哭着要求莱阳生把自己的尸骨重新迁到母亲的坟旁,并告诉他,人鬼殊途,不宜久留,别了送给他一双罗袜。</p> <p>但终因她死后埋在乱葬岗中而使莱阳生无法寻找,终于导致二人爱情失败。</p> <p>过了半年,莱阳生又去济南,天色暗下,只见一地鬼火,旧地重游,无限惆怅。隐约中看见公孙九娘在坟岗之间,莱阳生连连呼唤:&quot;九娘,九娘……&quot; 却始终不见公孙九娘回答。</p> <h3 id="白秋练"><a class="anchor" href="#白秋练">#</a> 《白秋练》</h3> <p>书生 <strong>慕蟾宫</strong> 和父亲到湖北一带跑船做买卖。无事便在船上读诗。不久,被一个叫白秋练的女子仰慕,使其害病。天黑后,女子的母亲和一婢女领白秋练到船上,慕生念情诗将其病治好,见她美貌,便和她共床枕一晚。</p> <p>后来随父亲回家后,思念成疾,其父只好带他又来到湖北慕生和白秋练相遇的地方。当晚,白秋练来到船上,这次换了是她给慕生念情诗,将其救活。两人由此结合,过了三年生了一个小孩。</p> <p>一天,白秋练告诉他自己是一条鲤鱼精,现在龙王要招她为妃,并恳求慕生救自己的母亲和让她免于被龙王占有。在白秋练的指点下,慕生遇一道士,得以救回白秋练。</p> <p>后来慕生的父亲死后,一家人搬到湖北,再也没有回故乡。</p> <h3 id="娇娜"><a class="anchor" href="#娇娜">#</a> 《娇娜》</h3> <p>一个叫 <strong>孔雪笠</strong> 的书生,性情文雅仁厚,善作诗。一次路过一家大门,被请进去做客,还做了这家公子的老师。过了半年,正当夏天,孔雪笠的胸口上长了一个碗大的脓疮。公子让表妹娇娜前来医治。娇娜美貌的面容让孔雪笠惊为天人,一时竟忘了疼痛。经过娇娜的医治,孔雪笠的病也日渐好转,而孔雪笠也对娇娜暗生情素。孔雪笠对娇娜思念之情渐渐难以抑制。</p> <p>公子不知道孔生中意娇娜,却将另一个表妹阿松嫁给了孔生。而不久,娇娜也嫁与吴郎。两人本以萌发的爱情升华为友情。</p> <p>一天,公子告知孔生他和娇娜,阿松都是狐狸,恳求孔生帮他们避开雷击。结果,孔生冒着被雷击的危险救下娇娜,而娇娜为救孔生两人肌肤相亲,接吻送丸,让孔生起死回生。也是这一天,娇娜的丈夫吴郎一家没有避过劫难。</p> <p>娇娜只好和表哥一起前去孔生家。</p> <p>孔生有空就去陪他们兄妹下棋,饮酒。两人再没有谈及儿女私情,终究有缘无份。</p> <h2 id="六-读后感"><a class="anchor" href="#六-读后感">#</a> 六、读后感</h2> <p>对于聊斋志异里的故事,我觉得说作者写他的目的是例如什么反封建一类的,是对他的一种亵渎,这里面的故事,实际上就是作者听到的传说或是自己编的故事,只是在一个大的时代背景下,作者通过一些离奇的故事,写出自己的看法、期望与现象。有一定时代的烙印,在客观上折射社会现实,但不等同于主这些这部作品的目的是批判现实的黑暗。故事中有相当的一部分是用来描述人与鬼之间纯洁、真挚、相互扶携的情感。这说明,作者对于当时的时代,是有幻想的。</p> <p>聊斋倒是说了一个事,那就是到多数的妖精本性也都是善良的。而对于现在的社会,人们时常抱怨世风日下,人们没有了过去的那种淳朴,变得自我、骄横、自私、势力,然而,不变的却仍是,在世上,好人永远比坏人多。我们可以用一个放大镜去观察我们的生活,但观察身边令我们感动的事,还是专门关心社会中不和谐的声音,取决于拿着放大镜的我们。我并不是说睁一只眼闭一只眼,对社会上不公正的事视而不见、置若罔闻,而是用一个理性、客观的角度分析,以求解决矛盾。一个义愤填膺的人,体现的是谁会的正义感,但一群义愤填膺的认为在一起,只顾 &quot;正义&quot; 地指责,将会带来非常不好的谁会影响,使一件本身并不是多么严重的问题,带上各种高帽子,随便是谁,都凑上来发表几句无关痛痒的评论和指责,接着就又有 &quot;世道变了,人心不古&quot; 的感叹,然而这样真的可以解决问题么?与其这样,我们不如利用正义的事,来感化不和谐的声音,这么说或许有一些太过于理想化,但是,至少可以有一个积极的社会氛围,而不是怨声载道。</p> <p>聊斋告诉我们,妖精也可以与人类和谐相处,那我们又为什么要带上有色眼镜看这样一群人?生活中会有一些人给人的印象就是 &quot;不是好人&quot;,但永远不要在不了解一个人之前,给他戴上任何帽子。有的人看上去和颜悦色,但实际上笑里藏刀;有的人看上去总黑着脸,但总会给你最给力的支持。聊斋这些故事,也告诉我要学会了解一个人的本质,不要以貌取人。<br /> <div class="links"><div class="item" title="jdjwzx233" style="--block-color:#e9546b;"><span class="exturl image" data-url="aHR0cHM6Ly9jZG4uamRqd3p4YXBpLmZ1bi/jgIrogYrmlovlv5flvILjgIvnroDku4vlj4ror7vlkI7mhJ8uZG9jeA==" data-background-image="https://bu.dusays.com/2022/08/18/62fe0d5d77bf2.png"></span> <div class="info"> <span class="exturl title" data-url="aHR0cHM6Ly9jZG4uamRqd3p4YXBpLmZ1bi/jgIrogYrmlovlv5flvILjgIvnroDku4vlj4ror7vlkI7mhJ8uZG9jeA==">下载文档(docx)</span> <p class="desc">下载文档(docx)</p> </div></div></div></p> <div class="note warning"> <p>文章转载于夸克文档,侵删。</p> </div>

2022/8/18
阅读更多

《水浒传》每章概括

<p><img data-src="/image/Water_Margin_summary/Water_Margin_summary_1.jpg" alt="Water_Margin_summary_1" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_2.jpg" alt="Water_Margin_summary_2" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_3.jpg" alt="Water_Margin_summary_3" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_4.jpg" alt="Water_Margin_summary_4" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_5.jpg" alt="Water_Margin_summary_5" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_6.jpg" alt="Water_Margin_summary_6" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_7.jpg" alt="Water_Margin_summary_7" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_8.jpg" alt="Water_Margin_summary_8" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_9.jpg" alt="Water_Margin_summary_9" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_10.jpg" alt="Water_Margin_summary_10" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_11.jpg" alt="Water_Margin_summary_11" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_12.jpg" alt="Water_Margin_summary_12" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_13.jpg" alt="Water_Margin_summary_13" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_14.jpg" alt="Water_Margin_summary_14" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_15.jpg" alt="Water_Margin_summary_15" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_16.jpg" alt="Water_Margin_summary_16" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_17.jpg" alt="Water_Margin_summary_17" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_18.jpg" alt="Water_Margin_summary_18" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_19.jpg" alt="Water_Margin_summary_19" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_20.jpg" alt="Water_Margin_summary_20" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_21.jpg" alt="Water_Margin_summary_21" /><br /> <img data-src="/image/Water_Margin_summary/Water_Margin_summary_22.jpg" alt="Water_Margin_summary_22" /></p> <p><div class="links"><div class="item" title="jdjwzx233" style="--block-color:#e9546b;"><a href="/download/Water%20Margin%20summary_jdjwzx233%20crack_20220814.7z" class="image" data-background-image="/image/other/62fe0d5d77bf2.png"></a> <div class="info"> <a href="/download/Water%20Margin%20summary_jdjwzx233%20crack_20220814.7z" class="title">一键下载所有图片(7Z)</a> <p class="desc">一键下载所有图片(7Z)</p> </div></div></div></p> <div class="note warning"> <p>图片转载于夸克文档 ---《水浒传每回内容梗概_完整版》(<span class="exturl" data-url="aHR0cHM6Ly92dC5xdWFyay5jbi9ibG0vcXVhcmstZG9jLXNzci0yOTMvcHJldmlldz9hcHBOYW1lPTEmYW1wO2JpPTM1ODI1JmFtcDtjaD1rayU0MHN0b3JlJmFtcDtkZT1BQU96d0VYSDhvSG1xM2FkTU15UW1md210b1IzQmt5d0VqSmFKYjlza1ZMQWJnJTI1M0QlMjUzRCZhbXA7ZG49NTY3NzY0ODkzMjQtMGM0YWVjMWMmYW1wO2RzPUFBTlAyaFNBcDhNJTJCcVlOV0VKaTklMkZnaSUyQm9oeGpNYjFaaE5WYUxhTGJHR3F0NGclM0QlM0QmYW1wO2VpPWJUa3dCQVh6OEwlMkZ6YTJRUXhFdFIyd085VHklMkJIOVZjTnRRJTNEJTNEJmFtcDtmcF9mcm9tPXZpZXdzcGFnZSZhbXA7ZnI9YW5kcm9pZCZhbXA7ZnJvbT0mYW1wO2dpPWJUa3dCTkJhdXNUNnBWSVQ4ZFVUM1BCa0lCVjIlMjUyRjVySnd0NHpKdTF6aTFVWURsbyUyNTNEJmFtcDtpZD0yNTA1QzFENkNGNUM3QUU1ODVBM0ZBOEJCODcwOTlDNSZhbXA7a3A9QUFUaGtXRFUxMyUyQmphajJLMnI5eHhzSGhwYUZFRGhkSkI2dzFuenNFTFNwTVhNcGtmS2ZLOHVUTDZHWjMzV08lMkZuMVJSQkN1bnJhZ2wwdmNONUg0SWdSMjVFT2Z4YjQyMUE3Qk5xJTJGU1RtNVNTZUElM0QlM0QmYW1wO250PTUmYW1wO253PTAmYW1wO3BmPTMzMDAmYW1wO3ByPXVjcHJvJmFtcDtzaWQ9MTYwODFlNmNmODQxNTcxMDgwNWUwOTkwYzVjZTA2NjUmYW1wO3N2PXJlbGVhc2UmYW1wO3VjX2Jpel9zdHI9T1BUJTNBQkFDS19CVE5fU1RZTEUlNDAwJTdDT1BUJTNBVE9PTEJBUl9TVFlMRSU0MDAlN0NPUFQlM0FTX0JBUl9CR19DT0xPUiU0MGZmZmZmZiZhbXA7dWNfcGFyYW1fc3RyPWRubnRud3ZlcGZmcmdpYmlqYnByc3ZwaWRpY2hlaXV0ZHNrcCZhbXA7dXQ9QUFOUDJoU0FwOE0lMkJxWU5XRUppOSUyRmdpJTJCb2h4ak1iMVpoTlZhTGFMYkdHcXQ0ZyUzRCUzRCZhbXA7dmU9NS40LjUuMTk4JmFtcDtwcmV2aWV3U2hhcmU9cHJldmlld1NoYXJl">点我前往</span>)(<span class="exturl" data-url="aHR0cHM6Ly9vY2suY24vaXIwcHU=">打不开点我</span>),侵删。</p> </div>

2022/8/14
阅读更多

Git 常用命令

<h1 id="git-常用命令"><a class="anchor" href="#git-常用命令">#</a> Git 常用命令</h1> <h2 id="初始化仓库"><a class="anchor" href="#初始化仓库">#</a> 初始化仓库</h2> <p>git init</p> <h2 id="添加所有文件"><a class="anchor" href="#添加所有文件">#</a> 添加所有文件</h2> <p>git add .</p> <h2 id="添加提交注释"><a class="anchor" href="#添加提交注释">#</a> 添加提交注释</h2> <p>git commit -m &quot;xxx&quot;</p> <h2 id="本地代码推送到远程仓库"><a class="anchor" href="#本地代码推送到远程仓库">#</a> 本地代码推送到远程仓库</h2> <p>git push origin master</p> <h2 id="拉取远程分支代码到本地"><a class="anchor" href="#拉取远程分支代码到本地">#</a> 拉取远程分支代码到本地</h2> <p>git pull origin master</p> <h2 id="创建本地分支-a"><a class="anchor" href="#创建本地分支-a">#</a> 创建本地分支 A</h2> <p>git branch A</p> <h2 id="切换到分支-a"><a class="anchor" href="#切换到分支-a">#</a> 切换到分支 A</h2> <p>git checkout A</p> <h2 id="创建并切换到本地分支-a"><a class="anchor" href="#创建并切换到本地分支-a">#</a> 创建并切换到本地分支 A</h2> <p>git checkout -b A</p> <h2 id="将分支-a-代码合并到当前分支"><a class="anchor" href="#将分支-a-代码合并到当前分支">#</a> 将分支 A 代码合并到当前分支</h2> <p>git merge A</p> <h2 id="将当前分支的-head-指向-a-分支"><a class="anchor" href="#将当前分支的-head-指向-a-分支">#</a> 将当前分支的 HEAD 指向 A 分支</h2> <p>git rebase A</p> <h2 id="删除本地分支"><a class="anchor" href="#删除本地分支">#</a> 删除本地分支</h2> <p>git branch -d xxx</p> <h2 id="删除远程分支"><a class="anchor" href="#删除远程分支">#</a> 删除远程分支</h2> <p>git push origin -d xxx</p> <h2 id="查看所有分支"><a class="anchor" href="#查看所有分支">#</a> 查看所有分支</h2> <p>git branch -a</p> <h2 id="重命名当前分支名称"><a class="anchor" href="#重命名当前分支名称">#</a> 重命名当前分支名称</h2> <p>git branch -m new_branch</p> <h2 id="重命名指定分支名称"><a class="anchor" href="#重命名指定分支名称">#</a> 重命名指定分支名称</h2> <p>git branch -m old_branch new_branch</p> <h2 id="修改最近一次-commit-信息"><a class="anchor" href="#修改最近一次-commit-信息">#</a> 修改最近一次 commit 信息</h2> <p>git commit --amend<br /> 按 i 进入编辑模式<br /> 修改完成后,按 Esc 退出编辑模式<br /> 输入:wq,按回车键保存并退出<br /> 重新 git push 代码到远程仓库</p> <h2 id="清空-commit-信息"><a class="anchor" href="#清空-commit-信息">#</a> 清空 commit 信息</h2> <p>git checkout --orphan new_branch<br /> git add .<br /> git commit -m &quot;xxx&quot;<br /> git branch -D master // 删除 master 分支<br /> git branch -m master // 修改当前分支名称为 master</p> <h2 id="删除本地项目的远程仓库连接"><a class="anchor" href="#删除本地项目的远程仓库连接">#</a> 删除本地项目的远程仓库连接</h2> <p>git remote rm origin</p> <h2 id="查看当前远程仓库"><a class="anchor" href="#查看当前远程仓库">#</a> 查看当前远程仓库</h2> <p>git remote -v</p> <h2 id="新项目第一次与远程仓库建立连接"><a class="anchor" href="#新项目第一次与远程仓库建立连接">#</a> 新项目第一次与远程仓库建立连接</h2> <p>git remote add origin <span class="exturl" data-url="bWFpbHRvOmdpdEBnaXRodWIuY29t">git@github.com</span>:leexiang59/l-helpers.git<br /> git push -u origin master</p>

2022/8/2
阅读更多

联想小新为硬件保留2G内存的解决方法

<h1 id="联想小新为硬件保留2g内存的解决方法"><a class="anchor" href="#联想小新为硬件保留2g内存的解决方法">#</a> 联想小新为硬件保留 2G 内存的解决方法</h1> <p>如下图,我们可以看到,系统为硬件保留了 2.1G 内存,实际可用内存减小</p> <p><img data-src="https://images.jdjwzx233.cn/upload/Qexo/2023/6/30/852d4683ffa44b4d88c40983ec224e8e_888d00b6a16a5d798dc962771fc34303.png" alt="https://images.jdjwzx233.cn/upload/Qexo/2023/6/30/852d4683ffa44b4d88c40983ec224e8e_888d00b6a16a5d798dc962771fc34303.png" /></p> <p>在任务管理器中查看 GPU 的占用可以看到,保留内存是被核心显卡共享走了,你电脑的集显需要显存,而他自带的集显是没有显存的,所以会使用你的内存来当显存。这就是为什么会出现为硬件保留 2G 多的原因。</p> <p><img data-src="https://images.jdjwzx233.cn/upload/Qexo/2023/6/30/6b493dd1d9eb41c7801cabdd73d29a2a_6c44c16d08f4df59c9eee04c7ec95fbc.png" alt="https://images.jdjwzx233.cn/upload/Qexo/2023/6/30/6b493dd1d9eb41c7801cabdd73d29a2a_6c44c16d08f4df59c9eee04c7ec95fbc.png" /></p> <h2 id="方法一"><a class="anchor" href="#方法一">#</a> 方法一:</h2> <p>我们可以将电脑重启,狂按 F2 进入 BOIS (其他品牌的自行百度)</p> <p><em>默认是英文,如果看不懂可以先调成中文再继续</em></p> <p>找到系统设置 -&gt; 共享显存</p> <p>然后可以根据自己的需求更改共享显存大小</p> <h2 id="方法二"><a class="anchor" href="#方法二">#</a> 方法二:</h2> <p>如果你的电脑有独显的话,可以将显卡切换为独显,独显自身有专用内存,一般不会占用电脑的内存,如果可以的话,可以自行百度,将显卡切换为独显,集显就别管它了。</p> <h2 id="方法三部分设备不行"><a class="anchor" href="#方法三部分设备不行">#</a> 方法三 (部分设备不行):</h2> <p>win+r 打开 msconfig 高级选项 最大内存勾上 点确定应用后重启 开机再到这个位置,勾选然后出现数字后再取消勾选(这时里面有灰色数字里面的数字不用更改),点确定应用。</p>

2022/7/29
阅读更多

博客扩展功能

<p><span class="exturl" data-url="aHR0cHM6Ly9zaG9rYS5sb3N0eXUubWUvY29tcHV0ZXItc2NpZW5jZS9ub3RlL3RoZW1lLXNob2thLWRvYy9zcGVjaWFsLw==">想看原文请点我!</span></p> <p><img data-src="/image/other/21-7-2022_13058_shoka.lostyu.me.jpeg" alt="21-7-2022_13058_shoka.lostyu.me.jpeg" /></p>

2022/7/21
阅读更多

VS2022 VC++程序如何生成安装程序

<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容."> <script id="hbeData" type="hbeData" data-hmacdigest="cb611f57611848108754dcf4986ea21a79c0d4154e8779ed658163a9fbef3d69">3537d6572f3f0fd5c50ac184a2626861a3cba29c48961332d79e0a844d6ae77dab5195ae09dbf1f6f99213f682ef162fb2ed79c27f8957824e60b871e5072f7ef5df518a665e82ecf207c72a11b92b6fc18370063491488e762a5309ece0cd60fbe2eed2c1dbcc97899419a130f8fb4a3305381147aa806dffc3953b5d73610d00cc2aaa611217e7449448e047c0a3e178a766be4f7426b7b807a2840bcabb260a865274845280b4878ae43a59801578ef2eb45f42f684bdd53cb968305ea36355af14fa668291d56b192f70718bdb6c685a7b0a8f2fa53922f45d82025e4556cda95ec7647c002e6cea33dd53c2aaa3ec82843e409ab886eea3f4559391f1fd4fa086fa660ac28ca9df3c7777840eef398044f8dd01c1d39c3c1f980eb9a6b93b67e11a88f7d9b88d58c530bd7ab417e5ffe20af96fd76408934a7abf7df8c6e555fe2e793a80c980211a22779a32bf5fe2b9fb3cb1d8bedf264b6c7b29adbdc1214043a84f3c3439199b541d1b67f896cf5ff92090fee543d8dc3291f8c1767f4a54eb2a73cfbe37b5aac08e4f744912e66ffb37539d35d43ad4554829a47cf1238840718676fcb3699ff8d8926d58f353399f4af59728e9397972ad4e85b998cbabf4118d6ce3de3bdd73272e235fe83227e5a14d8bdb97ec9af180c7db24de0e9f152dece449458acafb34e4cf3c55c5fa6f9e0638b4c397ab22a52da9283da71144efafd7015ba6ea70e641c225c25ac8851dfd561a70cae95877c42593ca8cab615a65bff9adfbae36f8da17463005dec0865dae51d35ea6bfad79da02fc144bf187578c02a211833fddc14f595fd926afbc923ad42c1938c3903380212a5f11702afb1bcad814fe946cb9df232a5ae9b2e56fa2573e033390ebd4b6f0b7d3770834db57f6986528c18ca5c95b9e9dfecc328860f94cd47d2c21a048193aecceafe93a1053b846342f429fb5b89e0f9ceedd686f72e80d150fd6e3f336129c75f6076878f71444db8f33f04b851e691a7472fec94fa05ec1a17f9c8c5d92c823dabb84ed9ccd07a66f5e19cf059a32eb52490bf4152da27ff6ff0ee7b8036dc68ce159315cdbf8949790626ff05f973c1d400882ff734095b435e85cdc8fa1c18439fd314fcad54bc1fcfba0ed8d5bf7dd2e5eb47d4b467e6316037bc5141629cd16530530f1aebf05e9f0ccbb0728c3b74ada3a32fd9989a9a2419955ddd03e0147428f3b7a963229bead7f6175f9545304063c1668dd91ce8886d0ba3011a6b20392ac5d7b746afdc00e5b72b4f37b13916537f1865e7651af63f5fc7630aafa785617494b86d4c317c0d51da27785c4bff29904bd806ce46cb44747e37c1acb4d5bb9fe49c278d223b57d1101c199c9ee52319ea19156f1ee9e179a0a1485c839009ed186efa30b685acbf5fb8c08a84fe1e2a7cb25b299252885655d4d79f430decdd3a6b91f515d8fcf7f4becf9a1ff629f4a0bae4209e3ceb2d6d50fc23b16ceda12b5c51f725bc6da9fae2d693fcd8721b89612e21d5b5bb391c2bf630b8ee7a20744e3c7fc6d4a7c5c0f7b9b41c7aa42a49a6e3dd90633f0e59448940f888b1f209c641e506f7591c0935bc1486ad8d60a6f91904430f76611a0b4759bc249f340e8511cda223c046a251890b83874f7770defbdfdca5377a076d77d799ae970c39d3e504c044ce43d14620aee30ab498c0a9499d010a3921ecf981b6901f245410ababad84ff119d6eca3da394dd2fedeecfff6434dbfcf3ab349a4589bf7724bde97ae230daa8aba9ba5d2426913bc4a858881c3d3b321df937fa32611433b798782d229cff02e71320093c39a3618ba8fae22a4d791ba093891baffedab6013550619dde61f5c34fa5e7c9ceb003ec5790a2f415918008af77adcc83eecb0097a43fd42398a32b5acac5335c476c5e0747c025700131166414b6af6bd1eba92a0c3390146d11fc4373d619e6a3149515490afa170748a9b52022bd85a8b4b332a35d75185d656c83360340b769121221e093691a6f96fc64ef3724906d5a668d1627b8d840f9ec24140b54d6ccf5c6d0ffa4021b24320a86cf8f714e873cfbed04ebd13cf5e56904d8de2a9f6ec1dceb3ba878cd4c8e1410214f5c4311b78f281a6ac17116ab6e77be484194d7b62cdd9a56893119f11ac7201c5cd60e4167d11f5252e94ae18cd7b91134be659620f3c04b62b0e674d77ed69479342f7f664fb36a91a97a5ebe306968dd459b6b3bba9b0f530dd16ccb8b13893974ec9f5a1a6d725e28d4cc6d161a4387e2c5fbcc96b9291c0f1593268217c4feb13641eff40c390dce1d3a22ebc0cddd8ada1c1470fc9ff686768921edfe0c32f19d5aa0959cfc8ea32710bf6cbddb0151489f2b580bdc62a1bf8b8125be10a6614483be4bbad543fbaca69cc21bb86079df2b60608df5badcf95cb6fb093ff89d11f34d93475dd87a1c2c7540e3a603698e3b547dd2255fb5ec4fb84733c0a15fd3b5f350acc97aea88d963b648e54720cb73fc898b2171fd864d9e925081f7dff5dd96c77390edda003fba06b16fdc843f7ddc520f448b6369b3e8cd1619cc556f2a176aa78b2c7cdbbc1aa7f1718f2cc25ff8f026f7a424665ea6cc60e7a45839a2c3eb20d30813c0125ee06a744c9e87b44214c3c7ef71634bb5e7a70f3a6913b659eb71b390a24b15655ab314f909aa90f8f413f4bb7ef70d9ac3767459bb3205009691fe17abd809b91cb211ad6dbc217dd11d34093726e0345fe53def625d035ad86a58c13efa852da7cbc552dbe0de2e76f4a6fed3e9b0dffdabea90e467fd1fc8e4dc76cddc10106093375ed48db79f5d4420a518823c6b419c78be4fe7ecb75b0a92b8cc289549db7a921c3c217ac1a8eeb707455ca3d95abe2c47b01772735b51108ed466cc0fb1b49a50375d73bc0c82991363b81bf577942203cf4686dbd53e6075444ec1a640fe3d84b25a435cf641cdfdadd75b0887466d344034712e5a301ec767495f45f5223bc13a78b9f58bff5b8f950167a987b31910a9c69ef0168075074cb1667fab7d34a1543bcaff448883a45c37aea25dece520b95d00e68e5f0bf4ce6e3c365ecea2d7a5a876ddfdded12c67b955baa3fa5d261afa70654bdbc54852a54975aa2ac347b2edeb4550ca82576bb8747288d8ebafe5394ffa8002cd9594ad85eb676ef1eb8e663ab120ebbf190885c581c6286cb108827ec1e5de8a463656b03d4929931ec6e8572f15dca0cfffcf35a173c678473dce34735e7b2b68376c3dbc2a0eb476164792b8dfe7eafb14c545462b835f33f335c4c48b0710e99437cd1da0fc522d63689597b62725d8c2ac589a576028a0a680cff276ad3f6a85d2b693970882f7f53dd9ff15cfc8d97293ef226982c8c34079c94a0ba6addf17a24b17d96308abd5191798c33acdec7b9ef21c3a511defa9c3805594f0d305034c4b157560880b9ffb679590c992771e4fb0cb91089e17160b8089e836a0bb074fc38bff37e0397eb12d4e3bdae6505b863fa2e727f1bc645f59edb65edec72d2fff7a855f0f8be611b16477943fdcbac89d14204841f8f7b95a900490d93f7ab1507363830100a842f2c8e938ec679356541c5408b925f080a5b9a1e9032b17f58bd18fc59653e1a92d24a81f62f2a60b927d29271db00c7a0c604f45cc23200e78f86f090c98ecf436ee26c89cd98746e624d6c982bb6a0bbf760d72ff37256a5bebe61f4ab08371771001aa701c8c5084e50fa127c5886bb7a49b0394f131b64e5b4784a974f8109276f2aa13a0269185eff02c74b9bbc5e75f8f79ae6e5f0e163c7b9191c69b3c2fc64f3e395299b71d7bc0f54ef125735ba4b9109563cc4405e49f9051b97a349d6569bc8879f314b4df9a8383c5475b57498e37636267b3d393d1a85a479b0249ffcd36b33f3e86f8db34fe0c3ac7833b1fcd807b84e2efa28905892e838f693b861ba5054782c3673d22c4f71f594ab633a14bfe54f75dab333c747523bbaf66df0a791e438c538914e443e9bb9bcc61518ebfa25a83ba93a6ab88fb8480b6c94e7323b6847be5acd672255e32c5d01f3daf7526a3f803d8c9a4c223ee441c62daf05562a277bb086e7193f12d4b75ec947734cb9f5b34d178f17be154bf3d032080767e1dff337db1745c22bc6cd0a01f136b613e5583771df5b97c7e92aa23c05122126671e36c3407f1d9c07396926a9ab9c4edfb649041aefdda780d0c7bd0ea57b9341102bac3fe7a4c7f18f03155108d2d6f536b789b8ae714453f1ece2e2bf40a4c7f0eaf4200c115084675de3344f9cfc6b2b9e8958e93fc03a4a7a65ed23616e8a158e5af45ac08a49cd5e721724ba0a6764df240392ab00ab276d38a18efdcc6c0fea781352334b854bbf4412c9184ea9eb2d120001d53d6a8d15f60852c5db5cc36fc2baf37275e26d1fa9639c9adb93461de07931cda741275caacf224f5a2a4c49364526a601fd8ee3326b2c91cff96f053d76e238120458a59bdd9869d1fec9584bb22c62eebee28a1bae47a92afc35ec2f9f24fb30ea4e1327b3912ea33424b9c827702abd08dcc8a7f861d1d7d47979bab1127bde4791ba9eba1a6dfd7d6219e3e8300d471398dc21590c3e357d674e33f523ddc471a7623273323b96ce8ed8162a2e5468c18e2744d1f21180e1650a202960faefb86df250356051b5e1b6db401bc779ad23bb58037e14e1b57eb556f4503351863532ed06eb6aedbdb8d3c0ea7979c815a2038cda90ff8fc4414d22665c99ede9747dce8821ef0b3355883ffaef89992d84f3b70d9ad53b7d92990aa39b0c75f6e2dc44ff7c82ecb8532ed9aeca5cd0f504a431ea0c406f859f6ff8ed6ec68dc0d754174e1cd3044c3743b0357bae4f41b8e5e6cde7ed6b5ea6f7a5cf6e98c166797bde9f4e536c64e234251ebbe9db1a117791f510b12523fd68c7ac4ab9a9d721090a3759d7eb3bf38ecb7435398b9d68cf53d554f5ae76abf85488d2471c4a601e52ba2c79d5e6c5e2187c26e8f0bda1df0113119afa4c4931ee565a47913a6530c8c0f010e043694ac6656e7ed2297af571cb58692596f49e28c6da647c553bd5d17c3cc857b6b77ef7731ec95e0cfd471cf6f4ccec7ee469f9a31760610c472958fb27a93beda3a78ecc3881429803bacefe9ff40f121c1b92ca061d2eba6c646bcc457fce4790bde0856935579b4d9a9a9809bbc91d6748afff7f142c1708776245db7ee5c57297c8a543dad66c2f79f5cc6412cb3615e78f126c937d632ef4261de6577c50a5b2a40194390b637f17c602580ca9ec027975de296b6b81b212a0813dc6507bba88257645ae523e68cfb741c5b8702cfde9ef2bc9e39eb77223bed92959ca833b2d5c60c480d25b97324d7c1eb6061d2fe95dd96cacb7f9faa21bea6971f5127c0cd6f0e685e22e69b564029d45ab7c60af777277d88862919c70e350e4d0b1591590a95af04b879e77f2855f779f42f137418d67324d938979f4b2f1054e2c135a549ea614992154c08d04e0203951bfa8ae3ff281b5064b8f191a2f6522a773bd2fb4d0545c8b148886b7281b30547c1978516341851d7d182f04179a5f32e05a258cfc553251c9aa2e5c2df14a3eea67f9120fe32cc053d95785c10ca1ffbb5b94e7796e2552bcc21bf8e6ca645ac0095ed37eac89420522b6cf8a7b801c4d366a1f200afbe5e7c11088cc85136596d512fc2492f84bab2238266fac0623ad8b40527f68030b01fd0fdb4c06f28dd1aa2cf0254e2b6a3ac75460b30707207044ddcac69cea129b3a7e211d656b56b248b7bc7922e31c620581761306b0c5829e7def3e994a5dbb9a0ea912a21c9e01b8566e3c9029b959a7c625a0568a9965a02e7c1b2704a4d6e0e633b8fd0400a3104b1ef7c9a4e88e602630d75003c412a7c7430dfe9146da02b1cdd84cf40764b9594062772a4ff6e4a7ee8f2c9306fc57255e4c5449e5bd3f502fb4f18299ee20bc03a9664f8f4d0da8600086d9eebe2f2d97abc810532396f63bb0f8816a2d09f28be2dc9afb575fe30e891ae13b414efa2acb6965299dafaa015186271885ba1ac3a15f8a92a024006bc8cec227e21251f534e23d5e2fee84ecf67fbc0fea1686833765f6064861b122046bf9d34c1c7ca610d3a829822aaa331796d0191c4020b3d3a70bfc69409d9a9678da75384f7a40d50d3628c61fbfbdc7688c0852ef3921d824d1e7e5b37bf241a75fe1a0f5f34ac6f68d010564ea22b2cf5b2cac2aa92ae52320c7d1e97ca69da86dd7ec2505daaf49964aed2b0a25a4977ea0fdc91de51271b52c5583657cf5f188ec62e241100f93d6ba3fd52d280e9d37e1cc5bea24bce7cb5f919fd980728dc8c34c2aa0306c053f91f42d33ab8ed23eb891943b75943fcb7fca7d4cd952fda38a682ccf03a8878c8e6d064c6948743093ccea974d0dbad6c196af05dac0336aed477afe484d03e19a1590785ddeef1057e8d564664d8781da54d8e302f970745d4f5705a00bbfd990c04c46f3201efd6f2b879185cde0ebc753dedf78c93cddf25c4925c7c67c3a21423e0aeaecafd2beb19b1678db30420c4d5f75550dce58ddfb129e473c591a198c5042736be92685f2e83f1649eb2288ba8a9bb7c60db26f366fca1efbaa53ed8b99588983b2b3d07132319f5dbafd7af052e812a4a9a979b32e1b246b974cd002699536bc9474cab8eb5df6dc3d0e11cd77acc5af6fbc40d71dbab7e126b76c99b59c8091fa5b67cf5d77e6992d07f52b41ac47f19d339b4d56f82c039b9a1f36d569cbeeba0859e2e395e65401be15e0ecf29f39f6366801f5d528034ae20db402f902fd5a792e57e98314f7f7f620e61394ddc4391619161ea4078e201fce66b9f66446b002887326cb6f36d22e055f4765a4ffd9dedf13a22a6ea0</script> <div class="hbe hbe-content"> <div class="hbe hbe-input hbe-input-wave"> <input class="hbe hbe-input-field hbe-input-field-wave" type="password" id="hbePass"> <label class="hbe hbe-input-label hbe-input-label-wave" for="hbePass"> <span class="hbe hbe-input-label-content hbe-input-label-content-wave">您好, 这里需要密码.</span> </label> <svg class="hbe hbe-graphic hbe-graphic-wave" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none"> <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path> </svg> </div> </div> </div> <script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">

2022/7/21
阅读更多

Markdown超全教程

<p>[TOC]</p> <h1 id="markdowntyporavscode-超全教程-给大一新生安利的文本神器"><a class="anchor" href="#markdowntyporavscode-超全教程-给大一新生安利的文本神器">#</a> [Markdown+Typora/VSCode 超全教程] 给大一新生安利的文本神器</h1> <p>Sakiyary 2022/7/16</p> <h2 id="简要介绍"><a class="anchor" href="#简要介绍">#</a> 😂 简要介绍</h2> <p><strong>Markdown</strong> 是一种轻量型标记语言,是一种语法。以 <code>.md</code> 结尾的文本文件就是 Markdown 文件。相较于 <strong>Word</strong>, 它更加像是 <strong>HTML</strong> 语言或是 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>LaTeX</mtext></mrow><annotation encoding="application/x-tex">\LaTeX</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.89883em;vertical-align:-0.2155em;"></span><span class="mord text"><span class="mord textrm">L</span><span class="mspace" style="margin-right:-0.36em;"></span><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.68333em;"><span style="top:-2.904999em;"><span class="pstrut" style="height:2.7em;"></span><span class="mord"><span class="mord textrm mtight sizing reset-size6 size3">A</span></span></span></span></span></span><span class="mspace" style="margin-right:-0.15em;"></span><span class="mord text"><span class="mord textrm">T</span><span class="mspace" style="margin-right:-0.1667em;"></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.46782999999999997em;"><span style="top:-2.7845em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord textrm">E</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2155em;"><span></span></span></span></span><span class="mspace" style="margin-right:-0.125em;"></span><span class="mord textrm">X</span></span></span></span></span></span>, 并不是最淳朴的那种 &quot;所见即所得&quot;. 它处处透露着一种极简主义。高效简洁清晰的同时,又很简单。看起来舒服,语法简单,尤其在处理纯文本上有很大的优势.</p> <p>它相较于 <strong>Word</strong>, 兼容性非常高,可以跨平台使用,不用担心奇奇怪怪的版本兼容问题。同时,有许多网站都支持或正在使用 <strong>Markdown</strong> 语法。如 <strong>Github</strong> (等一系列代码托管平台), StackOverflow (等答疑平台), 简书,语雀 (等一系列笔记平台).</p> <h2 id="实际应用"><a class="anchor" href="#实际应用">#</a> 📐 实际应用</h2> <p>所有要写文本的时候都可以用上 <strong>Markdown</strong>!</p> <p>它可以让你不再纠结什么字体,什么样式,什么排版。而且逻辑清晰,层次分明.</p> <p>像我大一的时候就用 Markdown 来写各种笔记,演讲稿,课程论文,实验报告,代码的 <code>README.md</code> ... 包括本教程文档.</p> <h2 id="工具"><a class="anchor" href="#工具">#</a> 🍴 工具</h2> <p>Markdown 只是一种语法。那么用来写 Markdown 的文本编辑器呢?我推荐的是 <strong>Typora</strong> 或者 <strong>VS Code</strong></p> <h3 id="typora"><a class="anchor" href="#typora">#</a> Typora</h3> <p>Typora 应该是被广泛用于写 Markdown 的文本软件,就和 Markdown 语法一样高效。而且它还有很实用的扩展语法与自定义样式的功能。其能将 <code>.md</code> 导出成多种文件,如 <code>.pdf</code> , <code>.html</code> , <code>.docx</code> (没想到吧,能导出到 Word)</p> <p>但是现在 Typora 已经发布正式版并且变为收费软件。中文官网在此 <span class="exturl" data-url="aHR0cHM6Ly90eXBvcmFpby5jbi8=">Typora 官方中文站 </span>.</p> <p>我当然是推荐大家都用正版啦。不过价格是永久版¥89, 好在可以用在 3 台设备上。如果和你的两位同学 / 舍友均摊一下,每人就只要¥30, 和一张游戏月卡差不多.</p> <p>至于盗版以及破解方法<span class="exturl" data-url="aHR0cHM6Ly93d3cub25seTQud29yay9ibG9nLz9pZD0zNzk=">在此随便找一种改注册表时间方法的</span><s>不介绍 (还挺多的其实)</s>.</p> <p><s>还有一种免费白嫖的方法就是安装测试版 / Beta 版。官网有历史版本的下载链接 <span class="exturl" data-url="aHR0cHM6Ly90eXBvcmFpby5jbi93aW5kb3dzL2Rldl9yZWxlYXNlLmh0bWw=">Typora 历史版本下载页</span></s></p> <p>白嫖 Beta 版已经寄了,要么支持正版要么去学习一下破解方法吧 (还是忍不住啦,看上面的链接👆)</p> <h3 id="vs-code"><a class="anchor" href="#vs-code">#</a> VS Code</h3> <p>这是微软家的开源文本编辑器,理论上来说所有代码,语言,都可以用 VS Code 来写,同样是非常的简洁好用。在下载插件 <strong>Markdown All in One</strong> 后对 Markdown 的基础支持也是非常的好。若在 VS Code 下载 Markdown 各种附加扩展,就能获得比 Typora 更加丰富的扩展语法与操作.</p> <h3 id="其他"><a class="anchor" href="#其他">#</a> 其他</h3> <p>大部分 IDE, 像 Jetbrain 的全家桶里应该每一款,都支持 Markdown 语法,在此不多赘述.</p> <p>本文档主要使用 Typora 进行演示,同时会介绍许多 Typora 所包含的扩展语法.</p> <h2 id="基础教程"><a class="anchor" href="#基础教程">#</a> 🍭 基础教程</h2> <p>当有多种标记方法时我会倾向其中一种.</p> <p>标题有 <code>*</code> 表示该为扩展语法,仅在 Typora 或 添加了扩展的 VS Code <strong>本地生效</strong>,在大多数平台上<strong>并不认可</strong>.</p> <h3 id="0-写-markdown-的第零步"><a class="anchor" href="#0-写-markdown-的第零步">#</a> 0. 写 Markdown 的第零步</h3> <p>我们写文本的时候大多写的是中文,可是输入法在输中文时使用的标点为全角标点,如 <code>,。?!()【】:;“”</code> . 这些标点是不被 Markdown 所认可的,也是无法转义的.</p> <p>我建议大家写 Markdown 的时候都用半角标点,即英文标点,如 <code>,.?!()[]:;&quot;&quot;</code> . 且每个半角标点在文本使用时加上后置空格,符合英文标点的书写规范,也更加美观.</p> <p>以微软自带输入法举例,在使用中文输入法时按下 <code>Ctrl</code> + <code>.(这是个句号)</code> , 切换标点的全角与半角。这样即可中文输入 + 半角标点.</p> <h3 id="1-标题-数个-空格-前置"><a class="anchor" href="#1-标题-数个-空格-前置">#</a> 1. 标题 [数个 &quot;#&quot; + 空格 前置]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 一级标题</span><br><span class="line">## 二级标题</span><br><span class="line">### 三级标题</span><br><span class="line">#### 四级标题</span><br><span class="line">##### 五级标题</span><br><span class="line">###### 六级标题</span><br></pre></td></tr></table></figure></p> <p>标题会在目录与大纲分级显示,可以跳转.</p> <p>在 Typora 中建议开启 <code>严格模式</code> ,即不应为 <code>#标题</code> ,应为 <code># 标题</code> .</p> <p>应该要手动补上空格,使得 Markdown 语法在其他文本编辑器上兼容.</p> <h3 id="2-强调-用-或-__-包围"><a class="anchor" href="#2-强调-用-或-__-包围">#</a> 2. 强调 [用 &quot;**&quot; 或 &quot;__&quot; 包围]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">**欢迎报考南京大学!** (我喜欢用这种)</span><br><span class="line">__欢迎报考南京大学!__</span><br></pre></td></tr></table></figure></p> <p>或者选中想要强调的文字按下 <code>Ctrl</code> + <code>B</code> .</p> <p>E.G.</p> <p><strong>欢迎报考南京大学!</strong></p> <h3 id="3-斜体-用-或-_-包围"><a class="anchor" href="#3-斜体-用-或-_-包围">#</a> 3. 斜体 [用 &quot;*&quot; 或 &quot;_&quot; 包围]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">*欢迎大佬来浇浇我各种知识* (我喜欢用这种)</span><br><span class="line">_欢迎大佬来浇浇我各种知识_</span><br></pre></td></tr></table></figure></p> <p>或者选中想要强调的文字按下 <code>Ctrl</code> + <code>I</code> .</p> <p>E.G.</p> <p><em>欢迎大佬来浇浇我各种知识</em></p> <p>(P.S. <em><strong>斜体并强调</strong></em> [用 &quot;***&quot; 或 &quot;___&quot; 包围])</p> <h3 id="4-删除线-用-~~-包围"><a class="anchor" href="#4-删除线-用-~~-包围">#</a> 4. 删除线 [用 &quot;~~&quot; 包围]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">~~我宣布个事儿, 我是Sabiyary!~~</span><br></pre></td></tr></table></figure><br /> E.G.<br /> <s> 我宣布个事儿,我是 Sabiyary!</s></p> <h3 id="5-高亮-用-包围"><a class="anchor" href="#5-高亮-用-包围">#</a> 5. * 高亮 [用 &quot;==&quot; 包围]</h3> <p><strong>(注意:此为扩展语法)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">==我喜欢黄色, 也喜欢绿色==</span><br></pre></td></tr></table></figure><br /> E.G.<br /> <mark> 我喜欢黄色,也喜欢绿色</mark></p> <h3 id="6-代码-用-包围"><a class="anchor" href="#6-代码-用-包围">#</a> 6. 代码 [用 &quot;`&quot; 包围]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">`sudo rm -rf /*`</span><br></pre></td></tr></table></figure><br /> E.G.<br /> <code>sudo rm -rf /*</code> (没事别乱敲这个!)<br /> <s>&quot;请输入管理员密码: (闪烁的光标)&quot;</s></p> <h3 id="7-代码块-按三个-并敲回车"><a class="anchor" href="#7-代码块-按三个-并敲回车">#</a> 7. 代码块 [按三个 &quot;`&quot; 并敲回车]</h3> <p><figure class="highlight c"><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><br><span class="line"><span class="comment">// 这里就可以开始输入你要的代码了</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">mian</span><span class="params">()</span> &#123;</span><br><span class="line"> print(“Hello, world!\n<span class="string">&quot;);</span></span><br><span class="line"><span class="string"> retrun O;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">``` // (这三个&quot;</span>`<span class="string">&quot;文本编辑器会帮你自动补全 一般不用手动输)</span></span><br></pre></td></tr></table></figure><br /> (我之前都是用这个来展示各种语法的,应该不用举例了吧)<br /> 要想显示行数的话,一般要在 Typora 的设置里勾上这个显示行数的选项.<br /> 代码块里可以选择语言,其会根据语言来自动高亮各个语句。在选择语言后, <code>```</code> 会变为 <code>````</code> + <code>对应语言</code> .</p> <h3 id="8-引用-空格-前置"><a class="anchor" href="#8-引用-空格-前置">#</a> 8. 引用 [&quot;&gt;&quot; + 空格 前置]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt; 24岁, 是学生.</span><br><span class="line">&gt; &gt; 学生特有的无处不在(恼)</span><br></pre></td></tr></table></figure><br /> 引用是可以嵌套的!<br /> E.G.</p> <blockquote> <p>24 岁,是学生.</p> <blockquote> <p>学生特有的无处不在 (恼)</p> </blockquote> </blockquote> <h3 id="9-无序列表-或-空格-前置"><a class="anchor" href="#9-无序列表-或-空格-前置">#</a> 9. 无序列表 [&quot;-&quot; 或 &quot;+&quot; + 空格 前置]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">- 一颗是枣树 (我喜欢用这种)</span><br><span class="line">+ 另一颗还是枣树</span><br><span class="line">* (其实这种也可以, 不过由于在 Typora 中很难单个输入, 故不常用)</span><br></pre></td></tr></table></figure><br /> 三种前置符都可以,敲回车会自动补全,可在 Typora 设置中调整补全的符号,敲回车后按下 <code>Tab</code> 会缩进一级.<br /> E.G.</p> <ul> <li>一颗是枣树</li> <li>另一颗还是枣树</li> </ul> <h3 id="10-有序列表-数字-空格-前置"><a class="anchor" href="#10-有序列表-数字-空格-前置">#</a> 10. 有序列表 [数字 + &quot;.&quot; + 空格 前置]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">我来这里就为了三件事:</span><br><span class="line">1. 公平</span><br><span class="line">2. 公平</span><br><span class="line">3. 还是tm的公平!</span><br></pre></td></tr></table></figure><br /> 敲回车会自动补全,敲回车后按下 <code>Tab</code> 会缩进一级.<br /> E.G.<br /> 我来这里就为了三件事:</p> <ol> <li>公平</li> <li>公平</li> <li>还是 tm 的公平!</li> </ol> <h3 id="11-上标-用-包围"><a class="anchor" href="#11-上标-用-包围">#</a> 11. * 上标 [用 &quot;^&quot; 包围]</h3> <p><strong>(注意:此为扩展语法)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">C语言中int的上限是 2^31^ - 1 = 2147483647</span><br></pre></td></tr></table></figure><br /> E.G.<br /> C 语言中 <code>int</code> 的上限是 2<sup>31</sup> - 1 = 2147483647</p> <h3 id="12-下标-用-~-包围"><a class="anchor" href="#12-下标-用-~-包围">#</a> 12. * 下标 [用 &quot;~&quot; 包围]</h3> <p><strong>(注意:此为扩展语法)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">H~2~O 是剧毒的!</span><br></pre></td></tr></table></figure><br /> E.G.<br /> H<sub>2</sub>O 是剧毒的!</p> <h3 id="13-注释-后置"><a class="anchor" href="#13-注释-后置">#</a> 13. * 注释 [&quot;[^]&quot; 后置]</h3> <p><strong>(注意:此为扩展语法)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt; 今日我们相聚于此, 是为了学习 Markdown 的使用, 它的教程对于全体「观众」而言, 值得足足两个硬币的支持鼓励![^1]</span><br><span class="line">[^1]: 沃兹·基·硕德 改编自「公鸡」普契涅拉.</span><br></pre></td></tr></table></figure><br /> 需要在文末写上注释对应的内容<br /> E.G.</p> <blockquote> <p>今日我们相聚于此,是为了学习 Markdown 的使用,它的教程对于全体「观众」而言,值得足足两个硬币的支持鼓励![^1]<br /> [^1]: 沃兹・基・硕德 改编自「公鸡」普契涅拉.</p> </blockquote> <h3 id="14-链接-常用-分别包围文本与链接"><a class="anchor" href="#14-链接-常用-分别包围文本与链接">#</a> 14. 链接 [常用 &quot;[]&quot; + &quot;( )&quot; 分别包围文本与链接]</h3> <p><strong>(注意:文内跳转为扩展用法)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[来看看我贫瘠的仓库罢](https://github.com/jdjwzxAPI)</span><br><span class="line">[基础教程: 12. 下标](#12. 下标 [用 &quot;~&quot; 包围])</span><br></pre></td></tr></table></figure><br /> 支持网页链接与文内跳转,按住 <code>Ctrl</code> 并 <code>单击鼠标左键</code> 即可跳转.<br /> E.G.<br /> <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2pkand6eEFQSQ=="> 来看看我贫瘠的仓库罢</span><br /> [基础教程: 12. 下标](#12. 下标 [用 &quot;~&quot; 包围])</p> <h3 id="15-任务列表-空格-前置"><a class="anchor" href="#15-任务列表-空格-前置">#</a> 15. 任务列表 [&quot;- []&quot; + 空格 前置]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">TodoList:</span><br><span class="line">- [ ] 刷B站</span><br><span class="line">- [ ] 写代码</span><br><span class="line">- [ ] 起床</span><br></pre></td></tr></table></figure><br /> 用 <code>x</code> 代替 <code>[ ]</code> 中的空格来勾选任务列表。在 Typora 中可以直接用鼠标左键单击勾选框.<br /> E.G. TodoList:</p> <ul class="task-list"> <li class="task-list-item"><input type="checkbox" id="cbx_0" checked="true" disabled="true" /><label for="cbx_0"> 刷 B 站</label></li> <li class="task-list-item"><input type="checkbox" id="cbx_1" checked="true" disabled="true" /><label for="cbx_1"> 写代码</label></li> <li class="task-list-item"><input type="checkbox" id="cbx_2" checked="true" disabled="true" /><label for="cbx_2"> 起床</label></li> </ul> <h3 id="16-表格-用-绘制表格边框"><a class="anchor" href="#16-表格-用-绘制表格边框">#</a> 16. 表格 [用 &quot;|&quot; 绘制表格边框]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">| 学号 | 姓名 | 年龄 |</span><br><span class="line">| :--- | :---: | ---: | (引号的位置代表着 左对齐, 居中, 右对齐)</span><br><span class="line">|114514|田所|24|</span><br><span class="line">|1919810|浩三|25|</span><br></pre></td></tr></table></figure><br /> 第一行为表头,并由第二行分割线决定对齐方式与长度,第三行及之后即表格数据<br /> E.G.</p> <table> <thead> <tr> <th style="text-align:left">学号</th> <th style="text-align:center">姓名</th> <th style="text-align:right">年龄</th> </tr> </thead> <tbody> <tr> <td style="text-align:left">114514</td> <td style="text-align:center">田所</td> <td style="text-align:right">24</td> </tr> <tr> <td style="text-align:left">1919810</td> <td style="text-align:center">浩三</td> <td style="text-align:right">25</td> </tr> </tbody> </table> <h3 id="17-图片-直接拖进来或者复制粘贴"><a class="anchor" href="#17-图片-直接拖进来或者复制粘贴">#</a> 17. 图片 [直接拖进来或者复制粘贴]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">![图片](图片的位置)</span><br></pre></td></tr></table></figure><br /> <img data-src="https://cdn.jdjwzxapi.fun/4b90f603738da97756eb7745d18e8b1f8418e3fa.jpeg" alt="欸嘿嘿.jpeg" /><br /> 我还是会选择拖进来或者复制粘贴啦~在 Typora 的设置里也可以改图片的储存方式.</p> <h3 id="18-分割线-按三个-或-或-_-并敲回车"><a class="anchor" href="#18-分割线-按三个-或-或-_-并敲回车">#</a> 18. 分割线 [按三个 &quot;*&quot; 或 &quot;-&quot; 或 &quot;_&quot; 并敲回车]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">***</span><br><span class="line">--- (我喜欢用这种)</span><br><span class="line">___</span><br><span class="line">// (其实按三个及以上都可以)</span><br></pre></td></tr></table></figure><br /> 由于 <code>*</code> 与 <code>_</code> 均会自动补全,所以我觉得 <code>-</code> 最为方便.<br /> E.G.</p> <hr /> <hr /> <hr /> <h3 id="19-emoji表情-前置"><a class="anchor" href="#19-emoji表情-前置">#</a> 19. Emoji 表情 [&quot;:&quot; 前置]</h3> <p><strong>(注意:英文输入为扩展语法)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">:sweat_smile: </span><br><span class="line">:drooling_face:</span><br><span class="line">:clown_face:</span><br><span class="line">// (敲回车或者鼠标点击, 后置的&quot;:&quot;一般不需要手动输)</span><br></pre></td></tr></table></figure><br /> 这个功能唯一的要求就是英语水平要高,或者大概记得各个 Emoji 的英文名.<br /> E.G.<br /> 😅<br /> 🤤<br /> 🤡<br /> 对于其余普通的 Markdown 文本编辑器,可以直接将 Emoji 表情复制进来,这是直接<strong>硬编码</strong>的 (<s>刻进 DNA 里</s>)<br /> E.G.<br /> 😅🤤🤡<br /> 用好这个功能可以让你的文本非常的可爱!<s>太抽象了</s><br /> 这里分享一个可以复制<span class="exturl" data-url="aHR0cHM6Ly9lbW9qaXBlZGlhLm9yZy9hcHBsZS8=">全 Emoji 的网站</span>,非常好用!我之前的 C 语言大作业也是从这里下载的资源!</p> <h2 id="进阶教程"><a class="anchor" href="#进阶教程">#</a> 🔥 进阶教程</h2> <h3 id="1-目录-自动生成"><a class="anchor" href="#1-目录-自动生成">#</a> 1. 目录 [自动生成]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[TOC] (此为 Typora 特有的, 如本文档开头)</span><br></pre></td></tr></table></figure><br /> 若使用 VS Code 搭配 Markdown All in One 扩展,可在 VS Code 的 <code>命令面板</code> (即 <span class="exturl" data-url="aHR0cHM6Ly9jb2RlLnZpc3VhbHN0dWRpby5jb20vZG9jcy9nZXRzdGFydGVkL3VzZXJpbnRlcmZhY2UjX2NvbW1hbmQtcGFsZXR0ZQ==">VS Code Command Palette</span>) 输入 <code>Create Table of Contents</code> 自动生成目录,且可在扩展设置中细调目录参数.</p> <h3 id="2-内联-html-代码-用-包围"><a class="anchor" href="#2-内联-html-代码-用-包围">#</a> 2. 内联 HTML 代码 [用 &quot;&lt;&gt; &lt;/&gt;&quot; 包围]</h3> <p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;div style=&quot;text-align:center&quot;&gt;</span><br><span class="line"> &lt;font style=&quot;color:red&quot;&gt;我不会 HTML 呜呜呜... 浇浇我&lt;/font&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line">&lt;center&gt;简单的文字居中也可以这样&lt;/center&gt;</span><br><span class="line">&lt;u&gt;我差点忘了还有下划线这东西...&lt;/u&gt;</span><br></pre></td></tr></table></figure><br /> 只要你会写,你完全可以把 Markdown 当作 <strong>HTML</strong> 来写.<br /> 同时, <code>.md</code> 文件可以直接导出成一个网页.<br /> 下划线可以选中想要下划的文字按下 <code>Ctrl</code> + <code>U</code> .<br /> E.G.<br /> &lt;div style=&quot;text-align:center&quot;&gt;<br /> &lt;font style=&quot;color:red&quot;&gt; 我不会 HTML 呜呜呜... 浇浇我 &lt;/font&gt;<br /> &lt;/div&gt;<br /> &lt;center&gt; 简单的文字居中也可以这样 &lt;/center&gt;<br /> &lt;u&gt; 我差点忘了还有下划线这东西...&lt;/u&gt;</p> <h3 id="3-内联-latex-公式-用-包围"><a class="anchor" href="#3-内联-latex-公式-用-包围">#</a> 3. 内联 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>LaTeX</mtext></mrow><annotation encoding="application/x-tex">\LaTeX</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.89883em;vertical-align:-0.2155em;"></span><span class="mord text"><span class="mord textrm">L</span><span class="mspace" style="margin-right:-0.36em;"></span><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.68333em;"><span style="top:-2.904999em;"><span class="pstrut" style="height:2.7em;"></span><span class="mord"><span class="mord textrm mtight sizing reset-size6 size3">A</span></span></span></span></span></span><span class="mspace" style="margin-right:-0.15em;"></span><span class="mord text"><span class="mord textrm">T</span><span class="mspace" style="margin-right:-0.1667em;"></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.46782999999999997em;"><span style="top:-2.7845em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord textrm">E</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2155em;"><span></span></span></span></span><span class="mspace" style="margin-right:-0.125em;"></span><span class="mord textrm">X</span></span></span></span></span></span> 公式 [用 &quot;$&quot; 包围]</h3> <p><strong>(注意:部分编译器会不识别部分符号)</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$\LaTeX$ 是最好用的论文排版语言! 不信你看!</span><br><span class="line">$a^n+b^n=c^n$</span><br><span class="line">$$</span><br><span class="line">%\usepackage&#123;unicode-math&#125;</span><br><span class="line">\displaystyle \ointctrclockwise\mathcal&#123;D&#125;[x(t)]</span><br><span class="line">\sqrt&#123;\frac&#123;\displaystyle3\uppi^2-\sum_&#123;q=0&#125;^&#123;\infty&#125;(z+\hat L)^&#123;q&#125;</span><br><span class="line">\exp(\symrm&#123;i&#125;q^2 \hbar x)&#125;&#123;\displaystyle (\symsfup&#123;Tr&#125;\symbfcal&#123;A&#125;)</span><br><span class="line">\left(\symbf\Lambda_&#123;j_1j_2&#125;^&#123;i_1i_2&#125;\Gamma_&#123;i_1i_2&#125;^&#123;j_1j_2&#125;</span><br><span class="line">\hookrightarrow\vec D\cdot \symbf P \right)&#125;&#125;</span><br><span class="line">=\underbrace&#123;\widetilde&#123;\left\langle \frac&#123;\notin \emptyset&#125;</span><br><span class="line">&#123;\varpi\alpha_&#123;k\uparrow&#125;&#125;\middle\vert</span><br><span class="line">\frac&#123;\partial_\mu T_&#123;\mu\nu&#125;&#125;&#123;2&#125;\right\rangle&#125;&#125;_&#123;\mathrm&#123;K&#125;_3</span><br><span class="line">\mathrm&#123;Fe&#125;(\mathrm&#123;CN&#125;)_6&#125; ,\forall z \in \mathbb&#123;R&#125;</span><br><span class="line">$$</span><br></pre></td></tr></table></figure><br /> 用 <code>$</code> 包围为单条公式,按下两个 <code>$</code> 并敲回车即生成公式块.<br /> E.G.<br /> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>LaTeX</mtext></mrow><annotation encoding="application/x-tex">\LaTeX</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.89883em;vertical-align:-0.2155em;"></span><span class="mord text"><span class="mord textrm">L</span><span class="mspace" style="margin-right:-0.36em;"></span><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.68333em;"><span style="top:-2.904999em;"><span class="pstrut" style="height:2.7em;"></span><span class="mord"><span class="mord textrm mtight sizing reset-size6 size3">A</span></span></span></span></span></span><span class="mspace" style="margin-right:-0.15em;"></span><span class="mord text"><span class="mord textrm">T</span><span class="mspace" style="margin-right:-0.1667em;"></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.46782999999999997em;"><span style="top:-2.7845em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord textrm">E</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2155em;"><span></span></span></span></span><span class="mspace" style="margin-right:-0.125em;"></span><span class="mord textrm">X</span></span></span></span></span></span> 是最好用的论文排版语言!不信你看!<br /> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mi>n</mi></msup><mo>+</mo><msup><mi>b</mi><mi>n</mi></msup><mo>=</mo><msup><mi>c</mi><mi>n</mi></msup></mrow><annotation encoding="application/x-tex">a^n+b^n=c^n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.747722em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.664392em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">c</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></p> %\usepackage{unicode-math} \displaystyle \ointctrclockwise\mathcal{D}[x(t)] \sqrt{\frac{\displaystyle3\uppi^2-\sum_{q=0}^{\infty}(z+\hat L)^{q} \exp(\symrm{i}q^2 \hbar x)}{\displaystyle (\symsfup{Tr}\symbfcal{A}) \left(\symbf\Lambda_{j_1j_2}^{i_1i_2}\Gamma_{i_1i_2}^{j_1j_2} \hookrightarrow\vec D\cdot \symbf P \right)}} =\underbrace{\widetilde{\left\langle \frac{\notin \emptyset} {\varpi\alpha_{k\uparrow}}\middle\vert \frac{\partial_\mu T_{\mu\nu}}{2}\right\rangle}}_{\mathrm{K}_3 \mathrm{Fe}(\mathrm{CN})_6} ,\forall z \in \mathbb{R} <h3 id="4-网络图床"><a class="anchor" href="#4-网络图床">#</a> 4. * 网络图床</h3> <p>(这是学长给我的网络图床教程,我并未实践过...)<br /> 分享一个 Typora 搭配腾讯云 COS / 阿里云 OSS 图床的<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b19yaWRnZXBvbGUvYXJ0aWNsZS9kZXRhaWxzLzEwODI1NzI3Nw==">例子</span>。新用户免费试用 6 个月,另外还可选择七牛云或者路过图床.</p> <h3 id="5-typora-的常用快捷键"><a class="anchor" href="#5-typora-的常用快捷键">#</a> 5. *Typora 的常用快捷键</h3> <table> <thead> <tr> <th style="text-align:center">按键</th> <th style="text-align:center">效果</th> <th style="text-align:center">按键</th> <th style="text-align:center">效果</th> </tr> </thead> <tbody> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>D</code></td> <td style="text-align:center">选中当前词</td> <td style="text-align:center"><code>Ctrl</code> + <code>L</code></td> <td style="text-align:center">选中当前句 / 行</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>E</code></td> <td style="text-align:center">选中当前区块</td> <td style="text-align:center"><code>Ctrl</code> + <code>F</code></td> <td style="text-align:center">搜索当前选中</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>B</code></td> <td style="text-align:center">加粗当前选中</td> <td style="text-align:center"><code>Ctrl</code> + <code>H</code></td> <td style="text-align:center">替换当前选中</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>I</code></td> <td style="text-align:center">倾斜当前选中</td> <td style="text-align:center"><code>Ctrl</code> + <code>U</code></td> <td style="text-align:center">下划当前选中</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>K</code></td> <td style="text-align:center">将当前选中生成链接</td> <td style="text-align:center"><code>Ctrl</code> + <code>J</code></td> <td style="text-align:center">滚动屏幕将选中滚至顶部</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>W</code></td> <td style="text-align:center">关闭当前窗口</td> <td style="text-align:center"><code>Ctrl</code> + <code>N</code></td> <td style="text-align:center">打开新窗口</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>O</code></td> <td style="text-align:center">打开文件</td> <td style="text-align:center"><code>Ctrl</code> + <code>P</code></td> <td style="text-align:center">搜索文件并打开</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>回车</code></td> <td style="text-align:center">表格下方插入行</td> <td style="text-align:center"><code>Ctrl</code> + <code>,</code></td> <td style="text-align:center">打开偏好设置</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>.</code></td> <td style="text-align:center">切换全角 / 半角标点</td> <td style="text-align:center"><code>Ctrl</code> + <code>/</code></td> <td style="text-align:center">切换正常 / 源代码视图</td> </tr> <tr> <td style="text-align:center"><code>Ctrl</code> + <code>Shift</code> + <code>-</code></td> <td style="text-align:center">缩小视图缩放</td> <td style="text-align:center"><code>Ctrl</code> + <code>Shift</code> + <code>+</code></td> <td style="text-align:center">放大视图缩放</td> </tr> </tbody> </table> <p>还有一些不常用的 / 三键的快捷键不在此列出.</p> <h3 id="6-typora-的主题样式与检查元素"><a class="anchor" href="#6-typora-的主题样式与检查元素">#</a> 6. *Typora 的主题样式与检查元素</h3> <p>Markdown 在编译后约等于 HTML. 而 Typora 的正常视图就是编译后的 Markdown, 故 Typora 的主题样式本质就是 CSS 文件.<br /> 可以下载各种好看的主题给 Typora 换上,同时也可以自己调整对应的 CSS 文件,或者自己手搓.<br /> 在 Typora 设置中开启 <code>调试模式</code> 后即可在正常视图右击打开 <code>检查元素</code> ,在其中就可以完全将 Markdown 文件当成 HTML 来编辑.</p> <h2 id="总结"><a class="anchor" href="#总结">#</a> 💯 总结</h2> <p>至此,<strong>Markdown + Typora / VSCode</strong> 的手册教程也告一段落.<br /> 不知你看完这么长的教程 / 手册,是否能体会到 Markdown 的精妙简洁之处呢?<br /> 其实 Markdown 只是标记语言的最开始,我的感受是会了 Markdown 之后对于理解 HTML 也有帮助,对于用 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>LaTeX</mtext></mrow><annotation encoding="application/x-tex">\LaTeX</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.89883em;vertical-align:-0.2155em;"></span><span class="mord text"><span class="mord textrm">L</span><span class="mspace" style="margin-right:-0.36em;"></span><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.68333em;"><span style="top:-2.904999em;"><span class="pstrut" style="height:2.7em;"></span><span class="mord"><span class="mord textrm mtight sizing reset-size6 size3">A</span></span></span></span></span></span><span class="mspace" style="margin-right:-0.15em;"></span><span class="mord text"><span class="mord textrm">T</span><span class="mspace" style="margin-right:-0.1667em;"></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.46782999999999997em;"><span style="top:-2.7845em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord textrm">E</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2155em;"><span></span></span></span></span><span class="mspace" style="margin-right:-0.125em;"></span><span class="mord textrm">X</span></span></span></span></span></span> 来写论文也有帮助。标记语言正是为了摆脱 Word 那种虽然 &quot;所见即所得&quot;, 但又过于花哨浮华,很差的兼容性与闭源的编码的缺陷。当你能掌握这样的 &quot;所写即所得&quot; 时,你肯定会感受到用 Markdown 这类语言来处理文本的妙处!</p>

2022/7/20
阅读更多

jdjwzx233的博客

<ol> <li></li> <li> <p>如无特别声明,该博客文章均为 jdjwzx233 原创,转载请遵循署名 - 非商业性使用 4.0 国际(CC BY-NC-SA)协议,即转载请注明文章来源。</p> </li> <li> <p><strong>如发现用户发布违规内容或评论,管理员将封禁其 IP 地址!(所有 jdjwzx233 的站点将不可访问。如果有误封,请联系 <a href="mailto:admin@jdjwzx233.cn">admin@jdjwzx233.cn</a> 进行申诉)</strong></p> </li> <li> <p>本博客使用 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvLw==">hexo</span> 进行搭建,采用 shoka 主题。</p> </li> <li> <p>本博客属于非商业性质的博客。</p> </li> <li> <p>如需联系 jdjwzx233,请<span class="exturl" data-url="aHR0cHM6Ly9hcGkuYnRzdHUuY24vcXF0YWxrL2FwaS5waHA/cXE9MTQzODE0ODI0Mw==">点击这里</span>,或通过添加好友的方式联系 jdjwzx233-bot(QQ: 1438148243)。在进入 QQ 后,向 jdjwzx233-bot 发送指令 &quot;!rg&quot;,即可获取 jdjwzx233 的联系方式。获取好友验证码请参考第 7 条。</p> </li> <li> <p>如果博客文章、使用的图片等侵犯了您的版权或给您带来了损失,请联系 <strong><a href="mailto:admin@jdjwzx233.cn">admin@jdjwzx233.cn</a></strong>。</p> </li> <li> <p>jdjwzx233-bot 的好友验证码为:jdjwzx233blogyyds(不定时更改)。</p> </li> <li> <p>jdjwzx233-bot 将于 2023 年二月份关闭,客服业务已经转移到 jdjwzx233-Blog 上。您现在可以通过博客右下角的咨询按钮联系 jdjwzx233-Blog 的管理员。</p> </li> <li> <p>如果喜欢 jdjwzx233-Blog,请<a href="/Subscribe">点击这里</a>订阅,获取 jdjwzx233-Blog 的最新动态。</p> </li> <li> <p>如果您访问本站,即表示您同意本站的<a href="/Privacy%20policy">隐私政策</a>、<a href="/Cookiepolicy">Cookie 政策</a>、<a href="/Term%20sand%20conditions">服务条款</a>和<a href="/Disclaimer">免责声明</a>。如果您不同意相关政策和条款,请勿访问本站。您可以联系 <strong><a href="mailto:admin@jdjwzx233.cn">admin@jdjwzx233.cn</a></strong> 删除您在本站中的一切信息(包括评论、账户、文章等)。</p> </li> <li> <p>为了尊重和保护访客和用户的隐私权,我们提供了一种方便的方式来关闭网站跟踪器。您可以在网站底部找到相应选项,以便自主选择是否接受网站跟踪。我们鼓励您在使用我们的网站时行使您的选择权,以获得更加个性化和符合您需求的浏览体验。</p> </li> <li> <p>本站点已启用腾讯云 CDN 加速,加速网址:<span class="exturl" data-url="aHR0cDovL3d3dy5qZGp3engyMzMuY24=">www.jdjwzx233.cn</span></p> </li> <li> <p>您可以使用爱发电赞助本博客的运营和开发。</p> </li> <li> <p>赞助感谢名单:<span class="exturl" data-url="aHR0cHM6Ly9zcG9uc29ybWUuamRqd3p4MjMzLmNvbS8=">https://sponsorme.jdjwzx233.com/</span></p> </li> </ol> <p><div class="links"><div class="item" title="jdjwzx233" style="--block-color:#e9546b;"><span class="exturl image" data-url="aHR0cHM6Ly9hZmRpYW4uY29tL3UvY2Q3ZjQ5ZjIwZjRiMTFlZDlmM2M1MjU0MDAyNWMzNzc=" data-background-image="https://upcdn.jdjwzx233.cn/upload/Qexo/24/11/24/logo_0bab5ae4d8eb33ed096e89d0912170f3.png"></span> <div class="info"> <span class="exturl title" data-url="aHR0cHM6Ly9hZmRpYW4uY29tL3UvY2Q3ZjQ5ZjIwZjRiMTFlZDlmM2M1MjU0MDAyNWMzNzc=">爱发电-jdjwzx233</span> <p class="desc">每月5元,感谢您的赞助</p> </div></div></div></p> <p><strong>广告</strong>:</p> <ol> <li><strong>LightNode</strong>:拥有高质量香港 CN2 GIA 节点与原生 IP (河内、曼谷、华盛顿、柬埔寨)。充值 10 美元,最多账户获得 30 美元,10 美元可用 5 个月,相当于<strong>不要钱</strong>。(<strong>支持支付宝、银联、paypal 等支付方式</strong>)。对于想用 VPS 解锁 **「Netflix、 TikTok」** 或者其他流媒体,以及对 CN2 有需求的都可以看看。官网链接:<span class="exturl" data-url="aHR0cHM6Ly93d3cubGlnaHRub2RlLmNvbS8/aW52aXRlQ29kZT1BRFFWTUomYW1wO3Byb21vdGVXYXk9TElOSw==">www.lightnode.com</span></li> <li><strong>又拍云</strong>:又拍云有非常多的优惠:加入又拍云联盟 (网站需备案,要在网站 / 应用底部添加又拍云 LOGO 并指向官网) 后,可以获得每月 10G 储存空间和 15G 的 CDN 流量 (按年发放,以 67 元的代金卷发放到账户);新用户注册 (<span class="exturl" data-url="aHR0cHM6Ly9jb25zb2xlLnVweXVuLmNvbS9yZWdpc3Rlci8/aW52aXRlPXRJOGxqaXhJVA==">点我注册</span>) 还可以直接获得 61 元的代金卷 (有效期一年)。在这些优惠的加成下,你可以零成本建站。</li> </ol> <p><strong><span class="exturl" data-url="aHR0cHM6Ly9jaWFsbG8ubXkv">Ciallo~(∠・ω&lt; )⌒★</span></strong></p>

2022/2/3
阅读更多

Hello World

<p>Welcome to <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvLw==">Hexo</span>! This is your very first post. Check <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL2RvY3Mv">documentation</span> for more info. If you get any problems when using Hexo, you can find the answer in <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL2RvY3MvdHJvdWJsZXNob290aW5nLmh0bWw=">troubleshooting</span> or you can ask me on <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2hleG9qcy9oZXhvL2lzc3Vlcw==">GitHub</span>.</p> <h2 id="quick-start"><a class="anchor" href="#quick-start">#</a> Quick Start</h2> <h3 id="create-a-new-post"><a class="anchor" href="#create-a-new-post">#</a> Create a new post</h3> <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">$ hexo new <span class="string">&quot;My New Post&quot;</span></span><br></pre></td></tr></table></figure></p> <p>More info: <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL2RvY3Mvd3JpdGluZy5odG1s">Writing</span></p> <p>也可以手动添加文档 -&gt; 文件名.md 放入:主文件夹 /source/_posts/ 中。</p> <p><strong>一定要在文档开头添加:</strong><br /> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: 文章的标题</span><br><span class="line">date: 2022-01-01 01:01:01</span><br><span class="line">categories:</span><br><span class="line">- [博客的分类1]</span><br><span class="line">- [博客的分类2]</span><br><span class="line">- [博客的分类3]</span><br><span class="line">tags:</span><br><span class="line">- 标签1</span><br><span class="line">- 标签2</span><br><span class="line">---</span><br><span class="line">这里开始使用Markdown书写博客正文</span><br></pre></td></tr></table></figure><br /> <strong> 否则会出现问题!!!</strong></p> <h3 id="run-server"><a class="anchor" href="#run-server">#</a> Run server</h3> <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">$ hexo server</span><br></pre></td></tr></table></figure></p> <p>More info: <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL2RvY3Mvc2VydmVyLmh0bWw=">Server</span></p> <h3 id="generate-static-files"><a class="anchor" href="#generate-static-files">#</a> Generate static files</h3> <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">$ hexo generate</span><br></pre></td></tr></table></figure></p> <p>More info: <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL2RvY3MvZ2VuZXJhdGluZy5odG1s">Generating</span></p> <h3 id="deploy-to-remote-sites"><a class="anchor" href="#deploy-to-remote-sites">#</a> Deploy to remote sites</h3> <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">$ hexo deploy</span><br></pre></td></tr></table></figure></p> <p>More info: <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL2RvY3Mvb25lLWNvbW1hbmQtZGVwbG95bWVudC5odG1s">Deployment</span></p>

2022/2/2
阅读更多