<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://blog.oopss.top/blog</id>
    <title>Brandon's Blog</title>
    <updated>2026-08-04T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://blog.oopss.top/blog"/>
    <subtitle>Brandon's Blog Blog</subtitle>
    <icon>https://blog.oopss.top/https://cdn.oopss.top/favicon.ico</icon>
    <rights>Copyright © 2026 Brandon</rights>
    <entry>
        <title type="html"><![CDATA[「cfmemos」—— 一个跑在 Cloudflare 上的自托管笔记]]></title>
        <id>https://blog.oopss.top/blog/cfmemos</id>
        <link href="https://blog.oopss.top/blog/cfmemos"/>
        <updated>2026-08-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[开源地址：https://github.com/Brandon-LIs/cfmemos]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>开源地址：<a href="https://github.com/Brandon-LIs/cfmemos" target="_blank" rel="noopener noreferrer" class="">https://github.com/Brandon-LIs/cfmemos</a>
在线体验：<a href="https://memos.oopss.top/" target="_blank" rel="noopener noreferrer" class="">https://memos.oopss.top</a></p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="为什么做这个">为什么做这个<a href="https://blog.oopss.top/blog/cfmemos#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%81%9A%E8%BF%99%E4%B8%AA" class="hash-link" aria-label="为什么做这个的直接链接" title="为什么做这个的直接链接" translate="no">​</a></h2>
<p><a href="https://github.com/usememos/memos" target="_blank" rel="noopener noreferrer" class="">Memos</a> 是我非常喜欢的一款自托管笔记工具——轻量、Markdown 原生、数据完全自持。于是我想：能不能用 <strong>Cloudflare 全家桶（Workers + D1 + KV + Assets）</strong> 把它 1:1 复刻一遍，让整个服务挂在 Cloudflare 的免费额度上，连服务器都不用买？</p>
<p>结果就是 <strong>cfmemos</strong>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="它长什么样">它长什么样<a href="https://blog.oopss.top/blog/cfmemos#%E5%AE%83%E9%95%BF%E4%BB%80%E4%B9%88%E6%A0%B7" class="hash-link" aria-label="它长什么样的直接链接" title="它长什么样的直接链接" translate="no">​</a></h2>
<ul>
<li class="">设计上直接移植了 Memos 官方前端的 <strong>OKLCH 设计令牌</strong>（暖白/石墨深色、可读性蓝主色、系统字体），左侧是固定的图标导航栏，中间是时间线，风格和 Memos 几乎一致。</li>
<li class="">支持浅色/深色主题一键切换。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="功能一览">功能一览<a href="https://blog.oopss.top/blog/cfmemos#%E5%8A%9F%E8%83%BD%E4%B8%80%E8%A7%88" class="hash-link" aria-label="功能一览的直接链接" title="功能一览的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><strong>用户系统</strong>：注册 / 登录 / 退出，登录状态用 <strong>30 天 HttpOnly Cookie</strong> 保存；<strong>第一个注册的用户自动成为管理员</strong>。</li>
<li class=""><strong>说说（Memo）</strong>：发布、编辑、删除、置顶；支持完整 <strong>Markdown</strong>（标题、加粗、列表、任务清单、代码块、引用、图片、链接、<code>#标签</code>）。</li>
<li class=""><strong>可见性</strong>：发布时可选 <strong>公开 / 私密</strong>。公开的进入「广场」供所有人（包括未登录访客）浏览；私密的只有自己和 API 能看。</li>
<li class=""><strong>唯一永久链接 + 评论</strong>：每条说说都有独立链接 <code>https://memos.oopss.top/m/&lt;id&gt;</code>，点进去可以看到详情和评论区，发布者和其他登录用户都可以评论。</li>
<li class=""><strong>图片上传</strong>：复用 Brandon 的图床 <code>admin.oopss.top/upload</code>（无需登录，任意字段名），说说里的图片自动走 jsdelivr 镜像并带兜底。</li>
<li class=""><strong>头像上传</strong>、<strong>昵称修改</strong>、<strong>生成 Memos 兼容的 API Key</strong>。</li>
<li class=""><strong>API 文档页</strong>：内置在 <code>/api-docs</code> 专用 URL，接口表格 + 输出示例齐全。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="技术栈全部免费额度">技术栈（全部免费额度）<a href="https://blog.oopss.top/blog/cfmemos#%E6%8A%80%E6%9C%AF%E6%A0%88%E5%85%A8%E9%83%A8%E5%85%8D%E8%B4%B9%E9%A2%9D%E5%BA%A6" class="hash-link" aria-label="技术栈（全部免费额度）的直接链接" title="技术栈（全部免费额度）的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>组件</th><th>用途</th></tr></thead><tbody><tr><td><strong>Cloudflare Workers</strong></td><td>后端路由 + 静态资源托管</td></tr><tr><td><strong>Cloudflare D1</strong>（SQLite）</td><td>用户、说说、标签、评论数据</td></tr><tr><td><strong>Cloudflare KV</strong></td><td>登录会话</td></tr><tr><td><strong>Cloudflare Assets</strong></td><td>前端 SPA（原生 HTML/CSS/JS，零构建）</td></tr><tr><td><strong>@cloudflare Pages/Workers</strong></td><td>部署（<code>wrangler deploy</code>）</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="与-memos-的-api-兼容">与 Memos 的 API 兼容<a href="https://blog.oopss.top/blog/cfmemos#%E4%B8%8E-memos-%E7%9A%84-api-%E5%85%BC%E5%AE%B9" class="hash-link" aria-label="与 Memos 的 API 兼容的直接链接" title="与 Memos 的 API 兼容的直接链接" translate="no">​</a></h2>
<p>除了自带的前端，我还实现了 <strong>Memos v1 兼容的 REST API</strong>（<code>/api/v1</code>）：<code>instance/profile</code>、<code>auth/me</code>、<code>signin</code>、<code>users</code>、<code>memos</code>、<code>comments</code> 等，返回结构与官方一致。这意味着<strong>官方 Memos 客户端/文档站可以直接对接</strong>这个实例。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="部署">部署<a href="https://blog.oopss.top/blog/cfmemos#%E9%83%A8%E7%BD%B2" class="hash-link" aria-label="部署的直接链接" title="部署的直接链接" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">git clone https://github.com/Brandon-LIs/cfmemos.git &amp;&amp; cd cfmemos</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">wrangler login</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">wrangler d1 create memos-cf-db            # 把 database_id 填进 wrangler.toml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">wrangler kv namespace create SESSIONS      # 把 id 填进 wrangler.toml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm run db:migrate                        # 应用 D1 迁移</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">wrangler deploy                           # 一键上线</span><br></div></code></pre></div></div>
<p>第一个注册的账号就是管理员。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="测试">测试<a href="https://blog.oopss.top/blog/cfmemos#%E6%B5%8B%E8%AF%95" class="hash-link" aria-label="测试的直接链接" title="测试的直接链接" translate="no">​</a></h2>
<p>内置了离线后端测试（模拟 D1 + KV，不需要真实账号）：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">node test/backend.test.mjs   # 目前 41 个用例全绿</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="为什么用-cloudflare-而不是-vps">为什么用 Cloudflare 而不是 VPS<a href="https://blog.oopss.top/blog/cfmemos#%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A8-cloudflare-%E8%80%8C%E4%B8%8D%E6%98%AF-vps" class="hash-link" aria-label="为什么用 Cloudflare 而不是 VPS的直接链接" title="为什么用 Cloudflare 而不是 VPS的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><strong>零成本</strong>：全部跑在免费额度上。</li>
<li class=""><strong>免运维</strong>：没有服务器要升级、打补丁。</li>
<li class=""><strong>全球加速</strong>：Cloudflare 边缘节点就近响应。</li>
<li class=""><strong>数据可控</strong>：D1 是标准的 SQLite 语义，随时可以导出。</li>
</ul>
<p>如果你也喜欢"小而美"的笔记工具，欢迎去 GitHub 看看、点个 Star、提 Issue，或者直接 fork 一份自定义成你自己的版本。</p>]]></content>
        <author>
            <name>Brandon</name>
            <uri>https://github.com/Brandon-LIs</uri>
        </author>
        <category label="Cloudflare" term="Cloudflare"/>
        <category label="项目" term="项目"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[生活|襄阳二日游记]]></title>
        <id>https://blog.oopss.top/blog/1</id>
        <link href="https://blog.oopss.top/blog/1"/>
        <updated>2026-08-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[湖北省城市足球联赛（楚超）第 12 轮宜昌东阳光队vs襄阳东风风神队的比赛 8.1 日在襄阳举行。借着这个机会，我顺道在襄阳游玩两日，也算是故地重游了吧。]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>湖北省城市足球联赛（楚超）第 12 轮宜昌东阳光队vs襄阳东风风神队的比赛 8.1 日在襄阳举行。借着这个机会，我顺道在襄阳游玩两日，也算是故地重游了吧。</p>
