G

gorpeln的个人博客 - gorpeln

gorpeln的个人博客(https://gorpeln.top/)是一个追求简洁、高效,专注记录生活点滴、分享技术成长、共享实用资源的个人优秀博客!趁年轻,做自己想做的!欢迎你来这里交流互动,一起探索精彩世界,开启知识与心灵的非凡旅程。

免费领取Synology C2的30G对象存储空间

<h3 id="前言">前言</h3> <p>今天继续为大家分享一款实用的免费云存储服务——Synology C2 对象存储。该服务提供与 <code class="language-plaintext highlighter-rouge">S3协议</code> 兼容的对象存储能力,具备企业级的数据安全性,定价透明,并与 Synology NAS 设备深度整合,适合中小团队或企业用户搭建云存储基础设施。</p> <p>更重要的是,它支持<strong>免费套餐,无需认证</strong>即可使用,每个区域提供<strong>15GB存储空间</strong>和<strong>15GB下载流量</strong>。当前可选区域共两个,总计可享<strong>30GB存储</strong> + 30GB下载流量。</p> <h3 id="synology-c2对象存储">Synology C2对象存储</h3> <h4 id="注册账号">注册账号</h4> <p>点击下方链接注册账号,也可以直接用Google邮箱快捷登录:<br /> <a href="https://account.synology.com/en-global/register/quick/a62fb91981af4796b902b525c8b216c5?lang=en-global">https://account.synology.com/en-global/register/quick/a62fb91981af4796b902b525c8b216c5?lang=en-global</a></p> <h4 id="创建桶">创建桶</h4> <p>注册登录后进入:<a href="https://c2.synology.com/en-global/object-storage/overview">https://c2.synology.com/en-global/object-storage/overview</a><br /> 点击【Get 15 GB for free】 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157741.jpg" alt="20260215085157741" /></p> <p>控制台界面很简洁哈,直接在 <code class="language-plaintext highlighter-rouge">Buckets</code> 栏目中【创建桶】 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157742.jpg" alt="20260215085157742" /></p> <ol> <li> <p>创建存储桶基础信息 <code class="language-plaintext highlighter-rouge">Bucket name</code> 是必须的。<strong>Create Access Key</strong> 是指单独为这个存储桶创建一个访问的密钥,这里我们点击勾选方便一会使用,一定要备份记住密钥,然后点击【Next】 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157743.jpg" alt="20260215085157743" /></p> </li> <li> <p>数据保护设置 下面的步骤就是是否开启桶的版本控制,和桶对象锁。这两项是保证数据安全的,建议开启。或者根据你自己的需求来,可以都勾选上,也可以不勾选。然后点击【create bucket】按钮。 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157744.jpg" alt="20260215085157744" /></p> </li> <li> <p>备份密钥 创建完成会展示 Access Key ID 与 Secret Key,密钥关闭窗口后无法再次查看,务必复制或下载备份。 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157745.jpg" alt="20260215085157745" /></p> </li> <li> <p>查看桶Endpoint 存储桶创建完成后,桶列表右侧可查看对应区域Endpoint地址: <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157746.jpg" alt="20260215085157746" /></p> </li> <li> <p>进入桶内可创建文件夹、上传文件,支持查看历史版本、清理分片上传碎片释放空间。 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157747.jpg" alt="20260215085157747" /></p> </li> </ol> <h3 id="跨区域开通免费额度">跨区域开通免费额度</h3> <p>每个区域的免费资源(15G存储+15G流量)需单独激活。 控制台右上角切换区域,可选:</p> <ul> <li>North America - Seattle</li> <li>Europe - Frankfurt</li> </ul> <p>切换未开通免费额度的区域,即可再次领取15GB存储+15GB流量,两个区域合计30GB存储+30GB下载流量;已开通区域不会再显示激活入口。 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157748.jpg" alt="20260215085157748" /></p> <h3 id="搭配图床cloudflare-imgbed">搭配图床:CloudFlare-ImgBed</h3> <p>在图片上传客户端的选择上,推荐 MarSeventh 开源的 <code class="language-plaintext highlighter-rouge">CloudFlare-ImgBed</code>,界面简洁直观,可免费部署在CloudFlare,也支持Docker一键部署,兼容多存储后端。</p> <p>不推荐PicGo/PicList原因:Synology C2桶默认私有,直链访问存在不便;替代方案还有OpenList等可自行尝试。</p> <h4 id="1搭建cloudflare-imgbed">1、搭建CloudFlare-ImgBed</h4> <p>搭建教程可参考往期文章:<a href="/article/17687280368">用HuggingFace搭建100G超大图床</a></p> <h4 id="2synology-c2-存储信息配置">2、Synology C2 存储信息配置</h4> <p>1). 进入 <code class="language-plaintext highlighter-rouge">CloudFlare-ImgBed</code> 系统后台,在系统设置中,点击【系统设置】-&gt;在【上传设置】中添加上传渠道。如下 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157749.jpg" alt="20260215085157749" /></p> <p>2). S3渠道填写参数对照表</p> <table> <thead> <tr> <th>填写项</th> <th>填写内容</th> </tr> </thead> <tbody> <tr> <td>渠道类型</td> <td>S3</td> </tr> <tr> <td>渠道名称</td> <td>自定义如:synology-1</td> </tr> <tr> <td>Endpoint</td> <td>创建桶的endpoint(例:https://us-004.s3.synologyc2.net)</td> </tr> <tr> <td>存储桶名称</td> <td>自己创建的桶名</td> </tr> <tr> <td>存储桶区域</td> <td>对应区域标识(例:us-004)</td> </tr> <tr> <td>访问密钥 ID</td> <td>备份的Access key ID</td> </tr> <tr> <td>机密访问密钥</td> <td>备份的Secret key</td> </tr> <tr> <td>容量限制</td> <td>15GB</td> </tr> <tr> <td>停用阙值</td> <td>95%</td> </tr> <tr> <td>CDN域名</td> <td>可选,有自有CDN可填写,加速访问</td> </tr> </tbody> </table> <p>填写界面参考: <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157750.jpg" alt="20260215085157750" /></p> <p>3). 首页上传配置 回到首页右下角【上传设置】,上传渠道选择刚刚新增的S3渠道,自定义上传目录、文件命名规则、图片压缩等参数,保存后即可拖拽粘贴上传图片。 <img src="https://img.gorpeln.top/blog/2026/17711167178/20260215085157751.jpg" alt="20260215085157751" /></p> <h3 id="总结">总结</h3> <p><strong>Synology C2 对象存储</strong>免费套餐优势:</p> <ol> <li>无需实名认证,门槛低;</li> <li>单区域15GB存储+15GB下载流量,双区域合计30GB存储+30GB流量;</li> <li>标准S3协议兼容,各类S3客户端/图床工具通用;</li> <li>企业级安全:桶版本控制、对象锁防误删覆盖;</li> <li>可用于个人图床、文件网盘、小型团队文件存储。</li> </ol> <p>操作简单,新手也能快速上手搭建专属图床/网盘。</p>

2026/2/15
阅读更多

用HuggingFace搭建100G超大图床

<p>今天要分享一个超级实用的黑科技教程——如何利用 HuggingFace 免费搭建一个 100G 的图床和网盘,而且全程无需实名认证,操作简单,小白也能轻松上手!</p> <p>这个项目其实是一个开源的“宝藏”,名字叫 CloudFlare-ImgBed,是一个基于 Cloudflare Pages 打造的文件托管平台。它不仅完全免费,还非常稳定高效,目前在 GitHub 上已经收获了超过 4k 的 star,热度非常高!项目的作者是 MarSeventh 大佬,不得不说,这个设计真的很良心。</p> <p>它支持多种存储方式,配置灵活,可以满足不同场景下的需求。无论是做图床、分享文件,还是搭建个人小网盘,都非常方便。话不多说,咱们直接进入正题,开搞!</p> <h3 id="项目预览">项目预览</h3> <p>官方文档:<a href="https://cfbed.sanyue.de/">https://cfbed.sanyue.de/</a><br /> 演示站点:<a href="https://cfbed.1314883.xyz/">https://cfbed.1314883.xyz/</a> 访问密码:cfbed<br /> 我自己搭建的实例:<a href="https://imgbed.202090.xyz/">https://imgbed.202090.xyz/</a></p> <p>前台界面<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036871.jpg" alt="20260118172036871" /> 后台界面<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036872.jpg" alt="20260118172036872" /></p> <h3 id="技术架构">技术架构</h3> <p>采用了<strong>前后端分离</strong>的架构:</p> <ul> <li><strong>前端</strong>:基于 Vue.js 开发,界面响应式,用起来很流畅。</li> <li><strong>后端</strong>:跑在 Cloudflare Workers 上,无服务器架构,省心又省钱。</li> <li><strong>存储层</strong>:支持多种存储后端,包括 Telegram、R2、S3、Discard,以及我们今天要用到的 HuggingFace。</li> <li><strong>元数据管理</strong>:统一通过 Cloudflare KV 进行管理,数据清晰又高效。</li> </ul> <p>简单来说,就是通过 Cloudflare 的强大边缘网络,把 HuggingFace 的 100G 免费存储空间利用起来,变成一个私人的图床或网盘。</p> <h3 id="项目部署">项目部署</h3> <p>作者提供了两种部署方式:一种是 Cloudflare Pages 托管(推荐,免费),另一种是 Docker 部署(适合有服务器的朋友),本博客仅展示 Cloudflare Pages 托管方式。</p> <p>首先 fork 源码仓库:<a href="https://github.com/MarSeventh/CloudFlare-ImgBed">https://github.com/MarSeventh/CloudFlare-ImgBed</a> 到自己的 GitHub 。如果有更新就可以直接将更新的立马部署到 Cloudflare Pages 上。</p> <p>1、在控制面板找到【计算和AI】然后点击【Worker and Pages】在页面的右上角点击【创建应用程序】,然后点击下面的想要部署 Pages?的【开始按钮】。如下图<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036873.jpg" alt="20260118172036873" /></p> <p>2、在 “导入现有 Git 存储库” 处点击 “开始使用”<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036874.jpg" alt="20260118172036874" /></p> <p>3、选择【CloudFlare-ImgBed】项目,然后点击【开始设置】按钮<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036875.jpg" alt="20260118172036875" /></p> <p>4、项目名称自定义,然后构建命令填入: npm install ,其他默认,点击【保存并部署】<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036876.jpg" alt="20260118172036876" /></p> <p>5、配置数据库</p> <blockquote> <p>数据库用于存储文件元数据,是必需的组件,可选数据库为 KV 数据库和 D1 数据库。两者对比如下表所示,根据自己使用场景从其中选择一种配置即可。</p> <p>重要提示:KV 数据库和 D1 数据库<strong>只需要配置其中一个即可</strong>,不需要同时配置两个!建议根据下表选择适合自己的数据库类型。</p> </blockquote> <table> <thead> <tr> <th>特点</th> <th>KV 数据库</th> <th>D1 数据库</th> </tr> </thead> <tbody> <tr> <td>读写性能</td> <td>高</td> <td>较低</td> </tr> <tr> <td>免费额度</td> <td>少</td> <td>多</td> </tr> </tbody> </table> <p>在【存储和数据库】-&gt;【workers KV】添加KV数据库,KV名称填写 img_url<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036877.jpg" alt="20260118172036877" /></p> <p>如果要使用D1数据库,就在【存储和数据库】-&gt;【D1 SQL数据库】,点击右上角的【创建数据库实例】,这里就不做详细说明了。</p> <p>6、将数据库绑定到项目上。</p> <p>在Workers and Pages中点击刚刚部署好的项目,在面板中找到【设置】选项,点击绑定按钮,添加绑定KV数据库的信息如下。点击保存以后,项目会重新部署。</p> <ul> <li>变量名称:<code class="language-plaintext highlighter-rouge">img_url</code></li> <li>KV命名空间:<code class="language-plaintext highlighter-rouge">img_url</code></li> </ul> <p><img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036878.jpg" alt="20260118172036878" /></p> <p>7、重新部署以后,就可以使用CloudFlare分配的域名访问了,当然建议绑定自己的域名 <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036879.jpg" alt="20260118172036879" /></p> <h3 id="huggingface注册">HuggingFace注册</h3> <blockquote> <p>官方地址:https://huggingface.co <br /> <em>HuggingFace 渠道支持大文件直传,适合上传超过 20MB 的文件。对于大文件,系统会自动使用 LFS 协议进行分片上传。</em></p> </blockquote> <p>1、注册登陆后,在控制面板新建一个新空间,空间名字自定义。<br /> <strong>Select the Space SDK</strong> 选择 <strong>docker</strong> 的空项目或者是其他<br /> <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036880.jpg" alt="20260118172036880" /></p> <p><strong>Space hardware</strong>选择<code class="language-plaintext highlighter-rouge">FREE</code>版本不要钱的。空间的可见性也是根据你自己的意向选择就好了 然后点击下面的【Create Space 】按钮 <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036881.jpg" alt="20260118172036881" /></p> <p>2、创建 <a href="https://huggingface.co/settings/tokens">HuggingFace Access Token</a>,在【Setting】中的【Access Tokens】中点击【Create New Token】就行了,token的名称自定义,然后勾选仓库的读写权限,如下。 <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036882.jpg" alt="20260118172036882" /></p> <h3 id="存储配置">存储配置</h3> <p>1、进入CloudFlare-ImgBed系统后台,在系统设置中,点击【系统设置】-&gt;在【上传设置】中添加上传渠道。如下 <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036883.jpg" alt="20260118172036883" /></p> <p>2、添加一个HF存储的渠道方式,渠道名称自定义,然后仓库名称一定是 用户名/仓库名 的格式,然后填入上面申请的Acess Token信息。点击保存就行了。 <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036884.jpg" alt="20260118172036884" /></p> <p>3、在系统设置中,点击【系统设置】-&gt;【页面设置】中去配置默认上传渠道信息和其他的配置就行了,如下。 <img src="https://img.gorpeln.top/blog/2026/17687280368/20260118172036885.jpg" alt="20260118172036885" /></p> <p>你也可以增加其他的上传渠道,还可以开启负载均衡!</p> <h3 id="总结">总结</h3> <p>这个方案是不是超级香?不需要实名认证,访问速度还杠杠的,最关键的是——完全免费!100G 的 HuggingFace 空间,加上 Cloudflare 的全球加速,无论是放博客图片、分享文件,还是当个人网盘,都绰绰有余。</p> <p>而且全程无需自己买服务器、不用装任何客户端,只要有个 GitHub 账号和 Cloudflare 账号就能搞定。还要什么自行车?赶紧去搭建一个吧!</p>

2026/1/18
阅读更多

毫无破绽的自我批评

<p>在工作自评中,我们总会陷入两难:不谈缺点显得虚伪,坦诚不足又怕被否定能力。其实很多所谓的 “短板”,不过是自我要求过高、追求极致过程中产生的副作用。于是我梳理了这份特殊的自我剖析,将职场自评的痛点转化为高标准下的完美主义瑕疵,找到最得体又真实的自我表达方式。</p> <p><strong>1、</strong>工作推进偏保守,习惯于按部就班完成流程,主动突破、大胆尝试的意识不足,导致部分工作推进不够高效,创新亮点不多。</p> <p><strong>2、</strong>业务钻研不够深入,满足于把日常事务处理到位,主动钻研新流程、新方法的劲头不足,专业能力提升速度跟不上岗位要求。</p> <p><strong>3、</strong>工作思考不够靠前,多是被动落实任务,主动提前谋划、提前预判的意识较弱,对工作整体节奏把控不够精准。</p> <p><strong>4、</strong>细节把控不够严格,完成任务时更注重速度,对质量、细节打磨不够,精益求精的意识有待加强。</p> <p><strong>5、</strong>重点工作聚焦不够,日常事务占用精力较多,对核心工作的持续跟进、深度推进力度不足,成效不够突出。</p> <p><strong>6、</strong>沟通衔接不够主动,与同事、协作方的沟通多停留在事务层面,深入交流思路、共同优化工作的频次偏少,协作效率有待提升。</p> <p><strong>7、</strong>经验沉淀不够系统,做完工作后复盘梳理不及时,好的做法没有及时固化,问题没有提前规避,重复消耗精力。</p> <p><strong>8、</strong>落实力度不够扎实,安排部署后跟踪问效不够,对过程中的新情况、新问题掌握不及时,解决问题的及时性不足。</p> <p><strong>9、</strong>工作标准要求较高,有时过于追求细节完美,在统筹推进速度与质量平衡上把握不够到位,一定程度上影响了整体工作效率。</p> <p><strong>10、</strong>对待工作责任心较强,凡事习惯亲力亲为、把关到底,在合理分工、放手放权方面思考不够,导致自身精力分散、统筹压力较大。</p> <p><strong>11、</strong>工作态度较为严谨,对任务完成质量要求较高,有时容易陷入局部细节纠结,对整体工作的宏观统筹和节奏把控仍需进一步加强。</p> <p><strong>12、</strong>自我要求相对严格,习惯于对标更高标准找差距,在及时总结成绩、提炼亮点方面重视不够,工作成果展示不够充分。</p>

2025/12/14
阅读更多

时光本的故事 - 始于热爱,归于珍藏

<p>大家好,我是<code class="language-plaintext highlighter-rouge">时光本</code>的开发者,<em class="color-gray">时光本是一款专注效率与记录的笔记工具。可以帮助你整理各种信息,包括便签、清单、图片、纪念日、地址、链接、银行卡、名片、账号、密码等</em>。今天想和大家聊聊这款 APP 从诞生到即将下线的全过程 —— 没有什么高大上的商业计划,只是一个技术人 “折腾” 出来的小成果,以及一些想和用户说的真心话。</p> <h3 id="一为什么会做时光本">一、为什么会做时光本?</h3> <p>我本身是 iOS 端开发,2020 年的时候,主要抱着两个想法开始做这个 APP:</p> <ul> <li>一是想给自己攒一个 “拿得出手的个人项目”—— 毕竟做开发的都知道,找工作或者职场进阶时,光有公司项目不够,一个完整的个人作品,能更直观体现自己的技术思路和执行力,相当于给简历加了个 “加分项”;</li> <li>二是真的被 “记东西” 这件事烦透了:既要记账号密码、银行卡信息这种敏感数据,又想存日常看到的优美句子、突发的灵感,或者随手记点生活小事。但当时找了一圈,要么是功能太单一的备忘录,要么是第三方工具 —— 满是广告,用起来闹心;核心功能要收费,性价比不高,还总担心隐私泄露。完全不符合我对 “简洁、免费、安全”APP 的追求,干脆自己动手做一个。</li> </ul> <p>所以时光本从一开始就设计了两大模块:一个管 “笔记”,能存日常灵感、纪念日、银行卡信息、名片、网址这些;另一个管 “账号密码”,专门用来安全存储各类登录信息,就是想一次性解决 “记东西麻烦” 的问题。</p> <h3 id="二一个人扛下所有流程">二、一个人,扛下所有流程</h3> <p>很多人问我,个人开发一个全平台 APP 难吗?说实话,难,但难的不是写代码。</p> <p>我虽然做 iOS 开发,但产品设计、UI、交互、推广这些完全是门外汉。为了让时光本 “像个正经 APP”,我逼着自己走完了完整的开发流程:</p> <ul> <li><code class="language-plaintext highlighter-rouge">需求调研</code>:先列了自己和身边朋友的痛点 —— 要能记密码、便签、纪念日、银行卡;要苹果多端能用;要安全不泄露数据。</li> <li><code class="language-plaintext highlighter-rouge">原型与设计</code>:先后画了好几版原型图,最终确定各个页面的功能模块。接着学 Sketch 做 UI,为了一个简洁的 icon,改了三十多版才满意;按钮的颜色、弹窗的圆角,甚至文字的字号,都反复调过,就想让用户打开时觉得 “舒服不刺眼”。</li> <li><code class="language-plaintext highlighter-rouge">交互设计</code>:用 Axure 模拟用户操作 —— 比如添加银行卡时,要先选卡类型再填卡号,避免字段混乱;输入密码后,要有 “隐藏 / 显示” 按钮;解锁时,指纹识别失败要弹友好提示,而不是冷冰冰的报错。这些细节,我对着自己的使用习惯改了又改,就怕用户用的时候觉得 “不顺手”。</li> <li><code class="language-plaintext highlighter-rouge">多端开发</code>:作为iOS开发,iOS端的开发 <em class="color-gray">(主要包括iCloud云同步,本地通知、远程推送,分享,统计,安全锁(指纹/面部、数字密码、图形密码),账号排序、搜索,扫一扫、证书申请、上线、谷歌广告、内购等)</em>,没遇到太大麻烦;但 MacOS 端因为涉猎较少,网上资料也较少的情况下,我只能下班和周末啃官方文档,从基础语法开始学,遇到同步 bug 时,熬夜查论坛、试代码,终于打通了 iPhone、iPad、Mac 的 iCloud 同步 —— 虽然切换设备要登 iCloud,但至少数据能无缝衔接了。</li> <li><code class="language-plaintext highlighter-rouge">测试与上线</code>:没有测试团队,就自己测:单元测试保证每个功能不崩,集成测试确认多端同步不会丢数据,还找了十几个朋友试用,比如有朋友说 “Mac 端同步慢”,我就优化了 iCloud 的同步策略;有人说 “想给笔记分类”,我就加了标签功能。最后提交 App Store 审核时,连截图的尺寸、描述的关键词都改了五遍,终于在 2020 年 1 月 22 日上线了。</li> </ul> <p>上线后,我没做过什么推广,全靠用户口口相传。看到有人说 “时光本帮我记住了奶奶的生日”“再也不用怕忘银行卡密码了”,那种开心,比涨工资还爽。</p> <h3 id="三为什么决定让时光本下线">三、为什么决定让时光本下线?</h3> <p>其实不是时光本不好用,而是我发现了它的 “局限性”:</p> <ul> <li>多端切换麻烦:虽然打通了苹果生态,但切换设备要登 iCloud,有些用户觉得麻烦,甚至担心账号安全;我自己平时也用安卓和 PC,跨系统看数据时,得先打开 Mac 同步 iCloud,再转到手机,真的很折腾。</li> <li>使用频率不高:账号密码、笔记这种东西,记一次可能好久才会看一次,专门下载个 APP 放在手机里,总觉得 “大材小用”—— 需要的时候找半天,反而不方便。</li> </ul> <p>后来我琢磨,要是把时光本的功能移到 H5 网页端,会不会更方便?不用下载 APP,不管用什么设备,打开网页登一次密码 <em class="color-gray">(之后会用缓存保持登录,除非手动登出)</em>,就能直接看数据,刚好解决了 “偶尔用但要用得顺” 的问题。</p> <p>不过,H5 网页端暂时没开放给普通用户:</p> <ul> <li>一来,隐私数据不能存在我的服务器里,需要用户自己搞数据库,这对很多人来说成本高、门槛高;</li> <li>二来,部署流程还有技术门槛,很多人可能无法操作。所以目前我在整理文档,慢慢优化流程,要是以后能把门槛降下来,说不定会以更方便的样子和大家见面。</li> </ul> <h3 id="四关于数据导出我想跟大家说声-放心">四、关于数据导出,我想跟大家说声 “放心”</h3> <p>决定下线后,我最担心的就是用户的数据丢了。所以特意写了详细的<a href="/article/17529840977">时光本数据导出指南</a>:</p> <p>为确保数据安全,我准备了 iOS <em class="color-gray">(适用于 iPhone)</em> 和 macOS <em class="color-gray">(适用于 Mac 电脑)</em> 版本的图文导出流程,操作中若有疑问,请留言,我会协助你完成迁移 —— 毕竟,时光本里存的不是数据,是大家的回忆和重要信息,我得帮大家守好。</p> <h3 id="五最后想说的话">五、最后想说的话</h3> <p>从 2020 年到 2026 年,时光本陪了大家六年。它不是什么爆款 APP,却有一群每天打开的忠实用户;它没有团队运营,却收到了无数暖心的反馈。</p> <p>对我来说,时光本不只是一个项目,更是我作为 iOS 开发者的成长印记 —— 从只会写前端代码,到学会设计、交互、多端开发,每一步都藏在时光本的版本更新里。</p> <p>虽然时光本要下线了,但我没有放弃 “做好用的记录工具” 的想法。以后不管是优化 H5,还是做新的小工具,我都会保持这份初心:做简洁、安全、真正帮到人的东西。</p> <p>最后,谢谢每一位用过时光本的人。谢谢你们包容它的不完美,谢谢你们给我的反馈,谢谢你们让我的 “折腾” 有了意义。</p> <p>时光本会停在这里,但我们记录生活的方式,永远不会停。 <br /> 祝大家,都能找到适合自己的 “时光容器”,好好记住那些重要的人和事。</p> <p><br /></p> <hr /> <p><br /></p> <p><strong>时光本内容汇总:</strong></p> <ul> <li><a href="https://gorpeln.top/notes">时光本-日记本·笔记本·记事本·备忘录</a></li> <li><a href="https://gorpeln.top/article/17529840977">时光本 - 数据导出</a></li> <li><a href="https://gorpeln.top/article/17529840360">时光本 - 下线公告</a></li> <li><a href="https://gorpeln.top/article/17372028582">Mac应用发布错误:ITMS-91109</a></li> <li><a href="https://gorpeln.top/article/15945227879">时光本 - 常见问题</a></li> <li><a href="https://gorpeln.top/article/15942881574">如果打开iCloud同步 - 时光本</a></li> <li><a href="https://gorpeln.top/help/app/privacy">隐私政策 - 时光本</a></li> <li><a href="https://gorpeln.top/help/app/service">用户服务条款 - 时光本</a></li> <li><a href="https://gorpeln.top/help/app/vip">会员服务协议 - 时光本</a></li> </ul>

2025/11/29
阅读更多

给博客图片添加水印

<p>本文分享一种基于对象存储+CDN的组合方案,可实现免费10G存储+无限流量的图片外链,同时配置自动水印功能,该方法理论适用于所有对象存储与 CDN 的搭配。</p> <h3 id="一核心思路">一、核心思路</h3> <p>以又拍云存储 + 腾讯云EdgeOne为例,通过对象存储存放图片并配置图片处理规则,再借助 CDN 的 URL 重写功能,实现访问图片时自动添加水印,且无需手动给每张图片链接加后缀。此方案不仅能避免图片被盗用,还能有效控制流量成本。</p> <h3 id="二操作步骤">二、操作步骤</h3> <h4 id="一对象存储端配置图片水印处理规则">(一)对象存储端:配置图片水印处理规则</h4> <p>1). 选择任意对象存储 <em class="color-gray">(本文以又拍云为例)</em>作为图床,可直接上传图片或通过图床程序上传。<br /> 2). 在对象存储后台找到图片处理功能,选择间隔标识符,又拍云提供 <code class="language-plaintext highlighter-rouge">! _ -</code> 三种可选。</p> <p><img src="https://img.gorpeln.top/blog/2025/17594958674/20251003205107691.png" alt="20251003205107691" /></p> <p>3). 创建图片处理规则,按需配置参数:</p> <ul> <li>1.若上传前已对图片做过压缩、格式转换等处理,建议仅开启添加水印功能。</li> <li>2.支持文字水印或图片水印,设置水印位置及相关参数。</li> </ul> <p><img src="https://img.gorpeln.top/blog/2025/17594958674/20251003205107692.jpg" alt="20251003205107692" /></p> <p>4). 点击预览按钮确认水印效果,满意后保存规则,务必记录规则名称 <em class="color-gray">(如示例中的 shuiyin)</em>,后续配置会用到。</p> <p>到此就可以进行实际图片测试了,比如原来的图片外链是<a href="https://img.gorpeln.top/gorpeln.png">https://img.gorpeln.top/gorpeln.png</a>,加上前面设置的图片处理参数之后的格式就是<a href="https://img.gorpeln.top/gorpeln.png!gorpeln">https://img.gorpeln.top/gorpeln.png-shuiyin</a>,这样其实还是没有达到目的,因为访问不带图片处理规则的原链接,还是没有水印效果的,想要最终实现不加参数又能加上水印,这就要去CDN加速那边设置了。</p> <h4 id="二cdn-端配置-url-重写实现自动水印">(二)CDN 端:配置 URL 重写实现自动水印</h4> <p>1). 进入腾讯云 EdgeOne 后台,找到图床域名对应的规则引擎。 <br /> 2). 配置回源 URL 重写规则,参数设置如下:</p> <ul> <li>1.正则表达式:<code class="language-plaintext highlighter-rouge">^/(.*\.(jpg|jpeg|png|gif|webp|bmp))$</code> <em class="color-gray">(可根据实际使用的图片格式增减后缀)</em></li> <li>2.替换为:<code class="language-plaintext highlighter-rouge">/$1-shuiyin</code> <em class="color-gray">(其中 - 为步骤 2 选择的间隔标识符,shuiyin 为步骤 4 保存的规则名称)</em></li> <li>3.配置完成后,清除该 CDN 域名的缓存,刷新文章中的图片外链,即可实现无后缀自动添加水印。</li> </ul> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>正则表达式: ^/(.*\.(jpg|jpeg|png|gif|webp|bmp))$ (这里加上实际使用的图片格式的后缀) 替换为: /$1-shuiyin (这里的-就是上面设置的间隔标识符,shuiyin就是上面设置的图片处理规则的名称) </code></pre></div></div> <p><img src="https://img.gorpeln.top/blog/2025/17594958674/20251003205107693.png" alt="20251003205107693" /></p> <h3 id="三方案优势">三、方案优势</h3> <ol> <li>批量生效:无需手动修改每张图片的外链后缀,所有匹配格式的图片均自动添加水印。</li> <li>灵活调整:后续如需更换水印样式或域名,仅需修改对象存储的水印规则,原图片文件不受影响。</li> <li>跨平台适配:亲测七牛云等其他对象存储,按相同逻辑配置均可实现同等效果。</li> </ol> <h3 id="四流量成本控制技巧">四、流量成本控制技巧</h3> <p>很多使用对象存储的博主会因流量被刷产生高额账单,核心解决办法是做好防护配置:</p> <ol> <li>选用不限量流量的 CDN <em class="color-gray">(如腾讯云 EdgeOne、ESA)</em>,采用 HTTP 回源 方式对接对象存储 <em class="color-gray">(HTTPS 回源可能产生额外费用)</em>。</li> <li>可搭配支持达量拉闸功能的 CDN <em class="color-gray">(如多吉云)</em>,避免流量超额产生欠费。</li> <li>以又拍云联盟为例,每年 61 元优惠券即可满足需求,按此方案配置后,年花费可控制在 1 元以内。</li> </ol>

