
立即开始,无需注册,访问 unforget.computing-den.com。
Unforget 是一款极简、离线优先且端到端加密的笔记应用(不使用 Electron.js),具有以下特点:
Unforget 由 Computing Den 开发,这是一家专注于 Web 技术的软件公司。
免费注册,将您的笔记安全地备份到云端,全程加密,并在各设备间同步。
无需提供电子邮件或电话。
直接在浏览器中使用或安装:
| 浏览器 | 安装方式 |
|---|---|
| Chrome | 地址栏中的安装图标 |
| Edge | 地址栏中的安装图标 |
| Android 浏览器 | 菜单 → 添加到主屏幕 |
| Safari 桌面版 | 共享 → 添加到程序坞 |
| Safari iOS 版 | 共享 → 添加到主屏幕 |
| Firefox 桌面版 | 无法安装 |
| Firefox Android | 地址栏中的安装图标 |
笔记按时间顺序组织,置顶笔记显示在顶部。
尽管简单,但这种组织方式已被证明非常有效。搜索非常快速(离线进行),只需输入几个短语即可快速缩小笔记范围。此外,您还可以搜索非字母字符,从而使用标签,如 #idea、#project、#work、#book 等。
笔记大小没有限制。对于较长的笔记,您可以在单独的一行插入 --- 来折叠笔记的其余部分。
笔记在您输入时立即保存,并每隔几秒钟同步一次。
如果您从两个设备编辑同一笔记,同步时发生冲突,将以最近的编辑为准。
Unforget 不会接收或存储任何个人数据。注册不需要电子邮件或电话。只要您选择一个强密码,您的笔记将被 完全加密并安全地存储在云端。
Unforget 服务器只能看到您的用户名和笔记修改日期。
与 Github 风格的 Markdown 的主要区别是:
--- 之后的所有内容都将被隐藏,并替换为一个"显示更多"按钮,点击后可展开笔记。# H1 标题
## H2 标题
### H3 标题
#### H4 标题
##### H5 标题
###### H6 标题
*这是斜体。*
**这是粗体。**
***这是粗斜体。***
~~这是删除线~~
- 这是一个项目符号
- 另一个项目符号
- 内部项目符号
- [ ] 这是一个复选框
与复选框相关的更多文本。
1. 这是一个有序列表项
2. 另一个有序列表项
[这是一个链接](https://unforget.computing-den.com)
使用反引号的内联`代码`。
代码块:
```javascript
function plusOne(a) {
return a + 1;
}
```
| 表格 | 很 | 酷 |
| ------------ |:------------:| -----:|
| 第3列是 | 右对齐 | $1600 |
| 第2列是 | 居中 | $12 |
水平线:
---
要为生产环境构建 Unforget,请在项目根目录下放置一个 .env 文件:
PORT=3000
NODE_ENV=production
DISABLE_CACHE=0
LOG_TO_CONSOLE=0
FORWARD_LOGS_TO_SERVER=0
FORWARD_ERRORS_TO_SERVER=0
然后运行
cd unforget/
npm run build
npm run start
建议使用 Nginx 作为反向代理,并使用 Let's Encrypt 设置 SSL 证书。
要在开发模式下构建和运行 Unforget,请在项目根目录下放置一个 .env 文件:
PORT=3000
NODE_ENV=development
DISABLE_CACHE=1
LOG_TO_CONSOLE=1
FORWARD_LOGS_TO_SERVER=0
FORWARD_ERRORS_TO_SERVER=0
然后运行
cd unforget/
npm run dev
这将构建项目并监视源文件的变化。
这里的所有路径都相对于官方服务器 https://unforget.computing-den.com 或您自己的服务器(如果您在自托管)。
在 examples/ 目录中,您会找到 TypeScript 和 Python 的示例代码。
要运行 TypeScript 示例:
cd examples/ # 注册 npx tsx example.ts signup USERNAME PASSWORD # 登录 npx tsx example.ts login USERNAME PASSWORD # 创建新笔记 npx tsx example.ts create "Hello world!" # 获取所有笔记 npx tsx example.ts get # 通过 ID 获取笔记 npx tsx example.ts get ID
要运行 Python 示例:
cd examples/ # 注册 python3 example.py signup USERNAME PASSWORD # 登录 python3 example.py login USERNAME PASSWORD # 创建新笔记 python3 example.py create "Hello world!" # 获取所有笔记 python3 example.py get # 通过 ID 获取笔记 python3 example.py get ID
type Note = { // UUID 版本 4 id: string; // 已删除的笔记 text 为 null text: string | null; // ISO 8601 格式 creation_date: string; // ISO 8601 格式 modification_date: string; // 0 表示已删除,1 表示未删除 not_deleted: number; // 0 表示已归档,1 表示未归档 not_archived: number; // 0 表示未置顶,1 表示已置顶 pinned: number; // 数字越大,在列表中越靠前 // 通常,默认情况下是自纪元以来的毫秒数 order: number; } type EncryptedNote = { // UUID 版本 4 id: string; // ISO 8601 格式 modification_date: string; // 加密的 Note,base64 格式 encrypted_base64: string; // 初始向量,用于加密这个特定笔记的随机数 iv: string; }
服务器只知道 EncryptedNote,从不看到实际的 Note。因此,客户端必须在发送到服务器之前加密笔记,并在从服务器接收笔记后解密。
附注:使用数字(0 和 1)而不是布尔值的原因是为了更容易将笔记存储在不支持布尔值的 SQLite 中。一些字段被反转(not_deleted 而不是 deleted)的原因是为了方便使用 IndexedDB,它不支持按任意顺序索引多个键。
要注册,向 /api/signup 发送 POST 请求,JSON 负载类型为 SignupData:
type SignupData = { username: string; password_client_hash: string; encryption_salt: string; }
要登录,向 /api/login 发送 POST 请求,JSON 负载类型为 LoginData:
type LoginData = { username: string; password_client_hash: string; }
在这两种情况下,如果凭据错误,您将收到 401 错误。否则,服务器将响应 LoginResponse 和 200 状态码:
type LoginResponse = { username: string; token: string; encryption_salt: string; }
要登出,向 /api/login?token=TOKEN 发送 POST 请求
在以下章节中,所有对服务器的请求都必须包含 token,可以作为 URL 中的查询参数(例如 /api/delta-sync?token=XXX)或名为 unforget_token 的 cookie。
请注意,我们从不向服务器发送原始密码。相反,我们计算其哈希值 password_client_hash,该值由用户名、密码和静态随机数派生而来。如果您希望能够使用官方 Unforget 客户端和您自己的客户端,使用完全相同的算法计算哈希值非常重要。encryption_salt 是用于派生加密和解密笔记的密钥的随机数。它存储在服务器上并在登录时提供。示例部分展示了如何计算哈希值和生成盐。
向 /api/get-notes?token=TOKEN 发送 POST 请求以获取所有笔记。您也可以选择提供 {ids: string[]} 类型的 JSON 负载来获取特定笔记。
您将收到 EncryptedNote[]。
向 /api/merge-notes?token=TOKEN 发送 POST 请求,并附带 {notes: EncryptedNote[]} 类型的 JSON 负载。
如果笔记不存在,它将被添加。
如果其 modification_date 大于现有笔记,它将替换现有笔记。
否则,它将被丢弃。
要删除笔记,请将其 text 设为 null,not_deleted 设为 0,然后合并它。这样,存根将保留在数据库中,并且删除事实将传播到所有其他客户端。
对于长期运行的客户端,您可以使用以下方式进行同步,而不是使用获取笔记和合并笔记。
客户端和服务器各自维护一个要发送给对方的更改队列以及一个同步编号。这些更改的交换称为增量同步。
登录时同步编号为 0,只有在接收到的所有更改都已合并并存 储后,每一方才会递增同步编号。在每次增量同步开始时,如果它们的同步编号不同,这表明上次增量同步出现问题,因此它们必须进行队列同步。
队列同步是指每一方发送其同步编号以及它所知道的所有笔记的 ID 和修改日期列表。队列同步后,双方都将知道对方缺少哪些更改,因此可以更新自己的队列和同步编号。
当同步编号为 0(登录后立即)时,服务器将在第一次增量同步中发送所有笔记。
要执行增量同步,向 /api/delta-sync?token=TOKEN 发送 POST 请求,并附带 SyncData 类型的 JSON 负载:
type SyncData = { notes: EncryptedNote[]; syncNumber: number; }
如果服务器同意 syncNumber,它将响应 DeltaSyncResNormal,其中包括自上次同步以来存储在服务器上的该客户端的更改。否则,服务器将响应 PartialSyncResRequireQueueSync,要求客户端启动队列同步。
type DeltaSyncResNormal = { type: 'ok'; notes: EncryptedNote[]; syncNumber: number; } type DeltaSyncResRequireQueueSync = { type: 'require_queue_sync'; }
要执行队列同步,向 /api/queue-sync?token=TOKEN 发送 POST 请求,并附带 SyncHeadsData 类型的 JSON 负载,其中包括客户端已知的所有笔记的头部和其同步编号。然后您将收到另一个 SyncHeadsData,其中包括服务器为该用户已知的所有笔记的头部以及服务器为该客户端的同步编号。
type SyncHeadsData = { noteHeads: NoteHead[]; syncNumber: number; } type NoteHead = { id: string; modification_date: string; }
队列同步后,每一方都会更新其队列以包括对方缺少的更改,并将新的同步编号设置为较大的同步编号 + 1。
重要的是,客户端和服务器要就笔记的合并方式达成一致,以便最终得到一致的状态。我们认为,如果 A.id == B.id 且 A.modification_date > B.modification_date,则笔记 A 必须替换笔记 B。
加密和解密的详细信息在代码中更容易解释。请参阅示例部分。
当遇到状态码 >= 400 的错误时,所有 API 调用都将返回 ServerError 类型的对象:
type ServerError { message: string; code: number; type: 'app_requires_update' | 'generic'; }
如果您收到类型为 app_requires_update 的错误,这表明您正在使用不再支持的旧版 API。


AI一键生成PPT,就用博思AIPPT!
博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使 用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频


实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。


选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


最强AI数据分析助手
小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。


像人一样思考的AI智能体
imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号