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

23-01-10 banq

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

我决定将整个应用程序的状态编码为一个Base64编码的字符串,放在url的hashmark中。例如,一个url看起来像(注意它被截断了,因为它们非常长)。


knotend.com/g/aN4IgzgpgTglghgGxgLwnARgiAxA9lAWxAC5QA7X...

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

下面是创建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-stirng或pako。

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

另一个很大的好处是,这些尿液可以被嵌入。这意味着用户可以把他们的图表放在任何支持嵌入的EWB页面上。我看到人们通常用像Notion这样的维基做这个,这意味着你可以与团队分享,而不需要任何人在我的网站上有一个账户。

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


感谢hacker news上redleader55的评论,他指出使用window.location.hashmark更适合存储较长的url,因为一些浏览器在通过http发送url时会截断它,不会截断hashmark,它会保存在客户端。