2025/10/3
阅读更多

博客CDN流量异常

<p>今天打开博客查看时显示异常,提示<code class="language-plaintext highlighter-rouge">connection reset by peer</code>。通过控制台数据回溯发现,9 月 26 日 - 9 月 30 日期间,博客流量已出现明显异常波动:访问请求量远超日常均值,且来源 IP 分散、访问行为不符合正常用户逻辑,初步判断为恶意流量攻击。所幸此前已针对博客安全做了基础防护配置 —— 开启了IP访问频率限制与流量封顶限制,所以在本次攻击中损失较小。</p> <p><img src="https://img.gorpeln.top/blog/2025/17592227011/20250930165821910.png" alt="20250930165821910" /></p> <p>在检测到持续的异常流量后,CDN系统触发了安全防护机制,对博客访问进行了临时限制,但由于我此前未开启又拍云的异常事件短信/邮件提醒功能,未能第一时间收到预警,导致发现问题时已出现访问中断。截至目前,博客访问链路完全恢复,经测试各项功能均正常可用。</p> <p>最后建议平时做好防护,避免出现损失:</p> <ul> <li>CDN 关键配置必到位:开启「异常提醒」 <em class="color-gray">(短信 + 邮件)</em>,避免错过预警;同时设置 IP 访问频率限制 <em class="color-gray">(如单 IP1 分钟≤60 次)</em>、流量封顶,再给静态资源加 URL 鉴权,筑牢基础防护。</li> <li>定期看数据识异常:每周花几分钟查流量,记住正常 IP 地域、请求时段 <em class="color-gray">(如博客晚间高峰)</em>,若出现海外 IP 突增、凌晨流量异常,及时排查。</li> <li>做好兜底应急准备:每周备份网站数据 <em class="color-gray">(本地 + 云盘)</em>,留存 CDN 服务商紧急联系方式;提前配置临时备用页,避免访问异常时读者误解。</li> </ul>

