如何制作离线友好的表单?

cover

本文翻译自 Offline-Friendly Forms

在网络不佳的情况下表单的表现并不理想。如果提交表单的时候恰好断网了,辛苦填好的数据有可能就找不回来了。下面就分享一下我们是如何修复这个问题的。

先睹为快,CodePen 上的 Demo

自从有了 Service Worker,开发者可以为用户提供离线版的 Web 应用。静态资源的缓存相对比较容易,但对于需要和服务端交互的表单来说就有点困难了。不过还好,我们还是有办法为离线提供一种 fallback 的方案。

首先,创建一个与离线友好表单相对应的 Class。将表单的 idaction 保存下来,并绑定表单的 submit 事件。

在 submit 的处理函数中,可以使用 navigator.onLine 来检查网络链接情况,这个 API 浏览器都支持得差不多了,就算要实现也比较简单。

但是这个 API 存在误报的可能。因为这个属性只能表示存在网络链接,并不保证网络是通的。反过来,如果结果是 false 就可以明确表示是断网的。因此据此判断是否离线是一种相对靠谱的方式。

如果用户处于离线状态,我们将表单提 hold 住,把表单数据保存在本地。

保存表单

我们有数种在用户设备商保存数据的方式。根据数据的特点,你可以使用 sessionStorage,如果不想把数据存储在内存种,也可保存在localStorage 中。

给表单数据付上一个时间戳,挂在一个新对象上。然后使用 localStorage.setItem 保存。这个方法接受两个参数,key(表单 id) 和 value(通常是一个 JSON 字符串)。

注意:可以在 Chrome 的开发者工具的 Application 标签中查看 storage 数据。如果不出差错,里面的内容如下:

devtools.png

还有最好将离线的情况告知用户,告诉他们填写的数据并不会丢失。补充 handleSubmit 方法,将这些信息反馈给用户。

message.png

考虑得真是周到呀!

检查保存的数据

一旦用户联网,就需要检查一下本地是否存在未提交的表单。我们需要监听 online 事件跟踪网络链接的变化,或者页面刷新触发的 load 事件。

当这些事件触发时,我们只需检查在 storage 中是否存在与表单 id 相匹配的数据。根据表单数据类型的不同,可能需要添加一个过期时间的判断,只允许在特定的时间内的表单。这一点对于偶尔网络链接异常的情况很有效果,避免错误地把两个月以前保存在本地的表单提交。

如果表单成功提交,则还需要最后一步,将表单数据从 localStorage 清除。比如说一个 Ajax 表单,我们可以在服务端成功返回后马上实施清除动作。这里简单使用 storage removeItem() 方法即可。

如果实在不想使用 Ajax 提交,另外一种处理方案就是将数据回填表单,直接调用 form.submit() 提交,或者让用户自己点击提交按钮提交。

注意:简单起见,我略去了一些环节,比如表单验证以及安全 token 验证等等。这些步骤在真正的产品开发中是必不可少的。还有一个问题是关于敏感数据的处理,避免在本地明文存储用户密码信用卡信息等等。

如果有兴趣,可以在 CodePen 里查看完整的例子:

See the Pen Offline Form by Max Böck (@mxbck) on CodePen.

1 收藏 1 评论

相关文章

可能感兴趣的话题



直接登录
最新评论
  • 许孟子~ 前端开发工程师 11/08

    将数据存储在localStorage是一种好习惯.

    但是要注意的是如果不是认为清除掉,它会永久存在,要是每个网站都这么弄的话,那将是很恐怖的事,哈哈

跳到底部
返回顶部