博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何制作离线友好的表单?
阅读量:6191 次
发布时间:2019-06-21

本文共 3083 字,大约阅读时间需要 10 分钟。

本文翻译自 。

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

先睹为快,。

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

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

class OfflineForm {  // setup the instance.  constructor(form) {    this.id = form.id;    this.action = form.action;    this.data = {};    form.addEventListener('submit', e => this.handleSubmit(e));  }}复制代码

在 submit 的处理函数中,可以使用 navigator.onLine 来检查网络链接情况,这个 API ,就算要实现也比较简单。

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

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

handleSubmit(e) {  e.preventDefault();  // parse form inputs into data object.  this.getFormData();  if (!navigator.onLine) {    // user is offline, store data on device.    this.storeData();  } else {    // user is online, send data via ajax.    this.sendData();  }}复制代码

保存表单

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

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

storeData() {  // check if localStorage is available.  if (typeof Storage !== 'undefined') {    const entry = {      time: new Date().getTime(),      data: this.data,    };    // save data as JSON string.    localStorage.setItem(this.id, JSON.stringify(entry));    return true;  }  return false;}复制代码

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

devtools.png

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

message.png

考虑得真是周到呀!

检查保存的数据

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

constructor(form){  ...  window.addEventListener('online', () => this.checkStorage());  window.addEventListener('load', () => this.checkStorage());}复制代码

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

checkStorage() {  if (typeof Storage !== 'undefined') {    // check if we have saved data in localStorage.    const item = localStorage.getItem(this.id);    const entry = item && JSON.parse(item);    if (entry) {      // discard submissions older than one day. (optional)      const now = new Date().getTime();      const day = 24 * 60 * 60 * 1000;      if (now - day > entry.time) {        localStorage.removeItem(this.id);        return;      }      // we have valid form data, try to submit it.      this.data = entry.data;      this.sendData();    }  }}复制代码

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

removeItem() 方法即可。

sendData() {  // send ajax request to server  axios.post(this.action, this.data)    .then((response) => {      if (response.status === 200) {        // remove stored data on success        localStorage.removeItem(this.id);      }    })    .catch((error) => {      console.warn(error);    });}复制代码

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

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

如果有兴趣,可以。

转载地址:http://nvrda.baihongyu.com/

你可能感兴趣的文章
Common Logging包装设计
查看>>
【BZOJ】1051 [HAOI2006]受欢迎的牛
查看>>
Linux 模块编译问题分析
查看>>
2^1000的各位数字和
查看>>
bzoj2730(割点+分类讨论)
查看>>
秒杀系统架构优化思路
查看>>
AJAX的简洁写法
查看>>
中国金融体系简略图
查看>>
Hadoop 配置好hive,第一次在conf能进入,第二次就不行了,怎么办?
查看>>
Centos7 编译安装PHP7
查看>>
spoj3105 MOD - Power Modulo Inverted(exbsgs)
查看>>
Apache Camel 与 Spring Boot 集成,通过FTP定时采集、处理文件
查看>>
D.6661 - Equal Sum Sets
查看>>
确保每一步的业务代码都能够正确执行。
查看>>
iOS调用系统相册、相机 显示中文标题
查看>>
SEU第一次训练练习题
查看>>
Ansible安装
查看>>
-sh: ./helloworld: not found
查看>>
5.IntellijIDEA常用快捷键总结
查看>>
The type org.springframework.core.io.support.ResourcePatternResolver cannot be resolved. It is ind
查看>>