2025/9/30
阅读更多

一路生花

<p>一路生花</p> <p>唱:温奕心 <br /> 词:宋普照<br /> 曲:张博文</p> <p>海上的晚霞像年少的画<br /> 铺在天空等海鸥衔走它<br /> 遥远的帆任风浪拍打<br /> 为梦再痛也不会害怕<br /> 远走的风沙去谁的天涯<br /> 春天可曾在哪里见过他<br /> 时间的手抚过了脸颊<br /> 他们谁都沉默不说话<br /> 我希望许过的愿望一路生花<br /> 护送那时的梦抵挡过风沙<br /> 指尖的樱花如诗写谁的韶华<br /> 疯狂的热爱夹带着文雅<br /> 我希望许过的愿望一路生花<br /> 将那雨中的人藏在屋檐下<br /> 岁月在冲刷逆流沧桑的喧哗<br /> 安静的夜晚你在想谁吗<br /> 远走的风沙去谁的天涯<br /> 春天可曾在哪里见过他<br /> 时间的手抚过了脸颊<br /> 他们谁都沉默不说话<br /> 我希望许过的愿望一路生花<br /> 护送那时的梦抵挡过风沙<br /> 指尖的樱花如诗写谁的韶华<br /> 疯狂的热爱夹带着文雅<br /> 我希望许过的愿望一路生花<br /> 将那雨中的人藏在屋檐下<br /> 岁月在冲刷逆流沧桑的喧哗<br /> 安静的夜晚你在想谁吗<br /> 我希望许过的愿望一路生花<br /> 护送那时的梦抵挡过风沙<br /> 指尖的樱花如诗写谁的韶华<br /> 疯狂的热爱夹带着文雅<br /> 我希望许过的愿望一路生花<br /> 将那雨中的人藏在屋檐下<br /> 岁月在冲刷逆流沧桑的喧哗<br /> 安静的夜晚你在想谁吗<br /> 安静的夜晚你在想谁吗</p> <p><br /></p> <style> .post-content{ text-align: center; } </style>

2025/9/13
阅读更多

10 周年:时光为证,与你共赴新程

<p>在博客十年之际,写一篇纪念博文很有必要。博主苦思冥想写了一篇类似 <a href="/article/15981552003">5周年</a> 和 <a href="article/16927632006">8周年</a> 的博文,但是思前想后,感觉过于书面,不接地气,你也没有阅读的兴趣,就改用了现在的问答形式,简明扼要的展示想表达的内容。用来总结十年的风雨征程和见闻感悟,下一个十年,愿我们依然,对技术保持敬畏,对未知渴求探索。<br /><br /></p> <div id="blog-problem"> <p id="blog-problem-title">博客最初搭建的时间?</p> <p id="blog-problem-des">2015年08月23日,时光飞逝,从大学毕业前搭建到现在已过去10个年头了。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">最初为什么搭建博客?</p> <p id="blog-problem-des">学即将毕业走入职场时,老师说计算机专业学生出去找工作如果有一个自己的博客,将会为自己的面试加分,为了找工作轻松,在懵懂中搭建了自己的博客。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">博客能否为自己求职加分呢?</p> <p id="blog-problem-des">能的,在同等情况下,面试官一般都会优先选择你的,因为博客是你的“专业能力 + 学习习惯 + 思维深度 + 个人特质”的综合证明,比一纸简历更有说服力,尤其是刚毕业,没有丰富的工作经验的同学。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">现在还有写博客的必要吗?</p> <p id="blog-problem-des">有的,现在许多大的网站,小编为了完成KPI或流量,生产出大量“洗稿”或拼凑出来的内容,内容质量一言难尽,但个人博客不一样,博主写的都是自己真实的想法和见解。它像是互联网的一片自留地,安静、干净,也更有灵魂。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">博客域名的由来?</p> <p id="blog-problem-des">刚开始博客域名使用的是我名字的全称 guanpengchen ,但是感觉太长了,体验感不好,就放弃使用了。<br />接着就改用了名字的缩写 gpchen ,但是 gpchen 在很多平台都被占用了,无法在全平台形成个人品牌,于是只能无奈放弃。<br />最后决定用自己的英语储备,将自己的名字音译为了英语,即 gorpeln ,实现全平台个人品牌,即你在任何平台搜索 gorpeln 的相关内容,都是与我相关的。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">为什么博客名字使用英文而不是用中文?</p> <p id="blog-problem-des">为了多平台统一,形成个人的品牌效应。gorpeln 是独一无二的,这个单词对其他人没有任何意义,不存在重复可能,而中文名字很多平台有使用限制,且简短的中文名称一定有被占用的情况。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">为什么选用TOP域名?</p> <p id="blog-problem-des">感觉走了很多弯路才最终选择使用top域名。<br />刚开始用的都是com域名,但是名称一直没有确定,使用过 guanpengchen、gpchen、gpchenx 等名字,2018年左右确定了名字 gorpeln ,从而形成了 <a href="https://img.gorpeln.top/blog/2019/15462756619/20190101010101185.png" target="_blank">gorpeln#com</a> 域名,当时博客收录量较好,也有一定的权重,但在一个平凡的午后,一位陌生人问我域名出手吗?博主最后妥协了。博主改用 <a href="https://img.gorpeln.top/blog/2019/15462756619/20190101010101184.png" target="_blank">gorpeln#cn</a> 域名,但是CN域名在使用过程中存在一些弊端,博主认为不适合自己,还是得申请国际顶级域名,COM域名一直没有释放,就只能选用TOP域名了。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">博客还会修改域名吗?</p> <p id="blog-problem-des">应该不会了,在博客十年之际,博主将TOP域名续费了10年,正常要再用十年。<br />CN域名使用限制较多,后续不再考虑。<br />COM价格涨价频繁也不再考虑了。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">COM和CN域名还可以访问?</p> <p id="blog-problem-des">由于域名在我使用后有一定的权重,被一些专业机构抢注用来做一些不好的事情,请大家谨防上当,随着权重降低,举报增多,域名将会失去价值,应该会逐渐释放。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">坚持“无人问津”的爱好是否有意义?</p> <p id="blog-problem-des">针对“无人问津”的兴趣爱好,我的看法是,做好自己的本职工作,无论是学习还是在职工作,然后放手去做吧。日常生活中,博客的坚持并不会占用你太多的时间和精力,但是经过长期的坚持,将会有质的获得。另外,在变强的路上注定是孤独的,所以不必担心。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">新手使用第三方博客如何?</p> <p id="blog-problem-des">个人极其不建议,因为你到最后肯定会走到自建博客的道路的。因为第三方平台限制多、审核时间长、广告多、收费多,体验感很不好。博主刚开始写博客也会将内容同步到CS*N等平台,因为平台有流量,但是体验感很不好,尤其是近年来广告、收费等愈发变态,博主接受不了的。当然前期你可以将文章同步到多个平台,用来提高个人博客的流量,但建议将重心放在个人博客中。博主的两个CS*N账户分别10年和7年了,现在已经彻底放弃了。<a href="https://gorpeln.blog.csdn.net/" target="_blank">CS*N 1</a> 和 <a href="https://blog.csdn.net/gorpeln" target="_blank">CS*N 2</a></p> </div> <div id="blog-problem"> <p id="blog-problem-title">对博客新手的建议?</p> <p id="blog-problem-des">博客的搭建十分简单,不用担心技术问题。<br />如果你不懂技术可以选用 Hexo、Jekyll、Hugo、WordPress 等各种博客框架,加上第三方主题,可以实现零基础搭建的。如果你懂技术,还是建议不用框架,这样才方便自己后期的自定义开发等。<br />博客搭建过程中最重要的就是 <b>成本</b>,尤其是初学者,你要尽可能压缩成本,使其无限趋近于零才是最好的,只有这样你才能走的更远。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">为什么建议新手降低成本呢?</p> <p id="blog-problem-des">你不可能永远喜欢一件事,当你的第一波热情退去,你的博客将会摆烂的,随着着服务器、域名、CDN等到期,你又不想管,你的博客就会随之而去。但是,如果你前期使用的成本较低,如使用静态博客,几乎零成本,资源也不会到期,等你再次想搭建博客,就可以快速开始。这是博主将 <a href="https://list.travellings.cn/" target="_blank">来往</a> 的成员列表中1700+个博主一个一个的看了两遍的深刻体会,很多博客就只存活了1年就结束了。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">时光为证,与你共赴新程?</p> <p id="blog-problem-des">每个人都有独属于自己的「十年故事」。在你的十年故事里,是否也有一个无人问津,却仍坚持至今的「gorpeln's Blog」?这十年里,尽管我已成长了很多,但许多问题,诸如「奋斗的意义」、「人为何而活」,我仍然给不出一个令我感到满意的答案。但人生的这份试卷仍在继续,我们仍在行进,在不断书写属于自己的那份或许并不完美,但一定是独一无二的答案。我曾以为的「参考答案」,实际上是:略。下一个十年,愿我们依然,对技术保持敬畏,对未知渴求探索。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">人生格言?</p> <p id="blog-problem-des">趁年轻,做自己想做的!<br />你一定听过「人不可能同时拥有青春和青春的感受」,因此,一定要「趁年轻,做自己想做的!」,无论结果成败,都是自己的人生财富。一旦错过,剩下的就只剩遗憾。</p> </div> <div id="blog-problem"> <p id="blog-problem-title">博客成长记录?</p> <p id="blog-problem-des"><a href="/record" target="_blank">查看博客成长记录</a></p> </div> <div id="blog-problem"> <p id="blog-problem-title">博客常见问题?</p> <p id="blog-problem-des"><a href="/article/17265361548" target="_blank">查看博客常见问题</a></p> </div> <p><br /></p> <details class="toggle"> <summary class="toggle-button">博客成长相关图片</summary> <div class="box-detail"> <img src="https://img.gorpeln.top/blog/2019/15462756619/20190101010101187.png" alt="" /> <img src="https://img.gorpeln.top/blog/2019/15462756619/20190101010101184.png" alt="" /> <img src="https://img.gorpeln.top/blog/2019/15462756619/20190101010101185.png" alt="" /> <img src="https://img.gorpeln.top/blog/2019/15462756619/20190101010101186.png" alt="" /> <img src="https://img.gorpeln.top/blog/2025/17559116027/20250823091322631.png" alt="" /> <img src="https://img.gorpeln.top/blog/2025/17559116027/20250823091322632.png" alt="" /> <img src="https://img.gorpeln.top/blog/2025/17559116027/20250823091322633.png" alt="" /> </div> </details> <p><br /></p> <p><img src="https://img.gorpeln.top/blog/2020/15981552003/20200823120000260.jpg" alt="20200823120000260" /></p> <p>  </p>

