my-edge-blog 项目文档
概览
一个部署在 Cloudflare Workers 上的个人博客系统,纯服务端渲染(SSR),支持多主题切换、管理后台、Markdown 渲染、暗色模式等。共 5,495 行代码。
技术栈
| 层级 |
技术 |
| 框架 |
Hono v4 — 轻量 Web 框架,JSX 模板引擎 |
| 运行时 |
Cloudflare Workers — 边缘计算平台 |
| 数据库 |
Cloudflare D1 (SQLite) — 文章/设置存储 |
| 对象存储 |
Cloudflare R2 — 图片上传和管理 |
| KV |
Cloudflare KV — Admin Session 持久化 |
| Markdown |
marked + marked-highlight + highlight.js |
| 部署 |
Wrangler CLI |
| 类型 |
TypeScript (JSX: react-jsx + hono/jsx) |
| CSS |
原生 CSS + CSS 变量实现主题/暗色 |
完整功能清单
前端(4 套主题)
| 功能 |
说明 |
| 4 套独立主题 |
LoveIt (详细), PaperMod (简洁), Minimal (衬线留白), Tech (深色科技) |
| 首页文章卡片 |
分页展示,支持置顶帖子 |
| 文章详情页 |
标题/日期/分类/标签/阅读时间/字数统计/浏览计数 |
| Markdown 渲染 |
语法高亮 (highlight.js)、代码复制按钮、TOC 标题锚点 |
| 侧边栏目录 (TOC) |
文章页左侧可折叠目录,手机端浮动按钮 |
| 搜索功能 |
全文搜索 + 关键词高亮 + 摘要回退 |
| 标签系统 |
标签列表页、按标签筛选 |
| 分类系统 |
分类列表页、按分类筛选 |
| 归档页 |
按年月分组,显示文章计数 |
| 关于页 |
Markdown 编辑器的自由内容 |
| 暗色模式 |
localStorage 持久化 + 系统偏好检测,图片暗调 |
| 阅读进度条 |
顶部彩色进度条 |
| 分享按钮 |
微博 / X (Twitter) 一键分享 |
| 上一篇/下一篇导航 |
文章底部相邻文章链接 |
| RSS 订阅 |
/feed.xml 含全文 <content:encoded> |
| Sitemap |
/sitemap.xml 含分页、lastmod |
| robots.txt |
动态生成,含正确域名 Sitemap URL |
| JSON-LD |
Schema.org Article 类型结构化数据 |
| Open Graph |
OG title/description/url/image/type/site_name, article:published_time/modified_time, robots, Twitter cards |
| 访问者统计 |
浏览量计数 |
| 无障碍 |
ARIA 标签、:focus-visible 全局样式、:prefers-reduced-motion、::selection 样式 |
| 无 404 破损 |
图片 onerror 隐藏、搜索内容为空回退 |
管理后台
| 功能 |
说明 |
| Session 认证 |
KV 持久化 session + HttpOnly cookie |
| 登录速率限制 |
5 次/5 分钟,基于 IP |
| 文章 CRUD |
新建/编辑/删除/批量删除 |
| Markdown 编辑器 |
工具栏、分屏预览、拖拽上传、字数+阅读时间统计 |
| 主题切换 |
4 套主题一键切换 |
| 站点设置 |
标题/描述/页脚/GitHub/邮箱/头像/RSS 标题等 |
| 图片上传 R2 |
5MB 限制 + 类型白名单 + 速率限制 (20次/60秒) |
| 置顶帖子管理 |
添加/移除置顶,排序 |
| 社交链接管理 |
添加/编辑/删除 |
| 关于页编辑 |
Markdown 编辑器 |
| 数据导出 |
JSON 格式导出所有内容 |
安全措施
| 措施 |
实现 |
| XSS 防护 |
所有用户输入经 e() HTML 实体转义 |
| 安全头 |
X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy |
| CORS 控制 |
仅允许 github.io / localhost / 127.0.0.1 |
| 上传校验 |
文件类型白名单 + 大小限制 |
| 路径穿越 |
/assets/* 过滤 .. / / / \0 |
| CDN SRI |
highlight.js 加载带 integrity + crossorigin |
| 认证 |
KV session + HttpOnly + SameSite=Lax + Secure cookie |
数据库表结构
-- 文章表
posts (id, slug, title, summary, content, cover_image, tags, category,
published, created_at, updated_at, view_count)
-- 评论表(已建表,待开发)
comments (id, post_id, author, content, created_at)
-- 置顶帖子
pinned_posts (id, post_id, sort_order, created_at)
-- 站点设置
settings (key, value)
-- 社交链接
social_links (id, label, url, icon, sort_order, created_at)
源码结构
my-edge-blog/
├── src/
│ ├── index.ts (143行) 入口、认证路由、安全中间件
│ ├── routes.ts (273行) 公开路由(首页/文章/搜索/RSS/sitemap/robots)
│ ├── admin.ts (310行) 管理后台 CRUD + 主题/设置/上传
│ ├── db.ts (392行) D1 查询封装 + 内存缓存层
│ ├── auth.ts (19行) 共享认证模块
│ ├── marked.ts (46行) Marked 配置 + 自定义渲染器
│ └── templates.tsx (2147行) 所有 JSX 模板(4主题 Layout + Page)
├── public/
│ ├── common.css (577行) 共享样式
│ ├── theme-loveit.css (451行)
│ ├── theme-papermod.css (354行)
│ ├── theme-minimal.css (345行)
│ ├── theme-tech.css (438行)
│ └── robots.txt
├── migrations/ (6 个 SQL 迁移文件)
├── schema.sql (完整建表 SQL)
├── wrangler.jsonc (Cloudflare Workers 配置)
├── tsconfig.json (TypeScript 配置)
└── package.json (依赖配置)
路由表
| 路由 |
方法 |
功能 |
GET / |
public |
首页(第1页) |
GET /page/:page |
public |
分页 |
GET /post/:slug |
public |
文章详情 |
GET /tags |
public |
标签列表 |
GET /tag/:tag |
public |
按标签筛选(分页) |
GET /category/:category |
public |
按分类筛选(分页) |
GET /about |
public |
关于页 |
GET /search?q= |
public |
搜索 |
GET /archives |
public |
归档页 |
GET /feed.xml |
public |
RSS |
GET /sitemap.xml |
public |
Sitemap |
GET /robots.txt |
public |
Robots |
GET /assets/* |
public |
R2 图片代理 |
GET /admin |
auth |
后台首页 |
GET /admin/login |
auth |
登录页 |
POST /admin/login |
auth |
登录提交 |
POST /admin/logout |
auth |
登出 |
GET/POST /admin/new |
auth |
新建文章 |
GET/POST /admin/edit/:id |
auth |
编辑文章 |
POST /admin/delete/:id |
auth |
删除文章 |
POST /admin/bulk-delete |
auth |
批量删除 |
POST /admin/upload |
auth |
图片上传 |
GET/POST /admin/theme |
auth |
主题管理 |
GET/POST /admin/pinned |
auth |
置顶管理 |
GET/POST /admin/settings |
auth |
站点设置 |
GET/POST /admin/about |
auth |
关于页编辑 |
GET/POST /admin/social |
auth |
社交链接管理 |
GET /admin/export |
auth |
数据导出 |
部署文档(从头手搓)
前置条件
# 1. 安装 Node.js 18+
# 2. 安装 Wrangler CLI
npm install -g wrangler
# 3. 登录 Cloudflare
wrangler login
项目初始化
# 1. 创建项目目录
mkdir my-edge-blog && cd my-edge-blog
# 2. 初始化项目
npm init -y
npm install hono marked marked-highlight highlight.js
npm install -D wrangler @types/node
# 3. 配置 tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
"lib": ["ESNext"]
}
}
创建 Cloudflare 资源
# 1. 创建 D1 数据库
wrangler d1 create notion-d1
# 2. 创建 R2 存储桶
wrangler r2 bucket create notion-r2
# 3. 创建 KV namespace
wrangler kv:namespace create ADMIN_KV
# 4. 设置管理员密码
wrangler secret put ADMIN_PASSWORD
配置 wrangler.jsonc
将 d1_databases、r2_buckets、kv_namespaces 中的 ID 替换为上一步创建的值。
数据库初始化
wrangler d1 execute notion-d1 --file schema.sql
# 再依次执行所有 migrations/*.sql
本地开发
npm run dev
# 启动 http://localhost:8787
# 连接生产资源: npx wrangler dev --remote
部署
npm run deploy
# = wrangler deploy --minify
项目亮点
- 零外部 Frontend 框架 — 纯 Hono JSX SSR
- 零 CSS 框架 — 原生 CSS + 自定义属性
- 全站 SSR — 首屏极速
- 多主题架构 — 通过
Layout() 分发函数,新增主题只需加一个函数
- 内存缓存层 — 60s TTL 减少 D1 查询次数
- 边缘部署 — Cloudflare Workers 全球 300+ 节点
评论
评论功能即将上线,敬请期待。