</blockquote>
<p>·楚超球赛<br>
宜昌队与襄阳队进行了激烈的对抗，作为我现场看的第一场楚超球赛，现场的气氛确实十分震撼，球员之间的配合也相当娴熟，几乎零失误。在双方队员激烈的攻防之下，最终比分保持了 0:0。襄阳队和宜昌队各积 1 分，暂时并列积分榜第三。
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020002.webp" alt="IMG20260801202139_BURST002" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020003.webp" alt="IMG20260801212416" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020004.webp" alt="IMG20260801212929" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020005.webp" alt="IMG20260801214107" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020006.webp" alt="IMG20260801214527" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020007.webp" alt="IMG20260801215530" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020008.webp" alt="IMG20260801215617" width="4096" height="3072" class="img_ev3q"></p>
<p>·米公祠<br>
坐落在襄阳樊城汉江边的米公祠，原名米家庵，是专为纪念北宋书法大家米芾修建的祠宇，也是国内保存最完整的米芾纪念建筑群，属全国重点文保单位、3A级景区。米公祠未成年人免费，全票20元，大学生半票10元。</p>
<p>始建于元代，经明清多次重修，整座院落是雅致的江南园林格局，白墙黛瓦、古银杏与池水相映。祠内碑廊珍藏190余方石刻，复刻米芾《蜀素帖》等经典行书，还有苏轼、黄庭坚、蔡襄宋代四家笔墨，是难得的书法宝库 。</p>
<p>园内拜殿、宝晋斋、洁亭错落分布，既能了解米芾“米颠”爱石、洁癖的趣事，登上仰高堂还能隔江眺望襄阳古城墙，兼具人文底蕴与临水风光，适合慢逛赏字、古风拍照。
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020009.webp" alt="IMG20260802104531" width="3072" height="4096" class="img_ev3q">
园中有很多亭台楼阁，十分雅致。
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020011.webp" alt="IMG20260802110102" width="3072" height="4096" class="img_ev3q"></p>
<p>·襄阳古城<br>
坐落汉江南岸的襄阳古城，有着2800余年建城史，人称华夏第一城池、铁打的襄阳，是国内保存完整的明清古城垣之一 。</p>
<p>古城最独特的亮点是亚洲最宽护城河，平均宽180米，城北以汉江天然为屏障，城墙全长7.3公里，六座城门皆配有瓮城，古代防御体系完整壮观 。登城墙全程免费，地标临汉门（小北门）直面汉江，白日可眺望对岸樊城、米公祠，夜晚城楼灯火倒映江面，氛围感十足。</p>
<p>城内北街古巷烟火浓郁，藏着襄阳牛肉面、黄酒等本地特色小吃；还有明代藩王府遗存绿影壁、昭明台博物馆、夫人城等古迹，三国、南宋守城的历史故事贯穿整座城池。既有金戈铁马的厚重历史，又有市井生活的温柔烟火，逛完对岸米公祠，过江漫步古城，是来襄阳必打卡的行程。</p>
<p>襄阳古城昭明台二楼、三楼为昭明台博物馆，全票 30 元，未成年人、60-70 岁20元。个人认为值得一看。
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020010.webp" alt="IMG20260802121721_01" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020012.webp" alt="IMG20260802125226" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020013.webp" alt="IMG20260802134327" width="4096" height="3072" class="img_ev3q"></p>
<p>·汉江江景<br>
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020014.webp" alt="IMG20260802111315" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020015.webp" alt="IMG20260802120109" width="4096" height="3072" class="img_ev3q"></p>
<p>·襄阳市博物馆<br></p>
<p>馆内文物众多，布展合理，历史底蕴丰富，镇馆之宝为三国青铜马。搭配免费讲解更佳。
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020016.webp" alt="IMG20260802153400" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020017.webp" alt="IMG20260802153431" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020018.webp" alt="IMG20260802155714" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020019.webp" alt="IMG20260802160153" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020020.webp" alt="IMG20260802160351" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020021.webp" alt="IMG20260802161504" width="4096" height="3072" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020022.webp" alt="IMG20260802162530" width="3072" height="4096" class="img_ev3q">
<img decoding="async" loading="lazy" src="https://jsd.oopss.top/uploads/2026/08020023.webp" alt="IMG20260802164008" width="3072" height="4096" class="img_ev3q"></p>
<p>总的来说，襄阳这座城市历史悠久，文化深厚，不虚此行！</p>]]></content>
        <author>
            <name>Brandon</name>
            <uri>https://github.com/Brandon-LIs</uri>
        </author>
        <category label="生活" term="生活"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[欢迎来到我的博客]]></title>
        <id>https://blog.oopss.top/blog/welcome</id>
        <link href="https://blog.oopss.top/blog/welcome"/>
        <updated>2026-07-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[欢迎来到我的博客！]]></summary>
        <content type="html"><![CDATA[<p>欢迎来到我的博客！</p>
<p>这里是我记录学习与生活的地方，主要分享：</p>
<ul>
<li class="">前端与计算机科学的学习笔记</li>
<li class="">AI 与工程化相关内容</li>
<li class="">我做过的一些小项目</li>
</ul>
<p>博客使用 <a href="https://docusaurus.io/" target="_blank" rel="noopener noreferrer" class="">Docusaurus</a> 构建，支持本地搜索，评论区基于 Gitalk，欢迎在评论区交流讨论。</p>
<p>联系邮箱：<a href="mailto:bcihal@qq.com" target="_blank" rel="noopener noreferrer" class="">bcihal@qq.com</a></p>
]]></content>
        <author>
            <name>Brandon</name>
            <uri>https://github.com/Brandon-LIs</uri>
        </author>
        <category label="博客" term="博客"/>
    </entry>
</feed>