2025/8/23
阅读更多

时光本 - 数据导出

<p>亲爱的用户,非常抱歉因业务调整,时光本应用即将下架,给你带来的不便还望谅解。</p> <p>过去的日子里,感恩你的陪伴与信任,那些承载着回忆与成长的笔记,我始终珍视,即便APP落幕,我也会坚守有始有终的承诺,全力保障你的使用体验,帮你顺利迁移数据。</p> <p>为确保数据安全,我准备了 iOS <em class="color-gray">(适用于 iPhone)</em> 和 macOS <em class="color-gray">(适用于 Mac 电脑)</em> 版本的导出流程,操作中若有疑问,请留言,我会协助你完成迁移,再次感谢你的理解与支持。</p> <p>最后,请务必在APP下架前升级至<strong>最新版本</strong>完成导出,避免数据丢失。</p> <ul> <li><em class="color-gray">iOS端 最新版本号:2.1.4</em></li> <li><em class="color-gray">macOS端 最新版本号:1.5.4</em></li> </ul> <h3 id="ios-端">iOS 端</h3> <h4 id="一文字流程">一、文字流程</h4> <p>时光本iOS 端数据导出流程:</p> <ol> <li>前往 <a href="https://apps.apple.com/cn/app/id1495623965">App Store</a> 将应用更新至最新版本。</li> <li>点击进入 <code class="language-plaintext bg-blue highlighter-rouge">我的</code> - <code class="language-plaintext bg-blue highlighter-rouge">云备份</code> - <code class="language-plaintext bg-blue highlighter-rouge">本地备份</code>,选择 <code class="language-plaintext bg-red highlighter-rouge">『 笔记 』数据导出</code> 或 <code class="language-plaintext bg-red highlighter-rouge">『 账号 』数据导出</code>。<em class="color-gray">图 ①、图 ②、图 ③、图 ④</em></li> <li>导出的数据将以<code class="language-plaintext highlighter-rouge">json</code>格式复制到系统剪切板,你可以发送到电脑端以<code class="language-plaintext highlighter-rouge">文本</code> <em class="color-gray">(.txt)</em>或<code class="language-plaintext highlighter-rouge">json</code> <em class="color-gray">(.json)</em>格式存储。<em class="color-gray">图 ⑤、图 ⑥</em></li> <li>如果需要其他格式文件,请自行通过<code class="language-plaintext highlighter-rouge">json</code>文件转换成相应文件。以<code class="language-plaintext highlighter-rouge">json</code>转化为<code class="language-plaintext highlighter-rouge">excel</code>文件为例,方法如下: <em class="color-gray">(以下方法仅供参考,请自行判断)</em>。 <ul> <li>访问 <a href="https://www.lddgo.net/string/json-to-excel">在线JSON转Excel</a> 或 直接在浏览器搜索 <code class="language-plaintext bg-blue highlighter-rouge">json转excel</code> 选择相应的在线工具或应用。<em class="color-gray">图 ⑦</em></li> <li>将第 3 步导出的<code class="language-plaintext highlighter-rouge">json</code>数据复制到对应网站,点击转换,即可在线查看对应列表数据,可以点击页面<code class="language-plaintext bg-red highlighter-rouge">下载 Excel</code> 或 <code class="language-plaintext bg-red highlighter-rouge">下载 CSV</code>,下载本地保存。<em class="color-gray">图 ⑧、图 ⑨</em></li> </ul> </li> </ol> <h4 id="二图片流程">二、图片流程</h4> <p><img src="https://img.gorpeln.top/blog/2025/17529840977/20250720120137841.png" alt="20250720120137841" /></p> <p><img src="https://img.gorpeln.top/blog/2025/17529840977/20250720120137842.png" alt="20250720120137842" /></p> <p><img src="https://img.gorpeln.top/blog/2025/17529840977/20250720120137843.png" alt="20250720120137843" /></p> <p><img src="https://img.gorpeln.top/blog/2025/17529840977/20250720120137844.png" alt="20250720120137844" /></p> <h3 id="macos-端">macOS 端</h3> <p>时光本macOS 端数据导出流程:</p> <ol> <li>点击 <code class="language-plaintext bg-blue highlighter-rouge">备份到iCloud</code> ,将数据备份到 <code class="language-plaintext highlighter-rouge">iCloud</code>。</li> <li>在手机端 <code class="language-plaintext bg-blue highlighter-rouge">App Store</code> 下载最新版<code class="language-plaintext highlighter-rouge">iOS</code>端应用。</li> <li>点击进入 <code class="language-plaintext bg-blue highlighter-rouge">我的</code> - <code class="language-plaintext bg-blue highlighter-rouge">云备份</code> - <code class="language-plaintext bg-blue highlighter-rouge">云同步</code> - <code class="language-plaintext bg-blue highlighter-rouge">从iCloud恢复</code>,将<code class="language-plaintext highlighter-rouge">iCloud</code>云端数据同步到<code class="language-plaintext highlighter-rouge">iPhone</code>上。</li> <li>参照上述 <a href="#ios-端">iOS 端</a> 导出流程进行数据导出。</li> </ol>

2025/7/20
阅读更多

时光本 - 下线公告

<h3 style="text-align: center;border-bottom: 0;">重要通知</h3> <p>亲爱的时光本用户们:</p> <p>展信安好。</p> <p>首先,由衷地感谢大家这些年来对时光本的支持与陪伴。这款应用最初只是我在工作之余,出于兴趣开发的小小尝试 —— 我总希望能为大家提供一个纯净、便捷、免费且安全的工具,这份初心,从未改变。</p> <p>但今天,我带着些许不舍却又坚定的心情,想告诉大家一个决定:<strong>时光本将于 2026 年 01 月 20 日 23:59 正式停止运营</strong>。做出这个决定并不容易,反复斟酌后,我还是希望用这样的方式,为这段旅程画上一个平静的句号。未来,我想暂时放缓脚步,去做一些真正属于自己的内容,所以此刻只能道一句:后会有期。</p> <p>关于后续使用的几点说明,还请大家留意:</p> <ul> <li>已安装的时光本软件仍可继续使用,但未来将不再进行任何更新与维护;</li> <li>请务必及时备份好个人数据,若使用过程中出现问题,需由用户自行承担;</li> <li>应用结束运营前,时光本 <a href="/article/17529840977">数据导出</a> 方法;</li> </ul> <p>最后,想把最真诚的祝福送给每一位用户:愿大家在未来的日子里,总能与美好不期而遇。</p> <p><br /></p> <p style="text-align: right;margin-bottom: 0.2em;">开发者:gorpeln</p> <p style="text-align: right;margin-top: 0.2em;">2025 年 07 月 20 日</p>

2025/7/20
阅读更多

整蛊代码:你屏幕上有根毛

<p>我看评论很多人问主页上显示的这跟毛,可以直接放到自己博客,仅为娱乐,请勿滥用哦。</p> <p>以下是优化后的完整 js 代码,将代码插入到你的网页中即可看到效果! 代码中的图片地址可能后续会失效,建议保存到本地使用。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/*** * 愚人节彩蛋 - 你屏幕上有根毛 * 提示:仅为娱乐,请勿滥用 * 整理:gorpeln https://gorpeln.top/ */ !function() { var bottom = Math.floor(60 * Math.random()), right = Math.floor(50 * Math.random()), rotate = Math.floor(360 * Math.random()); var foolsEgg = document.createElement("img"); foolsEgg.src = "https://img.gorpeln.top/blog/2025/17499800077/20250615173327311.png"; foolsEgg.style.position = "fixed"; foolsEgg.style.bottom = "".concat(bottom, "%"); foolsEgg.style.right = "".concat(right, "%"); foolsEgg.style.zIndex = "9999"; foolsEgg.style.pointerEvents = "none"; foolsEgg.style.width = "40%"; foolsEgg.style.maxWidth = "190px"; foolsEgg.style.transform = "".concat("rotate(", rotate, "deg)"); document.body.append(foolsEgg); } (); </code></pre></div></div> <script> /*** * 愚人节彩蛋 - 你屏幕上有根毛 * 提示:仅为娱乐,请勿滥用 * 整理:gorpeln https://gorpeln.top/ */ !function() { var bottom = Math.floor(60 * Math.random()), right = Math.floor(50 * Math.random()), rotate = Math.floor(360 * Math.random()); var foolsEgg = document.createElement("img"); foolsEgg.src = "https://img.gorpeln.top/blog/2025/17499800077/20250615173327311.png"; foolsEgg.style.position = "fixed"; foolsEgg.style.bottom = "".concat(bottom, "%"); foolsEgg.style.right = "".concat(right, "%"); foolsEgg.style.zIndex = "9999"; foolsEgg.style.pointerEvents = "none"; foolsEgg.style.width = "40%"; foolsEgg.style.maxWidth = "190px"; foolsEgg.style.transform = "".concat("rotate(", rotate, "deg)"); document.body.append(foolsEgg); } (); </script>

2025/6/15
阅读更多

博客阅读进度条

<p>将下方代码放到头部HTML代码内</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;div id="percentageCounter"&gt;&lt;/div&gt; </code></pre></div></div> <p>css代码:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;!-- 阅读进度条开始 --&gt; &lt;style type="text/css"&gt; #percentageCounter{ position:fixed; left:0; top:0; height:3px; z-index:99999; /*绿红色*/ /*background-image: linear-gradient(to right, #339933,#FF6666);*/ /*白蓝色*/ background-image: linear-gradient(to right, #E8EAF6,#C5CAE9,#9FA8DA,#7986CB,#5C6BC0,#3F51B5,#3949AB,#303F9F,#283593,#1A237E); border-radius:5px; } &lt;/style&gt; </code></pre></div></div> <p>js代码:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;script type="text/javascript"&gt; $(window).scroll(function() { var a = $(window).scrollTop(), c = $(document).height(), b = $(window).height(); scrollPercent = a / (c - b) * 100; scrollPercent = scrollPercent.toFixed(1); $("#percentageCounter").css({ width: scrollPercent + "%" }); }).trigger("scroll"); &lt;/script&gt; &lt;!-- 阅读进度条结束 --&gt; </code></pre></div></div>

2025/6/6
阅读更多

手机真的在监听你的谈话?

