Orbeon Forms:如何自动触发表单保存以避免数据丢失?
解决表单数据丢失:离开前自动触发表单保存的方法
方案一:拦截页面内链接点击事件
针对页面内的<a>标签,拦截点击行为,先完成表单保存再执行跳转:
// 监听所有页面内链接的点击事件 document.querySelectorAll('a').forEach(link => { link.addEventListener('click', async function(e) { // 阻止默认跳转 e.preventDefault(); const targetUrl = this.href; try { // 执行表单保存逻辑(替换为你的实际保存函数) await saveFormData(); // 保存成功后跳转,适配新窗口打开的情况 if (this.target === '_blank') { window.open(targetUrl); } else { window.location.href = targetUrl; } } catch (err) { console.error('表单保存失败:', err); // 可根据业务需求选择是否允许跳转,或添加用户提示 // window.location.href = targetUrl; } }); }); // 示例表单保存函数 async function saveFormData() { const form = document.getElementById('your-form-id'); const formData = new FormData(form); const res = await fetch('/api/save-form-data', { method: 'POST', body: formData }); if (!res.ok) throw new Error('保存请求失败'); }
方案二:监听页面卸载/离开事件
当用户关闭页面、刷新或跳转到外部域名时,用beforeunload事件触发本地存储备份(或同步保存):
// 页面离开前备份表单数据到本地存储 window.addEventListener('beforeunload', () => { const form = document.getElementById('your-form-id'); const formData = new FormData(form); const backup = {}; formData.forEach((val, key) => backup[key] = val); localStorage.setItem('form-temp-backup', JSON.stringify(backup)); // 注意:异步请求在beforeunload中可能被浏览器拦截,如需同步提交可使用同步XMLHttpRequest(不推荐,会阻塞页面) // const xhr = new XMLHttpRequest(); // xhr.open('POST', '/api/save-form', false); // xhr.send(new FormData(form)); }); // 页面加载时恢复本地备份的数据 window.addEventListener('load', () => { const backup = localStorage.getItem('form-temp-backup'); if (backup) { const data = JSON.parse(backup); const form = document.getElementById('your-form-id'); Object.keys(data).forEach(key => { const field = form.querySelector(`[name="${key}"]`); if (field) field.value = data[key]; }); } });
方案三:单页应用(SPA)路由跳转拦截
如果是Vue/React这类SPA框架,可通过路由守卫拦截跳转,完成保存后再放行:
Vue示例:
router.beforeEach(async (to, from, next) => { // 自定义函数判断表单是否有未保存内容 const hasUnsaved = () => { const form = document.getElementById('your-form-id'); // 简单示例:判断核心输入框是否有内容 return form.querySelector('input[name="content"]').value.trim() !== ''; }; if (hasUnsaved()) { try { await saveFormData(); next(); } catch (err) { console.error('保存失败:', err); next(false); // 阻止跳转,可添加用户提示 } } else { next(); } });
React示例(结合react-router):
import { useEffect } from 'react'; import { useHistory } from 'react-router-dom'; function FormComponent() { const history = useHistory(); useEffect(() => { const unblock = history.block(async (tx) => { const hasUnsaved = document.getElementById('your-form-id').querySelector('input[name="content"]').value.trim() !== ''; if (hasUnsaved) { try { await saveFormData(); unblock(); tx.retry(); } catch (err) { console.error('保存失败:', err); return false; // 阻止跳转 } } return true; }); return () => unblock(); }, [history]); // ...组件其余内容 }
内容的提问来源于stack exchange,提问作者Pete Atkin
相关产品推荐
相关产品推荐

