2023年1月

我正在开发一个在浏览器中运行的流程图编辑器,我想要一种方法让人们无需登录或在我们的服务器上存储任何数据即可使用它。我想让他们控制自己的数据,并能够将其存储在本地以便稍后打开和编辑。并且还可以轻松地与其他人分享。通过支持文件上传/下载很容易做到这一点,但我想要更简单的东西,比如通过发送 url 进行共享的能力。我也不想在后端存储任何东西(至少对于免费层)。

我决定将整个应用程序状态编码为 URL 哈希标记中的 Base64 编码字符串。例如,一个 url 看起来像(注意它被截断了,因为它们很长):


knotend.com/g/a#N4IgzgpgTglghgGxgLwnARgiAxA9lAWxAC5QA7X...

之后的所有内容`/g/a#`都是 json 对象的字符串化版本,其中包含有关流程图的所有信息。它被字符串化,然后压缩,然后进行 Base64 编码。我会在每次图形编辑时更新 url,因此复制图形状态就像在浏览器栏中复制 url 一样简单。

下面是创建 url 的伪代码,稍后再阅读它:


const stateString = JSON.stringify(appState); // appState is a json object
const compressed = compress(stateString);
const encoded = Base64.encode(compressed);
// Push that `encoded` string to the url
// ... Later, on page load or on undo/redo we read the url and
// do the following
const decoded = Base64.decode(encoded); // same encoded as above, but read from url
const uncompressed = uncompress(decoded);
const newState = JSON.parse(uncompressed);
// Now load your application with the newState

有几个选项可用于实现压缩/解压缩功能,例如 lz-stirngpako

因为我在每次图形编辑时都会更新它,所以我免费获得了一些重要的东西——撤消/重做。浏览器的历史堆栈成为我的撤消/重做功能。用户可以点击浏览器的后退/前进按钮,或我映射到历史弹出和推送的 Command-Z、Command-Shift-Z。对于我想快速发货的免费产品来说,这是一个重大胜利。

另一个很大的好处是可以嵌入这些 url。这意味着用户可以将他们的图表放在任何支持嵌入的 ewb 页面上。我看到人们通常使用像 Notion 这样的维基来这样做,这意味着您可以与团队共享而无需任何人在我的站点上拥有帐户。

您可以通过查看我正在使用的以键盘为中心的流程图编辑器 knotend来了解它是如何工作的。

之前的工作,谢谢。

我不是第一个采用这种方法的人。我以前至少见过mermaidjs这样做过,而且我敢肯定还有其他人这样做。

感谢redleader55 在黑客新闻上的评论,指出使用 window.location.hashmark 更适合存储更长的 url,因为某些浏览器在通过 http 发送 url 时会截断 url。但这不适用于保留在客户端的哈希标记。

如何在 url 中存储应用程序的整个状态