<p>许多人都遇到过这样的情况:刚跟朋友谈到某件商品,手机很快就推送了相关广告。于是,一种流行的阴谋论便开始流传:“手机在随时监听我们的对话。”但事实真的如此吗?我将从技术原理、经济逻辑、法律监管和实际证据四个维度进行全面分析,以澄清这一误解。</p> <h3 id="一技术层面实时监听难度巨大成本过高">一、技术层面:实时监听难度巨大,成本过高</h3> <p>要想实现“实时监听并精准推送广告”,技术上需要解决三大难题:</p> <p><strong>高频音频采集与实时分析</strong>:如果手机要随时监听,意味着需要持续运行麦克风录音、语音识别与自然语言处理(NLP)技术。这对电池消耗、计算资源、数据处理能力都提出极高要求。目前主流手机的电池和处理器尚无法支撑如此强大的后台持续运行任务。即使是语音助手(如Siri、Google Assistant)也只会在触发特定关键词(“嘿Siri”或“OK Google”)后才启动识别。</p> <p><strong>网络传输负担巨大</strong>:若要实时上传每个用户的所有音频数据,所需的数据流量和服务器存储将达到天文数字。目前全球所有的互联网服务商也无力承担这样巨大的网络带宽需求和存储成本。</p> <p><strong>精准的上下文分析</strong>:困难重重语言中的歧义、方言、噪声干扰,都会导致语音转文字后的准确性大幅降低,更不要说实时理解上下文并匹配广告推送了。这种技术的误差率高、成本大,收益也远远不足以覆盖成本。</p> <h3 id="二商业逻辑监听谈话并非最佳营销策略">二、商业逻辑:监听谈话并非最佳营销策略</h3> <p>很多人认为“监听谈话推广告”对商家有利,但事实上:</p> <p>数据精准度不足,效果有限即使商家真的监听了你的对话,由于人们的日常交谈随意性强,很多对话内容与真实需求并无必然联系。从营销角度来看,这种推送的转化率和精准度远不及用户主动搜索、电商浏览历史或社交媒体互动行为所带来的精准。 已存在更有效的数据收集手段广告商早已有更高效、合法且成本更低的方法,例如用户的搜索记录、网页浏览历史、App使用行为、地理位置信息等。这些都是经过用户协议明确授权、合法合规获得的精准信息来源,比起昂贵又敏感的“监听”要安全有效得多。</p> <h3 id="三法律监管监听用户属违法行为风险极大">三、法律监管:监听用户属违法行为,风险极大</h3> <p>在绝大多数国家和地区,包括中国、美国和欧盟,未经用户许可私自监听谈话都是严重违法行为:</p> <p>严格的隐私保护法规欧盟的《通用数据保护条例》(GDPR)、美国的隐私保护法案、中国的《个人信息保护法》都对手机App、服务商的权限做出严格限制,违法违规者将面临巨额罚款、声誉损失甚至刑事责任。 法律后果严重,不符合商业理性如果手机厂商或软件公司真的采用监听的方式获取信息,不仅会触犯法律,更会面临严重的法律诉讼风险和公众信任的彻底崩溃。这对于品牌形象和企业长期利益都是致命打击,任何有理性商业头脑的公司都不会冒如此巨大的风险。</p> <h3 id="四实际证据实证研究与官方调查均否认监听行为">四、实际证据:实证研究与官方调查均否认监听行为</h3> <p>实际上,多个权威机构都已对这种谣言进行调查:</p> <p>科学实证研究美国东北大学研究团队在2018年进行了一项全面的实验,分析了超过1.7万个App,并未发现任何一个App在用户未授权的情况下秘密录音并上传语音数据。研究团队明确表示,目前尚无证据表明手机存在监听用户谈话的行为。 科技公司公开声明及第三方监督苹果、谷歌等科技巨头多次公开表示从未监听用户对话。若这些声明不属实,面临的法律风险和名誉损害都远远超出任何商业利益。同时,各国监管部门和第三方隐私保护机构也定期审计这些公司,未发现监听行为。</p> <h3 id="五为什么会产生这种错觉">五、为什么会产生这种错觉?</h3> <p>人们之所以误以为手机在监听,很可能是因为:</p> <p>选择性注意和心理暗示用户谈论了某个话题后,当看到相关广告时,更容易引起注意并加深记忆,形成“被监听”的错觉。实际上,这类广告可能早就出现,只是用户之前并未留意。 算法精准推荐的效果大数据分析和个性化推荐技术已经十分成熟,通过用户行为(搜索、位置、消费记录)就能高度准确地预测用户兴趣,因此看起来仿佛是“偷听”了对话。 话题的时效性和热度用户谈论的很多话题本身就是当前的热点(比如流行产品、时令商品),而广告系统也在同步更新热点推送内容,使用户感觉“刚说就推送”。</p> <h3 id="结论不存在手机实时监听推送广告的行为">结论:不存在手机实时监听推送广告的行为</h3> <p>综上所述,“手机监听用户谈话推广告”不过是一种误解,是缺乏对技术原理、经济逻辑、法律风险、实际证据全面了解而产生的阴谋论。我们生活在一个隐私保护越来越严密的时代,手机App厂商不仅没有足够的动机、技术条件,也没有胆量去冒违法风险进行实时监听。</p> <p>理解真实的推送原理和背后的技术、逻辑、法律基础,我们才能避免被不必要的焦虑和误解困扰。</p>

2025/5/31
阅读更多

使用Serv00部署在线工具箱

<h3 id="效果演示">效果演示</h3> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314124.png" alt="20250501123314124" /></p> <p><a href="https://tool.202090.xyz/">在线工具箱 演示网站</a></p> <p>在线工具箱:提供丰富的在线工具,如 JSON 格式化、美化、压缩、解析,Unix 时间戳转换,CSS 美化等多功能支持。</p> <h3 id="事前准备">事前准备</h3> <p>域名( <strong>非必须</strong>,你也可以使用免费域名)</p> <p><a href="https://www.serv00.com/">Serv00</a> ( <strong>必须</strong>,免费注册的,没有可以自行注册但是对IP环境和邮箱要求比较大,注册提示维护一般都是IP或者邮箱不太行,邮箱建议使用谷歌的。)</p> <h3 id="开始部署">开始部署</h3> <p>01、 登录你的 <code class="language-plaintext highlighter-rouge">serv00</code> 后,点击 <code class="language-plaintext highlighter-rouge">WWW websites</code> 再点 <code class="language-plaintext highlighter-rouge">Add new website</code> 添加你的域名我设置为 <code class="language-plaintext highlighter-rouge">tool.gorpeln.top</code> ,点 <code class="language-plaintext highlighter-rouge">Add</code> 添加。看到这个提示 <code class="language-plaintext highlighter-rouge">Operation performed successfully</code> 成功添加。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314111.png" alt="20250501123314111" /></p> <p>02、 点 <code class="language-plaintext highlighter-rouge">Manage SSL certificates</code> 可以看到这个ip地址 <code class="language-plaintext highlighter-rouge">128.204.223.xxx</code> 然后去你的DNS解析平台绑定。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314112.png" alt="20250501123314112" /></p> <p>03、 打开DNS解析平台解析。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314113.png" alt="20250501123314113" /></p> <p>04、 这样设置完,你打开的设置的网站域名,可以看到这样的页面就是成功。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314114.png" alt="20250501123314114" /></p> <p>05、 接下来正式开始打开 <a href="https://github.com/gorpeln/tool">tool下载源码</a> 。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314115.png" alt="20250501123314115" /></p> <p>06、 点击 <code class="language-plaintext highlighter-rouge">WWW websites</code> 再点 <code class="language-plaintext highlighter-rouge">Add new website</code> 再点 <code class="language-plaintext highlighter-rouge">tool.gorpeln.top</code>的<code class="language-plaintext highlighter-rouge">Details</code> ,设置你网站的路径,如图所示,修改 <code class="language-plaintext highlighter-rouge">Open Basedir directories</code> 中的内容,把下方代码中的 <code class="language-plaintext highlighter-rouge">serv00的名称</code> 替换为你的登录用户名, <code class="language-plaintext highlighter-rouge">自己的域名</code> 同理,修改完复制进去保存。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/home/serv00的名称/domains/自己的域名/public_html:/tmp:/usr/share:/usr/local/share:/dev:/tmp:/usr/share:/usr/local/share:/dev:/usr/home/serv00的名称/domains/自己的域名 </code></pre></div></div> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314116.png" alt="20250501123314116" /></p> <p>07、 设置完毕,打开serv00 的 <code class="language-plaintext highlighter-rouge">File manager</code>,上传从github下载的tool源文件压缩包</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314117.png" alt="20250501123314117" /></p> <p>08、 进到你域名这个目录,上传你之前下载好的源码。右键压缩包如图。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314118.png" alt="20250501123314118" /></p> <p>09、 进到 <code class="language-plaintext highlighter-rouge">tool-main</code> 这个目录里面,全选除<code class="language-plaintext highlighter-rouge">public</code>外的所有文件</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314119.png" alt="20250501123314119" /></p> <p>10、 选择解压到你域名的目录,只要你跟我图一样就没问题。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314120.png" alt="20250501123314120" /></p> <p>11、 进到命名为 <code class="language-plaintext highlighter-rouge">public</code> 目录,全选所有文件,右键解压到域名目录中的 <code class="language-plaintext highlighter-rouge">public_html</code> 目录。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314121.png" alt="20250501123314121" /></p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314122.png" alt="20250501123314122" /></p> <p>12、 进到 <code class="language-plaintext highlighter-rouge">public_html</code> 目录,将命名为 <code class="language-plaintext highlighter-rouge">.htaccess</code> 的文件右键打开使用text方式编辑,你如果没有我图片上的text,就选 <code class="language-plaintext highlighter-rouge">choose other</code> 进行选择编辑方式拉到最下面就有了。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314123.png" alt="20250501123314123" /></p> <p>13、 将文件内容改为这个代码 然后保存。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>AddType application/x-httpd-php71 .php &lt;IfModule mod_rewrite.c&gt; Options +FollowSymlinks -Multiviews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] &lt;/IfModule&gt; </code></pre></div></div> <p>14、 完成!打开你的网站就可以看到内容了。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314124.png" alt="20250501123314124" /></p> <p>15、 (可选项)通过访问 https://你的域名/admin,访问后台,进行相关配置修改。</p> <p><img src="https://img.gorpeln.top/blog/2025/17460739947/20250501123314125.png" alt="20250501123314125" /></p>

2025/5/1
阅读更多

自定义博客文章卡片

<h3 id="效果">效果</h3> <p>迷幻紫</p> <div class="post-card card-theme1">在这里输入文本</div> <p>西瓜红</p> <div class="post-card card-theme2">在这里输入文本</div> <p>天空之境</p> <div class="post-card card-theme3">在这里输入文本</div> <p>小宇宙</p> <div class="post-card card-theme4">在这里输入文本</div> <p>橄榄绿</p> <div class="post-card card-theme5">在这里输入文本</div> <p>小太阳</p> <div class="post-card card-theme6">在这里输入文本</div> <p>优雅紫</p> <div class="post-card card-theme7">在这里输入文本</div> <p>深邃黑</p> <div class="post-card card-theme8">在这里输入文本</div> <h3 id="代码">代码</h3> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>迷幻紫 &lt;div class="post-card card-theme1"&gt;在这里输入文本&lt;/div&gt; 西瓜红 &lt;div class="post-card card-theme2"&gt;在这里输入文本&lt;/div&gt; 天空之境 &lt;div class="post-card card-theme3"&gt;在这里输入文本&lt;/div&gt; 小宇宙 &lt;div class="post-card card-theme4"&gt;在这里输入文本&lt;/div&gt; 橄榄绿 &lt;div class="post-card card-theme5"&gt;在这里输入文本&lt;/div&gt; 小太阳 &lt;div class="post-card card-theme6"&gt;在这里输入文本&lt;/div&gt; 优雅紫 &lt;div class="post-card card-theme7"&gt;在这里输入文本&lt;/div&gt; 深邃黑 &lt;div class="post-card card-theme8"&gt;在这里输入文本&lt;/div&gt; </code></pre></div></div>

2025/4/26
阅读更多

个人博客可以尝试的 100 件事

