表单提交失败后怎么优雅地恢复用户输入?

UX-松浩 阅读 42

我做了一个带校验的注册表单,用户填完点提交,结果网络出错,页面刷新了,所有输入都没了。这体验太差了,用户肯定要骂人。

试过用 sessionStorage 临时存字段,但不知道该在什么时候清理,而且如果用户中途离开再回来,还会自动填充旧数据,反而造成干扰。有没有更靠谱的做法?

比如能不能在提交失败时保留当前表单状态,而不是整个页面重载?现在用的是原生 fetch 提交,代码大概这样:

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const res = await fetch('/register', { method: 'POST', body: new FormData(form) });
  if (!res.ok) {
    // 这里怎么让用户别丢掉已经填的内容?
    alert('提交失败,请重试');
  }
});
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
爱学习的弯弯
这问题我也踩过坑,半夜被用户投诉说填了半小时的表单一刷新全没了,血压直接拉满。说几个实用方案:

1. 最简单的办法是改用AJAX提交,失败时不刷新页面。你这代码已经用了fetch,只要把alert换成更友好的错误提示就行。比如这样:
if (!res.ok) {
const error = await res.json();
showErrorToast(error.message); // 用浮动提示替代alert
// 表单数据还在,不需要处理
}


2. 如果非得刷新页面(比如服务端渲染场景),可以用localStorage配合页面加载时的数据恢复:
// 提交前保存
form.addEventListener('submit', () => {
const formData = Object.fromEntries(new FormData(form));
localStorage.setItem('draftForm', JSON.stringify(formData));
});

// 页面加载时恢复
window.addEventListener('DOMContentLoaded', () => {
const draft = localStorage.getItem('draftForm');
if (draft) {
const formData = JSON.parse(draft);
Object.entries(formData).forEach(([name, value]) => {
const input = form.querySelector([name="${name}"]);
if (input) input.value = value;
});
}
});


安全提醒:记得在提交成功时清除存储,否则下次会有脏数据。密码类敏感字段不要存,要单独处理。

3. 更专业的做法是加个自动保存功能,配合防抖(比如每30秒存一次)。但要注意竞态条件,别存到旧数据。

个人建议先用方案1,体验最好。方案2要小心localStorage的5MB限制,大表单可能存不下。
点赞
2026-03-09 00:01