0xFF / 制作 Notes.cx
几天前,我启动了我的最新项目Notes.cx,这是我和妻子在车上时想到的一个小工具。当时,我正在(现在仍然)在我的另一个项目Diary.by上工作,所以我问我的妻子,她在 Diary.by 之类的东西中找到用处的可能性有多大。
我妻子提到她不是那种会记日记或写博客的人,这让我想起了她不久前提到的另一件事——她有时喜欢把事情写下来以帮助自己更好地处理它们。
我想如果有一个出口或空白你可以匿名地大声喊叫,只是为了把你的感受写下来,那将是非常整洁的。或者只是分享会议记录、临时文章或博客条目,这些文章或博客条目会在永远消失之前存在很短的时间。
要求
像这样的项目的要求并不多,可以归纳为要点:
- 创建笔记的简单、直接的体验。
- 易于阅读的笔记一旦呈现,无需过度设计。
- 笔记将以匿名方式保存,但在有限的时间内可供原作者编辑。
- 笔记,就像转瞬即逝的想法一样,是暂时的,只能保存 24 小时。
- 没有社交方面 – 这意味着没有喜欢、评论、赞成或其他方式。
挑战
尽管这个项目没有 Diary.by 复杂(并且总体上相当简单),但在创建它的过程中,我必须克服这些需求带来的一些挑战。仅举几例:
- 确保代码足够健壮,可以处理大量访问者戳、戳和测试工具(因为创建注释不需要注册或登录)。
- 确保没有存储关于笔记作者的 PII。
- 确保 UI/UX 在创建或阅读笔记时不会阻碍人们。
代码
建筑模块
值得庆幸的是,我最近开始以更可重用的方式编写代码。这实际上启动了该项目的开发,因为路由和模板至少已经作为制作Saisho和Diary.by 的一部分进行了处理。
匿名
当用户访问 Notes.cx 时,会为作者创建一个临时随机用户标识符,该标识符使用 SHA-256 散列并保存为 cookie。密钥是作者 IP 地址的 MD5 哈希random_bytes(32)
值,用于为此生成值。结果看起来有点像这样:
然后在数据库中创建笔记时使用这个哈希,看起来像这样:
由于散列是随机的,如果作者删除了允许编辑笔记的 cookie,则不再将作者与笔记联系起来(数据方面。nginx 日志记录仍然存在),除非作者决定自行保留 PII .
随机数
为了确保请求仅从表单发送,我决定生成一个 nonce 值,然后在创建注释后对其进行验证。由于随机数是临时的,我不一定需要与用户哈希相同级别的随机性,因此使用一个简单的字母随机数生成器来创建随机数:
public static function generateID(int $length = 32, ?int $negative = 0) : string {
$characterSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$id = '';
if ($negative > 0) {
$length = random_int($length - $negative, $length);
}
for ($i = 0; $i < $length; $i++) {
$id .= substr($characterSet, random_int(0, strlen($characterSet)), 1);
}
return $id;
}
随机生成的随机数与用户哈希相关联,作为一种额外的措施,以确保创建笔记的作者实际上是通过表单将其发送到数据库的人。如果 nonce 被验证,则将其删除并创建注释。
随机笔记ID
随机注释标识符使用所生成的generateID()
上述方法中,是这样的:generateID(10, 3)
。这将生成 7 到 10 个字符之间的随机字符串。为确保不存在重复项,会根据数据库检查生成的 ID,如果它已经存在,则会再次生成。
为了确保用户无法使用手动输入的标识符编辑注释(例如,将 URL 更改为https://notes.cx/edit/potato),在将用户重定向到编辑器表单之前,将保存生成的标识符在服务器上,然后在重定向后进行验证(这就是您也可以发现PHPSESSID
cookie 的原因)。
可能(很可能)有更好的方法来实现上述目标,但这就是我能想到的。
降价
我喜欢使用 Markdown,所以我也选择在这个项目中使用它。由于 Notes.cx 的重点是非常轻量级,因此前端没有特殊的编辑器,只有一个textarea
元素。
为了呈现 Markdown,我决定在后端使用广受欢迎的 Parsedown(以及 Extra 和 Extended 扩展),确保同时启用setSafeMode
和setMarkupEscaped
标志,以确保在解析内容后不会呈现 HTML。
清除旧数据
为了删除旧条目,MySQL 事件每小时运行一次以删除旧笔记,每半小时运行一次以删除旧随机数。数据库没有被备份,所以一旦它们被删除,就没有办法恢复它们。
前端
JavaScript
起初我决定不使用 JS 做任何事情,但目前它被用来为用户提供在桌面上复制笔记 ID 或在移动设备上打开共享菜单的能力。就是这样。
CSS
我很擅长让 CSS 文件看起来漂亮和有条理,所以整个事情都是一团糟。最重要的是,我决定不过度设计样式,就像我自己的网站和Diary.by 一样。我没有使用类,而是决定使用语义 HTML 和样式元素,以便很好地协同工作。
毕竟,这里的重点是作者的内容,而不是我的风格选择。
结论
这是一个有趣的小项目,我设法取得了成果,我打算继续运营,希望由我的其他项目(即 Diary.by)承担相关成本。
我在Hacker News和Product Hunt上分享了它以获得一些反馈和曝光。虽然有很多戳和刺激,但写了 1600 多条笔记,notes.cx 至少收到了 16.2k 独立访问者。根据 goaccess 的说法,所有这些的总传输量不到 22MB。
介绍平时我们Ping服务器的IP,只是ICMP协议传输获得的延迟,而某些IDC会把ICMP的延迟优化的很棒,实际上一走TCPing 就暴露了;而且我们使用过程中主要是TCP协议传输数据,所以可以测试一下TCPing得到的延迟;另外因为TCP协议的握手步骤原因,…
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666