<ul style="margin-left:2.8em;list-style-type: none;"> <li>✓ 本网站已支持  ☐ 本网站暂不支持  × 本网站暂不考虑  </li> </ul> <ol> <li>✓ 如果你还没有个人网站,可以搭建一个!</li> <li>✓ 写一篇博客,分享你感兴趣的事、最近让你开心的经历、过去一周学到的新东西、读完一本书后的感想、你玩喜欢的游戏的攻略,或者任何你感兴趣的话题。</li> <li>☐ 分享一道最近做的美味菜谱。</li> <li>☐ 发布一张最近拍摄的照片。</li> <li>✓ 创建一个<a href="/links">友情链接</a>,链接你喜爱的个人网站。</li> <li>✓ 添加一个 robots.txt 文件,明确限制搜索引擎和AI抓取你网站的内容。</li> <li>☐ 为你喜欢的乐队、电视剧或其他事物创建一个特别的「纪念馆」或「粉丝小站」。</li> <li>☐ 制作图像热区图,让访客点击图片不同部分探索更多信息,比如你书桌上的物品介绍。</li> <li>✗ 分享你最喜欢的书单。</li> <li>✗ 创建电影推荐专页。</li> <li>✓ 提供一个<a href="/article/17016025546">深色模式</a>选项,让读者更舒适地阅读。</li> <li>✓ 注册并使用一个属于你的专属域名。</li> <li>✓ 添加一个有趣的小彩蛋。</li> <li>✓ 搭建留言板,让大家畅所欲言。</li> <li>✓ 给你的网站或特定页面<a href="/article/17347663476">设置背景</a>图片。</li> <li>☐ 设计一个网站寻宝游戏,让访客通过寻找线索探索你的网站。</li> <li>✓ 在 HTML 代码中加入清晰的注释,帮助新手理解你网页各部分的用途。</li> <li>✓ 分享最近喜欢的网页,比如文章、博客、摄影作品或游戏。</li> <li>✓ 为图片添加描述文字。</li> <li>✓ 使用 <a href="https://wave.webaim.org/report#/gorpeln.top">WAVE</a> 工具检查网站的无障碍访问性。</li> <li>✓ 用 <a href="https://pagespeed.web.dev/analysis/https-gorpeln-top/uo1m7dhebl?form_factor=desktop">PageSpeed Insights</a> 优化网站速度。</li> <li>☐ 如果你发布学术作品,添加引用说明。</li> <li>✗ 创建一个「反向图书馆」清单,记录你拥有但未读的书籍。</li> <li>☐ 制作一个文字小游戏。</li> <li>✓ 记录<a href="/record">网站更新日志</a>。</li> <li>✗ 分享你最近学到的新词列表。</li> <li>✓ 添加 <a href="/feed.xml">RSS 订阅</a> 功能,让访客轻松关注更新。</li> <li>☐ 创建「历史上的今天」功能,链接到以往同日期发布的博客。</li> <li>✓ 添加<a href="/links#problem">锚点链接</a>,提升网站对屏幕阅读器的支持。</li> <li>✓ 制作<a href="/archives">文章归档</a>页面。</li> <li>☐ 为网站设计一个专属吉祥物。</li> <li>✗ 制作并添加一个 88×31 像素的小按钮图标,通常用于网页、博客、论坛等地方的链接按钮或标识图标。这种按钮图标在早期互联网时代非常流行,经常用于交换链接、展示合作伙伴或赞助商的链接。</li> <li>✓ 加入一个网站联盟,比如 <a href="https://www.foreverblog.cn/blog/577.html">十年之约</a> 和 <a href="https://list.travellings.cn/">开往 Travellings</a>。</li> <li>✓ 翻译网站的某个页面到你熟悉或正在学习的语言,比如 <a href="/notes">时光本</a>。</li> <li>✓ 创建<a href="/resume">打印样式表</a>。</li> <li>✓ 确保所有链接有效无误。</li> <li>☐ 发起博客活动,邀请朋友们围绕特定主题每月发表文章,并轮流确定主题。</li> <li>☐ 添加 rel=me 链接,认证其他平台上的个人资料,比如在博客自我介绍中列出自己的 Mastodon、GitHub、Twitter 账号。</li> <li>☐ 做一些额外的惊喜内容(おまけ)。</li> <li>✓ 如果你想展示专业作品,可以创建 HTML <a href="/resume">简历页面</a>。</li> <li>✓ 使用语法高亮工具(如 Prism.js)美化代码片段。</li> <li>✓ 检查和优化 head 标签中的内容。</li> <li>✓ 为网站添加搜索功能。</li> <li>☐ 创建“此刻(now page)”页面,通常用来展示网站拥有者当前正在关注的事情、工作、生活状态或感兴趣的项目。</li> <li>☐ 使用迷你图(sparkline)展示文章发布频率。Sparkline 是指通过一种小巧、简洁的折线或柱状图,以极小的空间清晰地展现文章发布数量在一段时间内的变化趋势。热图也是一个很好的选择。</li> <li>☐ 尝试不同的字体风格。不同的字体适合不同的主题,可以一起调整。</li> <li>✓ 优化标题字号的层次区分。</li> <li>✓ 在文章末尾加入装饰性分隔符。</li> <li>✗ 使用 lite-youtube 组件加快视频加载速度。</li> <li>☐ 更新网站配色方案。</li> <li>✓ 创建 HTML 元素样式<a href="/article/14402966023">展示页面</a>,辅助开发优化。</li> <li>☐ 编写趣味问答,邀请朋友参与。</li> <li>☐ 为网站添加 Webmention 支持。Webmention 是一种开放的 Web 标准,用于在不同网站之间发送和接收消息通知,使得网站可以相互引用、交互以及进行社交化沟通。</li> <li>☐ 制作共享使用的网页组件(web component)。</li> <li>✓ 为图片设置鼠标悬停效果。</li> <li>✗ 添加您说出自己名字或昵称的录音,以便大家知道如何发音。</li> <li>✓ 在<a href="/article/17347677826">特别的节日</a>为网站换上主题装扮。</li> <li>✗ 分享你亲手绘制的画作。</li> <li>✗ 在主页添加互动式像素网格。</li> <li>☐ 标记网站内容为非 AI 生成,可参考这个项目 Not By AI 。</li> <li>☐ 分享你喜爱的播客清单。</li> <li>✓ 为你的兴趣爱好专门开设一个新的网站。</li> <li>✓ 制作<a href="/favicon.ico">网站图标</a>(favicon)。</li> <li>✓ 写一篇纪念个人<a href="/article/15981552003">网站发展</a>史。</li> <li>☐ 添加背景播放音频,如鸟鸣或咖啡厅氛围。</li> <li>☐ 制作个人风格的情绪板(mood board),是指通过搜集并组合图片、颜色、文字、材质等元素,来视觉化呈现个人喜好、风格偏好或某种特定氛围的过程。</li> <li>✓ 使用 HTML 的 <a href="/links">details</a> 和 summary 标签。</li> <li>☐ 自定义文本选中时的高亮颜色。</li> <li>☐ 帮助朋友搭建他们的网站。</li> <li>✓ 为自己撰写网站维护文档。</li> <li>☐ 为喜欢的艺术作品撰写评论。</li> <li>☐ 与朋友合写一篇共同兴趣的博客。</li> <li>✓ 更新旧博客文章。</li> <li>☐ 在文章中添加旁注(sidenotes)。</li> <li>✓ 为长文章创建目录。</li> <li>☐ 为外部链接添加识别小图标。</li> <li>☐ 添加悬浮卡片(hovercards)。悬浮卡片指的是当用户的鼠标指针悬停在某个元素上时,会弹出一个小卡片,显示额外的信息或提示。</li> </ol> <p>没错。我确实承诺过要列出100个想法。但为了实现这个目标,我需要你的帮助。以上想法是我在个人网站上看到的,但我渴望听到更多人的想法。因此,我诚邀大家帮助我完成这份清单。写下一些可以在个人网站上实现的想法。将这些想法发布到你的博客上,与你的朋友们分享。</p> <p>网络的魅力在于,我们可以一起分享想法,共同开发新项目。事实上,我们可以规划定义人们网络体验的路径。我们需要更多人来编织独立网络——那些在网络平台上进行实验并创造自己感兴趣的新事物的人。</p>

2025/3/23
阅读更多

MathJax的基本使用

<h3 id="一引言">一、引言</h3> <p><code class="language-plaintext highlighter-rouge">MathJax</code>引擎是一个开源的JavaScript库,它允许Web开发者在网页中嵌入高质量的数学公式。通过利用Web的最新技术,MathJax引擎可以解析LaTeX、MathML和AsciiMath等数学标记语言,并将其渲染为可视化的数学公式,这些公式可以在各种浏览器和操作系统上流畅地显示。</p> <p>使用MathJax引擎,网页作者可以轻松地编写包含数学内容的文档,而无需担心用户的浏览器或操作系统是否能够正确显示这些数学公式。因为MathJax引擎会自动处理这些兼容性问题,确保用户能够以清晰、准确的方式查看数学内容。</p> <p>MathJax引擎的特点包括:</p> <ul> <li>跨平台兼容性:它支持多种浏览器和操作系统,确保数学公式能够在各种设备上正确显示。</li> <li>高质量的排版:MathJax引擎使用先进的排版算法,确保数学公式能够以清晰、准确的方式呈现。</li> <li>易于使用:通过简单的标记语言,如LaTeX,用户可以轻松地编写数学公式,并将其嵌入到网页中。</li> <li>高度可定制性:MathJax引擎提供了丰富的配置选项,允许用户根据自己的需求进行定制,以满足特定的排版和显示要求。</li> </ul> <p>总的来说,MathJax引擎是一个功能强大、易于使用的工具,它为Web上的数学内容显示提供了高质量的解决方案。无论是科学论文、教育资料还是技术文档,都可以利用MathJax引擎来呈现复杂的数学公式,提升网页的可读性和专业性。</p> <h3 id="二使用">二、使用</h3> <h4 id="1安装">1、安装</h4> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install mathjax@3 </code></pre></div></div> <h4 id="2配置">2、配置</h4> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MathJax = { tex: { packages: ['base'], // 要使用的扩展 inlineMath: [ // 行内数学公式的开始/结束定界符对 ['$', '$'], ['\\(', '\\)'] ], displayMath: [ // 显示数学公式的开始/结束定界符对 ['$$', '$$'], ['\\[', '\\]'] ], processEscapes: true, // 使用 \$ 来产生一个字面意义上的美元符号 processEnvironments: true, // 在数学模式之外处理 \begin{xxx}...\end{xxx} processRefs: true, // 在数学模式之外处理 \ref{...} digits: /^(?:[0-9]+(?:\{,\}[0-9]{3})*(?:\.[0-9]*)?|\.[0-9]+)/, // 用于识别数字的模式 tags: 'none', // 标签类型,可选值为 'none'、'ams' 或 'all' tagSide: 'right', // \tag 宏的位置 tagIndent: '0.8em', // 标签的缩进量 useLabelIds: true, // 使用标签名称而不是标签编号作为 ID maxMacros: 10000, // 每个表达式允许的最大宏替换次数 maxBuffer: 5 * 1024, // 内部 TeX 字符串的最大大小(5K) baseURL: (document.getElementsByTagName('base').length === 0) ? '' : String(document.location).replace(/#.*$/, '')), // 当存在 &lt;base&gt; 标签时,用于标签链接的 URL formatError: (jax, err) =&gt; jax.formatError(err) // 当 TeX 语法错误发生时调用的函数 }, options: { skipHtmlTags: [ 'script', 'noscript', 'style', 'textarea', 'pre', 'code', 'annotation', 'annotation-xml' ], // 不会搜索数学公式的 HTML 标签 includeHtmlTags: { br: '\n', wbr: '', '#comment': '' }, // 可以出现在数学公式内的 HTML 标签 ignoreHtmlClass: 'tex2jax_ignore', // 标记不进行搜索的标签的类名 processHtmlClass: 'tex2jax_process', // 标记应进行搜索的标签的类名 compileError: function (doc, math, err) {doc.compileError(math, err)}, // 编译错误处理函数 typesetError: function (doc, math, err) {doc.typesetError(math, err)}, // 排版错误处理函数 renderActions: {...} // 渲染操作 }, startup: { elements: null, // 要进行排版的元素(默认是文档主体) typeset: true, // 是否执行初始排版 ready: Startup.defaultReady.bind(Startup), // 组件加载完成时调用 pageReady: Startup.defaultPageReady.bind(Startup), // MathJax 和页面准备好时调用 document: document, // 要处理的文档(或片段或字符串) invalidOption: 'warn', // 无效选项是致命错误还是产生警告 optionError: OPTIONS.optionError, // 用于报告无效选项的函数 input: [], // 要使用的输入引擎的名称(从已加载的引擎中选择) output: null, // 要使用的输出引擎的名称(从已加载的引擎中选择) handler: null, // 要注册的处理程序的名称(从已加载的处理程序中选择) adaptor: null // 要使用的 DOM 适配器的名称(从已加载的适配器中选择) }, svg: { scale: 1, // 所有表达式的全局缩放因子 minScale: .5, // 要使用的最小缩放因子 mtextInheritFont: false, // 使 mtext 元素使用周围字体 merrorInheritFont: true, // 使 merror 文本使用周围字体 mathmlSpacing: false, // 为 true 时使用 MathML 间距规则,为 false 时使用 TeX 规则 skipAttributes: {}, // 不复制到输出的 RFDa 等属性 exFactor: .5, // ex 单位的默认大小(以 em 为单位) displayAlign: 'center', // 当 indentalign 设置为 'auto' 时的默认值 displayIndent: '0', // 当 indentshift 设置为 'auto' 时的默认值 fontCache: 'local', // 字体缓存设置,可选值为 'local'、'global' 或 'none' localID: null, // 用于本地字体缓存的 ID(用于单方程处理) internalSpeechTitles: true, // 插入带有语音内容的 &lt;title&gt; 标签 titleID: 0 // 用于 aria-labeledby 标题的初始 ID 编号 } }; </code></pre></div></div> <p>按需配置,如果你都不需要,你可以什么也不配置</p> <h4 id="3复制">3、复制</h4> <p>需要复制时,在对应公式部分点击 右键 -&gt; Copy to Clipboard -&gt; TeX Commands 即可完成复制 <br /> <img src="https://img.gorpeln.top/blog/2025/17384679236/20250202114523962.png" alt="20250202114523962" /></p> <h3 id="三例子">三、例子</h3> <h4 id="1四则运算">1、四则运算</h4> <h5 id="1加减">1)加减</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$a+b-c$ </code></pre></div></div> <p>效果:$a+b-c$</p> <h5 id="2乘法">2)乘法</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$a\times b$ (注意\times和b之间要有空格) </code></pre></div></div> <p>效果:$a\times b$</p> <h5 id="3分数">3)分数</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\frac{a}{b}$ </code></pre></div></div> <p>效果:$\frac{a}{b}$</p> <h5 id="4括号">4)括号</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$(\frac{a}{b})$ $\left( \frac{a}{b} \right)$ $\left[ \frac{a}{b} \right]$ # 当使用\left和\right时,它们会根据所包含内容的大小自动调整括号的大小,使得括号能够合适地包围住内容,看起来更加美观和协调。而普通的小括号()不会自动调整大小,在一些复杂的公式中,可能会出现括号与内容大小不匹配的情况 </code></pre></div></div> <p>效果: <br /> $(\frac{a}{b})$ <br /> $\left( \frac{a}{b} \right)$ <br /> $\left[ \frac{a}{b} \right]$</p> <h5 id="5四则组合">5)四则组合</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\frac{(a+b)\times c}{(d-e)\times f}$ </code></pre></div></div> <p>效果:$\frac{(a+b)\times c}{(d-e)\times f}$</p> <h4 id="2比较运算">2、比较运算</h4> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$a &lt; b$ $a &gt; b$ $a = b$ $a \not= b$ $a \leq b$ $a \geq b$ $a \equiv b$ </code></pre></div></div> <p>效果: <br /> $a &lt; b$ <br /> $a &gt; b$ <br /> $a = b$ <br /> $a \not= b$ <br /> $a \leq b$ <br /> $a \geq b$ <br /> $a \equiv b$</p> <h4 id="3上标与下标">3、上标与下标</h4> <h5 id="1上标">1)上标</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$x^a$, $x^{ab}$, $x^ab$ # 多个字符时,要用花括号代替,不过单个字符时有无花括号是等价的 </code></pre></div></div> <p>效果:$x^a$, $x^{ab}$, $x^ab$</p> <h5 id="2下标">2)下标</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$a_n$, $a_{nm}$, $a_nm$ # 花括号原理同上 </code></pre></div></div> <p>效果:$a_n$, $a_{nm}$, $a_nm$</p> <h5 id="3次方根">3)次方根</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\sqrt a$, $\sqrt[n]a$, $\sqrt[nm]{ab}$ </code></pre></div></div> <p>效果:$\sqrt a$, $\sqrt[n]a$, $\sqrt[nm]{ab}$</p> <h5 id="4上下标组合">4)上下标组合</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$a_i^2$, $C^2_{10}$ </code></pre></div></div> <p>效果:$a_i^2$, $C^2_{10}$</p> <h4 id="4集合间的运算">4、集合间的运算</h4> <h5 id="1集合">1)集合</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\left\\{ x_1,x_2 \right\\}$ # 不能直接打花括号,必须要有\left,\right # 可以写成一行,这样仅为了方便查看 </code></pre></div></div> <p>效果:$\left\{ x_1,x_2 \right\}$</p> <h5 id="2元素与集合的关系">2)元素与集合的关系</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$A \in B$ // 元素A 属于 集合B $A \notin B$ // 元素A 不属于 集合B </code></pre></div></div> <p>效果: <br /> $A \in B$ <br /> $A \notin B$</p> <h5 id="3集合与集合的关系">3)集合与集合的关系</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$A \subset B$ // 集合A是集合B的 真子集,意味着A的所有元素都在B中,但B中至少存在一个元素不在A中 $A \subseteq B$ // 集合A是集合B的 子集,即A的所有元素都在B中,A和B有可能相等 $A \supset B$ // 集合A 真包含 集合B,表明B的所有元素都在A中,但A中至少存在一个元素不在B中 $A \supseteq B$ // 集合A 包含 集合B,即B的所有元素都在A中,A和B有可能相等 </code></pre></div></div> <p>效果: <br /> $A \subset B$ <br /> $A \subseteq B$ <br /> $A \supset B$ <br /> $A \supseteq B$</p> <h5 id="4集合的基本运算">4)集合的基本运算</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$A \cap B$ // 集合A与集合B的 交集,由既属于A又属于B的所有元素共同组成 $A \cup B$ // 集合A与集合B的 并集,由属于A或者属于B的所有元素合并组成 $A \setminus B$ // 集合A与集合B的 差集,是由所有属于A但不属于B的元素构成的集合,也可表示为 A - B $\complement_U A$ // 集合A在全集U中的 补集,即全集中所有不属于A的元素所组成的集合 </code></pre></div></div> <p>效果: <br /> $A \cap B$ <br /> $A \cup B$ <br /> $A \setminus B$ 或 $A - B$ <br /> $\complement_U A$</p> <h5 id="5集合中的符号">5)集合中的符号</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ \cdot $ // 一个点 $ \cdots $ // 三个点 $ \mid $ // 分隔符 </code></pre></div></div> <p>效果: <br /> $ \cdot $ <br /> $ \cdots $ <br /> $ \mid $</p> <h5 id="6集合组合示例">6)集合组合示例</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$A = \left\\{ x_1,x_2,\cdots,x_n \right\\}$ // 定义集合A,集合A由元素x_1, x_2, ..., x_n组成 $A\cap \complement_{A\cup B}B=A - B$ // 集合A与集合B在A和B的并集中的补集的交集,等于集合A与集合B的差集 </code></pre></div></div> <p>效果: <br /> $A = \left\{ x_1,x_2,\cdots,x_n \right\}$ <br /> $A\cap \complement_{A\cup B}B=A - B$</p> <h4 id="5常用特殊函数">5、常用特殊函数</h4> <h5 id="1三角函数">1)三角函数</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\sin x$, $\cos x$, $\tan x$, $\cot x$ # 注意中间的空格 </code></pre></div></div> <p>效果:$\sin x$, $\cos x$, $\tan x$, $\cot x$</p> <h5 id="2反三角函数">2)反三角函数</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\arcsin x$, $\arccos x$, $\arctan x$ </code></pre></div></div> <p>效果:$\arcsin x$, $\arccos x$, $\arctan x$</p> <h5 id="3双曲函数">3)双曲函数</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\sinh x$, $\cosh x$, $\tanh x$, $\coth x$ </code></pre></div></div> <p>效果:$\sinh x$, $\cosh x$, $\tanh x$, $\coth x$</p> <h5 id="4对数">4)对数</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\log_ax$, $\ln x$, $\lg x$ </code></pre></div></div> <p>效果:$\log_ax$, $\ln x$, $\lg x$</p> <h4 id="6常用特殊符号">6、常用特殊符号</h4> <h5 id="1求和">1)求和</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\sum$, $\sum_{i=1}^n$, $\sum_{i=1}^na_i$, $\sum_{i=1}^{na_i}$ </code></pre></div></div> <p>效果:$\sum$, $\sum_{i=1}^n$, $\sum_{i=1}^na_i$, $\sum_{i=1}^{na_i}$</p> <h5 id="2无穷">2)无穷</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\infty$, $+\infty$, $-\infty$ </code></pre></div></div> <p>效果:$\infty$, $+\infty$, $-\infty$</p> <h5 id="3箭头">3)箭头</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\rightarrow$, $\leftarrow$, $\uparrow$, $\downarrow$ </code></pre></div></div> <p>效果:$\rightarrow$, $\leftarrow$, $\uparrow$, $\downarrow$</p> <h5 id="4极限">4)极限</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\lim$, $\lim_{x\rightarrow 0}$, $\lim_{x\rightarrow \infty}$ </code></pre></div></div> <p>效果:$\lim$, $\lim_{x\rightarrow 0}$, $\lim_{x\rightarrow \infty}$</p> <h5 id="5积分">5)积分</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\int$, $\int_a^b$, \$int_{ab}^{cd}$ $ \int_a^b \left( -\frac{1}{x^2} \right) dx = \frac{1}{x}|_a^b = \frac{1}{b} - \frac{1}{a} $ </code></pre></div></div> <p>效果: <br /> $\int$, $\int_a^b$, $int_{ab}^{cd}$ <br /> $ \int_a^b \left( -\frac{1}{x^2} \right) dx = \frac{1}{x}|_a^b = \frac{1}{b} - \frac{1}{a} $</p> <h5 id="6二重积分">6)二重积分</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\iint$, $\iint_D$ </code></pre></div></div> <p>效果:$\iint$, $\iint_D$</p> <h5 id="7三重积分">7)三重积分</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\iiint$, $\iiint_D$ # 以此类推,超过四重的积分不可用 </code></pre></div></div> <p>效果:$\iiint$, $\iiint_D$</p> <h5 id="8偏导">8)偏导</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\partial$ </code></pre></div></div> <p>效果:$\partial$</p> <h5 id="9梯度">9)梯度</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\nabla$ </code></pre></div></div> <p>效果:$\nabla$</p> <h5 id="10其他">10)其他</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ \star $ , $ \ast $, $ \oplus $, $ \circ $, $ \bullet $ </code></pre></div></div> <p>效果:$ \star $ , $ \ast $, $ \oplus $, $ \circ $, $ \bullet $</p> <h4 id="7常用希腊字母">7、常用希腊字母</h4> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ \alpha $ // 阿尔法 $ \beta $ // 贝塔 $ \gamma $ // 伽马 $ \delta $ // 德尔塔,变化量 $ \epsilon $ // 伊普西龙 $ \zeta $ // 泽塔 $ \eta $ // 伊塔,机械效率 $ \lambda $ // 兰姆达,常数 $ \mu $ // 缪,摩擦系数 $ \pi $ // 派,圆周率 $ \rho $ // 柔,极径 $ \sigma $ // 西格马,方差 $ \tau $ // 陶,力矩 $ \phi $ // 斐,欧拉函数 $ \chi $ // 希,卡方分布 $ \omega $ // 欧米伽,电阻 </code></pre></div></div> <p>效果: <br /> $ \alpha $, $ \beta $, $ \gamma $, $ \Delta $, $ \epsilon $, $ \zeta $, $ \eta $, $ \lambda $, $ \mu $, $ \pi $, $ \rho $, $ \sigma $, $ \tau $, $ \phi $, $ \chi $, $ \omega $</p> <p><a href="https://img.gorpeln.top/blog/2025/17384679236/20250202114523961.png">更多希腊字母</a></p> <h4 id="8多行公式">8、多行公式</h4> <h5 id="1换行">1)换行</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$$ \begin{aligned} a \\ b,c \\ d \end{aligned} $$ # '\\'是换行 </code></pre></div></div> <p>效果: <br /> \(\begin{aligned} a \\ b,c \\ d \end{aligned}\)</p> <h5 id="2空格">2)空格</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$a \ b $ # '\'表示一空格 </code></pre></div></div> <p>效果:$a \ b $</p> <h5 id="3对齐">3)对齐</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$$\begin{aligned} [(n+1)!+k]\operatorname{mod}k &amp;=(n+1)!\operatorname{mod}k+k\operatorname{mod}k \\ &amp;=0+0 \\ &amp;=0 \end{aligned}$$ # '&amp;'是对齐 </code></pre></div></div> <p>效果: <br /> \(\begin{aligned} [(n+1)!+k]\operatorname{mod}k &amp;=(n+1)!\operatorname{mod}k+k\operatorname{mod}k \\ &amp;=0+0 \\ &amp;=0 \end{aligned}\)</p> <h5 id="4方程组">4)方程组</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$$ \begin{cases} x_1+x_2=2 \\ x_1-x_2=0 \end{cases} $$ </code></pre></div></div> <p>效果: <br /> \(\begin{cases} x_1+x_2=2 \\ x_1-x_2=0 \end{cases}\)</p> <h5 id="5矩阵与行列式">5)矩阵与行列式</h5> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$$ \left( \begin{matrix} a &amp;b \\c &amp;d \end{matrix} \right) , \left| \begin{matrix} a &amp;b \\c &amp;d \end{matrix} \right| $$ </code></pre></div></div> <p>效果: <br /> \(\left( \begin{matrix} a &amp;b \\c &amp;d \end{matrix} \right) , \left| \begin{matrix} a &amp;b \\c &amp;d \end{matrix} \right|\)</p> <h4 id="9表格">9、表格</h4> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$$\begin{array}{c|lcr} n &amp; \text{左} &amp; \text{中} &amp; \text{右} \\ \hline 1 &amp; 0.24 &amp; 1 &amp; 125 \\ 2 &amp; -1 &amp; 189 &amp; -8 \\ 3 &amp; -20 &amp; 2000 &amp; 1+10i \\ \end{array}$$ </code></pre></div></div> <p>效果: <br /> \(\begin{array}{c|lcr} n &amp; \text{左} &amp; \text{中} &amp; \text{右} \\ \hline 1 &amp; 0.24 &amp; 1 &amp; 125 \\ 2 &amp; -1 &amp; 189 &amp; -8 \\ 3 &amp; -20 &amp; 2000 &amp; 1+10i \\ \end{array}\)</p>

2025/2/2
阅读更多

Mac应用发布错误:ITMS-91109

<h3 id="问题">问题</h3> <p>今天进行 时光本 macOS端 更新的时候,上传安装包到 App Store Connect 成功后,但是在 App Store Connect 一直无法看到相应的构架包,查看邮件后发现了一个警告邮件:Action needed: The uploaded build for 时光本-日记本·笔记本·记事本·备忘录 has one or more issues.</p> <blockquote> <p>App Store Connect</p> <p>Hello,</p> <p>We noticed one or more issues with a recent delivery for the following app:</p> <p>时光本-日记本·笔记本·记事本·备忘录 Version 1.2.9 Build 129 Please correct the following issues and upload a new binary to App Store Connect.</p> <p>ITMS-91109: Invalid package contents - The package contains one or more files with the com.apple.quarantine extended file attribute, such as “com.gorpeln.xxx.pkg/Payload/GPNotesForMac.app/Contents/Resources/zh-Hans.lproj/Main.strings”. This attribute isn’t permitted in macOS apps distributed on TestFlight or the App Store. Please remove the attribute from all files within your app and upload again.</p> <p>Apple Developer Relations</p> </blockquote> <p>在网上查找这个错误提示表明,提交到 App Store 的 macOS 应用程序包中包含一个或多个带有com.apple.quarantine扩展文件属性的文件,比如com.gorpeln.xxx.pkg/Payload/GPNotesForMac.app/Contents/Resources/zh-Hans.lproj/Main.strings,而这种属性是不被允许的。</p> <p>com.apple.quarantine属性是 macOS 的一个安全特性,用于标记从不受信任的来源获取的文件,例如通过互联网下载或 AirDrop 接收的文件,以防止潜在的恶意软件。要解决这个问题,需要移除应用程序中所有文件的 com.apple.quarantine 属性。</p> <p>看到网上的结果后知道是安装包中某些文件被添加了com.apple.quarantine 属性,具体可能导致相关错误的原因也很多:</p> <ul> <li>下载来源的影响</li> <li>Xcode 构建过程问题</li> <li>系统安全机制</li> <li>第三方软件干扰</li> </ul> <p>但是具体怎么被添加的就不得而知了,于是就进行了漫长的排查解决过程,最后结果让自己很无奈。</p> <h3 id="解决思路">解决思路</h3> <h4 id="步骤一-解压安装包">步骤一: 解压安装包</h4> <p>首先导出安装包,按照提示路径,找到对应文件,使用 xattr 查找该文件是否有 com.apple.quarantine ,查找结果显示的确有,并且有标记是keka解压软件,因为我是用的keka进行的安装包解压,想着keka的标记应该是该流程添加,并不是原来 com.apple.quarantine 属性添加的直接原因,于是就尝试其他方法解决该问题。</p> <h4 id="步骤二更新-xcode">步骤二:更新 Xcode</h4> <p>为什么要更新 Xcode 呢,因为在提交 macOS 版本前先提交了 iOS 版本,iOS 版本提交后,提交成功页面显示有警告内容,提示马上要强制使用 Xcode 16 进行开发发布了,所以就想着是不是当前 Xcode 版本太低了导致的呢,于是就进行了更新操作,经过漫长的下载安装,问题依然存在,使用新的 Mac 用户也不行,只能想其他方法了。</p> <h4 id="步骤三操作导出的安装包">步骤三:操作导出的安装包</h4> <p>Xcode 更新不行,想着提示有具体的安装包错误内容路径,就操作删除相关内容的 com.apple.quarantine 属性,网上也有相应的操作流程<code class="language-plaintext highlighter-rouge">xattr -rd com.apple.quarantine /path/to/YourApp.app</code>,操作后继续提交,还是不行,还是同样的错误。</p> <p>分析这个步骤只是进行简单的安装包操作,没有对安装包里面的内容遍历操作,于是想着进行一下遍历删除操作,但是该操作又无法直接遍历安装包内部内容,于是就进行相应的解压,遍历删除相关属性,操作还算顺利,并且重新打包上传,上传直接就报错了,提示证书问题,确实重新打包没有使用证书,重新查找资料,配置相关重新打包证书,完成打包成功上传,但是苹果接着发来邮件提示证书还是有问题。</p> <blockquote> <p>Hello,</p> <p>We noticed one or more issues with a recent delivery for the following app:</p> <p>时光本-日记本·笔记本·记事本·备忘录 Version 1.3.4 Build 134 Please correct the following issues and upload a new binary to App Store Connect.</p> <p>ITMS-90237: The product archive package’s signature is invalid. Ensure that it is signed with your ‘3rd Party Mac Developer Installer’ certificate.</p> <p>Apple Developer Relations</p> </blockquote> <p>查找 ITMS-90237 问题的解决方法,正确配置相关证书后依然不行,感觉这个方法不太靠谱,虽然能够成功删除 com.apple.quarantine 属性,但是重新将解压的安装包打包十分复杂,想着还是换个方法。</p> <p>该步骤相关操作代码:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import os import subprocess import shutil def remove_quarantine_attribute(pkg_path): extract_dir = os.path.expanduser('~/Desktop/unpacked_pkg') if os.path.exists(extract_dir): try: shutil.rmtree(extract_dir) print(f"已删除现有的 {extract_dir} 目录。") except Exception as e: print(f"删除 {extract_dir} 目录时出错: {e}") return try: os.makedirs(extract_dir) print(f"成功创建 {extract_dir} 目录。") except Exception as e: print(f"创建 {extract_dir} 目录时出错: {e}") return try: # 尝试使用 xar 解压 print("尝试使用 xar 解压 pkg 文件...") result = subprocess.run(['xar', '-xf', pkg_path, '-C', extract_dir], capture_output=True, text=True) if result.returncode != 0: print(f"使用 xar 解压失败: {result.stderr}") return else: print("使用 xar 解压成功。") # 打印解压后的目录内容,便于检查 print(f"解压后的目录 {extract_dir} 内容:") for item in os.listdir(extract_dir): print(item) pkg_inner_dir = os.path.join(extract_dir, 'com.gorpeln.xxx.pkg') payload_path = os.path.join(pkg_inner_dir, 'Payload') if os.path.exists(pkg_inner_dir) and os.path.exists(payload_path): # 进入 Payload 所在目录并进行进一步处理 os.chdir(pkg_inner_dir) try: # 执行 cat Payload | gunzip -dc | cpio -i 操作 print("正在对 Payload 进行进一步解压...") command = 'cat Payload | gunzip -dc | cpio -i' result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=60) if result.returncode == 0: print("Payload 进一步解压成功。") else: print(f"对 Payload 进一步解压时出错: {result.stderr}") except subprocess.TimeoutExpired: print("对 Payload 进一步解压时超时,请检查 Payload 文件是否正常。") except subprocess.CalledProcessError as e: print(f"对 Payload 进一步解压时出错: {e.stderr}") finally: # 切换回上级目录 os.chdir('..') # 遍历所有文件并移除属性 for root, dirs, files in os.walk(extract_dir): for file in files: file_path = os.path.join(root, file) try: subprocess.run(['xattr', '-d', 'com.apple.quarantine', file_path], check=True) print(f"成功移除 {file_path} 的 com.apple.quarantine 属性。") except subprocess.CalledProcessError: # 如果文件没有该属性,忽略错误 pass # 找到 .app 文件 app_path = None payload_extracted_dir = os.path.join(pkg_inner_dir) for item in os.listdir(payload_extracted_dir): if item.endswith('.app'): app_path = os.path.join(payload_extracted_dir, item) break if app_path is None: print("未找到有效的 .app 应用程序包。") return # 签名 .app 包内的所有文件 certificate_name_app = "3rd Party Mac Developer Application: xxxxxxxx (xxxxxxxxx)" find_command = f'find "{app_path}" -type f -exec codesign --force --deep --sign "{certificate_name_app}" \{\{\}} \;' subprocess.run(find_command, shell=True) # 签名 .app 包本身 codesign_command = f'codesign --force --deep --sign "{certificate_name_app}" "{app_path}"' subprocess.run(codesign_command, shell=True) # 重新打包成 pkg 文件 new_pkg_path = pkg_path.replace('.pkg', '_cleaned.pkg') install_path = '/Applications' certificate_name_installer = "3rd Party Mac Developer Installer: xxxxxxxx (xxxxxxxxx)" productbuild_command = [ 'productbuild', '--component', app_path, install_path, '--sign', certificate_name_installer, new_pkg_path ] result = subprocess.run(productbuild_command, capture_output=True, text=True) if result.returncode != 0: print(f"重新打包并签名 pkg 文件时出错:{result.stderr}") else: print(f"处理完成,新的签名 pkg 文件已生成: {new_pkg_path}") except Exception as e: print(f"处理过程中出现错误: {e}") finally: if os.path.exists(extract_dir): try: shutil.rmtree(extract_dir) print(f"已成功删除临时目录 {extract_dir}。") except Exception as e: print(f"删除临时目录 {extract_dir} 时出错: {e}") # 使用示例 pkg_path = '/Users/gorpeln/Desktop/123/GPNotesForMac.pkg' remove_quarantine_attribute(pkg_path) </code></pre></div></div> <h4 id="步骤四删除-mac-破解软件">步骤四:删除 Mac 破解软件</h4> <p>怀疑是电脑上安装的某些破解软件导致的,于是进行删除操作,包括删除了keka解压软件,再次尝试打包,问题依然没有解决。想想上个版本到现在电脑上也没有新安装什么应用,应该不是这个原因,只能想其他方法。</p> <h4 id="步骤五删除代码中的相关文件">步骤五:删除代码中的相关文件</h4> <p>尝试直接删除提示有问题的文件,该文件在项目中是语言适配文件,做本地化处理的,删除后虽然对应用体验有一定的影响,但是也没有好的办法,只能先删了提交后再慢慢看具体问题了。删除后提交,居然又发邮件提错误了。。。</p> <blockquote> <p>App Store Connect</p> <p>Hello,</p> <p>We noticed one or more issues with a recent delivery for the following app:</p> <p>时光本-日记本·笔记本·记事本·备忘录 Version 1.3.8 Build 138 Please correct the following issues and upload a new binary to App Store Connect.</p> <p>ITMS-91109: Invalid package contents - The package contains one or more files with the com.apple.quarantine extended file attribute, such as “com.gorpeln.xxx.pkg/Payload/GPNotesForMac.app/Contents/Resources/MLHudAlertInfo.png”. This attribute isn’t permitted in macOS apps distributed on TestFlight or the App Store. Please remove the attribute from all files within your app and upload again.</p> <p>Apple Developer Relations</p> </blockquote> <p>看到这个错误后心凉半截,删除了一个文件,但是同样错误又显示了一个新的文件,肯定不能再删除了,因为还不知道到底有多少文件被标记了 com.apple.quarantine 属性,其中被标记的还可能是核心代码,删除后影响项目运行的。并且标记的这个文件应该是一个第三方库文件,想着应该是第三方库有问题,输入搜索后没有发现对应文件,猜想可能是pod导入导致的错误。</p> <h4 id="步骤五固定和更新第三方库">步骤五:固定和更新第三方库</h4> <p>查看 Podfile 文件中第三方库都没有固定版本,想着可能是第三方库更新到新版本后出现了相关问题,于是就设置了所有库的对应版本并进行更新,提交上传,问题依旧。迷茫了,不知道该怎么办了。</p> <h4 id="步骤六降级-xcode-版本">步骤六:降级 Xcode 版本</h4> <p>脑子一昏,想着是不是 Xcode 版本高的问题,用比较旧的版本会不会好呢,于是就下载安装了。显而易见,并不会。因为在app上个版本到现在我除了这次升级,并没有操作 Xcode 版本,正常不会是 Xcode 版本问题的。</p> <h4 id="步骤七删除源码中的相关属性">步骤七:删除源码中的相关属性</h4> <p>不知不觉,这个问题搞了一天了。没想法了,想着还是直接删除提示的对应文件吧,再次搜索提示的MLHudAlertInfo.png,居然看到了这个相关文件,进入查看具体内容,查找在Finder中的内容,确实存在MLHudAlertInfo.png文件。那这就好办了呀,直接查看这个文件是否包含 com.apple.quarantine 属性就行了呀,使用 xattr 查看后,的确存在,<em class="color-gray">我感觉有点无语</em>,基本确认是源码问题,直接使用 xattr 遍历删除项目文件夹下所有文件,重新提交上传,问题完美解决了。</p> <h3 id="总结">总结</h3> <p>具体该问题是怎么导致的呢?</p> <ul> <li>静下来想想,无轮提示的 Main.strings 还是 MLHudAlertInfo.png,都是最近甚至多个版本都没有修改过,甚至 MLHudAlert 是导入后只使用,完全没有修改过的,再根据过程中提示到的 keka 解压软件标记,我推测大概率文件相关 com.apple.quarantine 的属性在相关文件下载后使用 keka 解压的时候就已经被标记了,跟随项目多个版本,但由于苹果官方最近收紧对 com.apple.quarantine 属性的检测导致构架包一直无法通过。</li> </ul> <p>总结这次问题,为什么耗费了这么长时间呢?</p> <ul> <li>macOS 软件开发较少,可参考的资料也较少,只能自己摸索</li> <li>解决问题思路问题:一直想的是前面的版本没问题,这次不行,应该是这次上次到这次提交之间修改某些文件导致的,没想到被苹果背刺了。</li> <li>第一次查找MLHudAlertInfo时,可能是因为手动输入错误导致没有成功搜索到相关文件</li> </ul> <p>最后,如果感兴趣可以去查看使用一下【时光本】应用,是一款专注效率与记录的笔记工具。可以帮助你整理各种信息,包括便签、清单、图片、纪念日、地址、链接、银行卡、名片、账号、密码等</p>

2025/1/18
阅读更多