ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

防止会话超时数据丢失:session-timeout-recovery 可访问性规则实战指南

防止会话超时数据丢失:session-timeout-recovery 可访问性规则实战指南 防止会话超时数据丢失session-timeout-recovery 可访问性规则实战指南【免费下载链接】Front-End-Checklist The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist本文基于 Front-End-Checklist 仓库中skills/session-timeout-recovery/SKILL.md及其完整实现细则 references/rule.md结合仓库内规则内容包packages/content/rules/en/accessibility/session-timeout-recovery.mdx与前端源码系统讲解如何在登录态流程与长表单中设计「提前警告 时间延长 草稿保留 重新认证恢复」四段式防线帮助开发者落实 WCAG「足够时间Enough Time」相关成功标准。会话超时session timeout是几乎所有登录态应用的隐形陷阱静默登出会瞬间抹掉用户填了一半的表单、写了一半的工单、进行到一半的结账流程。对认知障碍、运动障碍、视力障碍用户而言这往往意味着整项任务无法完成。Front-End-Checklist 将这条规则归类为accessibility 类别、high 优先级、advanced 难度、预计耗时 30 分钟见 session-timeout-recovery.mdx 的 frontmatter核心要求是用户在会话到期前收到警告、在合适场景下可以延长时限、并且在重新认证后能够无缝恢复未丢失的工作状态。一、规则全景它在检查什么根据 SKILL.md 的 Quick Reference这条规则要求开发者从四个层面自我检查警告先行在超时导致工作丢失之前向用户发出明确警告允许延长对于内容可控的时间限制content-controlled time limits在可行时提供时间延长能力数据保留通过自动保存或在登出/重新认证之间保留已输入数据可访问性达标超时对话框必须支持纯键盘操作并能被辅助技术assistive technology正确播报。其 Check / Fix / Explain / Code Review 四段式工作流也原样收录在规则内容包的prompts字段中是 Agent 与人工审查者共同的执行框架阶段核心任务Check审查登录态流程、表单与长时任务确认用户被告知超时时长、到期前收到警告、允许时能延长会话、重新认证后可恢复工作Fix加入可访问的超时警告跨会话保留草稿或已提交数据重新认证后恢复到同一步骤内容可控的时间限制尽量提供关闭/调整/延长Explain向利益相关方解释警告、延长控制、自动保存与重新认证恢复如何减少数据丢失并符合 WCAG 足够时间指南Code Review审查登录态表单、结账流程、编辑器与长时任务标记所有可能静默过期、丢弃已输入数据或阻碍重新认证后恢复的路由与组件该规则在仓库中被accessible-authentication可访问认证等规则引为关联规则见 accessible-authentication.mdx同时在 rules-catalog.md 中被全局收录是整个可访问性规则体系中的关键一环。二、为什么它关乎可访问性而非单纯安全规则文档references/rule.md明确强调这绝不只是便利性问题。超时通常出于安全或运维考虑而被加入但许多用户需要更多时间去阅读、思考、切换设备、收集信息或使用辅助技术。如果站点在无警告的情况下将其登出或在重新认证后清空其草稿交互将变得极其困难甚至无法完成。受影响的核心人群与场景包括认知可访问性用户可能需要额外时间理解说明或收集必需信息运动与语音输入使用替代输入方式时输入数据耗时更长低视力和屏幕阅读器用户阅读和浏览复杂表单需要更多时间与反复检查关键任务场景结账、福利申请、医疗表单、客服工单、安全账户流程往往包含高摩擦、高成本的数据录入。2.1 与 WCAG 的对应关系从规则内容包的sources字段见 session-timeout-recovery.mdx可以完整看到这条规则所锚定的 WCAG 成功标准标准角色关注点WCAG 2.2 SC 2.2.1 Timing Adjustable时间可调主标准警告、恢复与状态保留属于同一个用户任务WCAG 2.2 SC 2.2.5 Re-authenticating重新认证实现依据过期后重新认证不应丢失上下文与数据WCAG 2.1 SC 2.2.6 Timeouts超时实现依据超时的策略理由可能是正当的但不免除保留用户控制的责任对应的支撑技术resources字段包括G105保存数据以便用户重新认证后继续使用G181将用户数据编码到重新授权页面中。三、反面示例静默超时是如何摧毁工作的规则文档给出的反面代码references/rule.md 的 Code Examples非常典型——一个 15 分钟无任何警告的硬登出!-- Bad: silent timeout discards work -- form idclaim-form !-- Long form fields -- /form script setTimeout(() { window.location.href /login }, 15 * 60 * 1000) /script这段代码的问题可以逐条拆解零警告计时器到点直接跳转/login用户没有任何倒数提示零恢复跳转时不携带任何状态参数重新登录后回到首页草稿荡然无存零控制用户无法延长会话也无法选择在超时前主动保存零可访问性没有任何 ARIA 属性、焦点管理或实时区域播报屏幕阅读器用户根本无从得知发生了什么。这种模式会在结账、长表单等场景直接转化为用户的真实损失——这也是为什么规则要求审查者专门 Flag「能静默过期、丢弃已输入数据或阻碍重新认证后恢复」的路由与组件。四、正面实现一可访问的会话超时警告对话框规则文档提供了一个完整的 React TypeScript 实现references/rule.md 的 Code Examples 第二段这也是全仓库最完整的可参考范例。它实现了「提前 14 分钟警告 15 分钟强制登出 60 秒倒计时 焦点管理 键盘操作」的完整闭环import { useEffect, useRef, useState } from react const WARNING_MS 14 * 60 * 1000 const LOGOUT_MS 15 * 60 * 1000 export function SessionTimeoutWarning({ onExtend, onLogout, }: { onExtend: () Promisevoid onLogout: () void }) { const [open, setOpen] useState(false) const [remainingSeconds, setRemainingSeconds] useState(60) const extendButtonRef useRefHTMLButtonElement(null) useEffect(() { const warningTimer window.setTimeout(() { setOpen(true) }, WARNING_MS) const logoutTimer window.setTimeout(() { onLogout() }, LOGOUT_MS) return () { window.clearTimeout(warningTimer) window.clearTimeout(logoutTimer) } }, [onLogout]) useEffect(() { if (!open) return extendButtonRef.current?.focus() const interval window.setInterval(() { setRemainingSeconds((value) { if (value 1) { window.clearInterval(interval) return 0 } return value - 1 }) }, 1000) return () window.clearInterval(interval) }, [open]) async function handleExtend() { await onExtend() setRemainingSeconds(60) setOpen(false) } if (!open) return null return ( div rolealertdialog aria-modaltrue aria-labelledbysession-timeout-title aria-describedbysession-timeout-body h2 idsession-timeout-titleYour session is about to expire/h2 p idsession-timeout-body For security, you will be signed out in {remainingSeconds} seconds. Select Stay signed in to keep working without losing your draft. /p button ref{extendButtonRef} typebutton onClick{handleExtend} Stay signed in /button button typebutton onClick{onLogout} Sign out now /button /div ) }这段代码值得精读的实现细节两个独立的计时器WARNING_MS14 分钟只负责打开警告LOGOUT_MS15 分钟负责真正触发登出二者解耦组件卸载时通过 cleanup 清除避免内存泄漏rolealertdialogaria-modaltrue向辅助技术声明这是一个阻塞式、必须响应的模态警告aria-labelledby/aria-describedby分别关联标题与正文让警告有清晰的「可访问名称」和「可访问描述」打开瞬间移动焦点extendButtonRef.current?.focus()让键盘用户直接落在主要恢复动作上焦点管理不依赖鼠标每秒递减的倒计时setInterval更新remainingSeconds倒计时归零时自动清理 interval延长后重置handleExtend先await onExtend()完成会话续期再把倒计时重置为 60 并关闭对话框。五、正面实现二重新认证前的草稿保留规则文档给出的第三个代码示例解决了「401 之后数据不能丢」的问题先保存草稿再跳转登录登录后按 draftId 拉回// Good: preserve work before redirecting to re-authenticate async function submitProtectedDraft(formData: Recordstring, string) { const response await fetch(/api/secure-submit, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(formData), }) if (response.status 401) { const { draftId, loginUrl } await response.json() window.location.href ${loginUrl}?resume${draftId} return } return response.json() } async function resumeDraftAfterLogin(draftId: string) { const response await fetch(/api/drafts/${draftId}) return response.json() }5.1 客户端草稿持久化仅限非敏感数据规则文档进一步给出了sessionStorage本地草稿方案并附上重要安全边界客户端草稿存储仅限非敏感数据且需向用户说明保留行为。// Client-side draft persistence for non-sensitive fields const DRAFT_KEY support-ticket-draft function saveDraftLocally(formData: Recordstring, string) { sessionStorage.setItem(DRAFT_KEY, JSON.stringify(formData)) } function restoreDraftLocally() { const draft sessionStorage.getItem(DRAFT_KEY) return draft ? JSON.parse(draft) : null }5.2 仓库中的客户端状态持久化实践这种「客户端存储 会话恢复」的模式在仓库自身的前端代码中就有同类实践。以 apps/web/lib/framework-preferences.ts 为例它用localStorage的preferred-framework键保存用户的框架偏好并在读取时做了typeof window undefined守卫以避免服务端渲染崩溃export function getStoredFrameworkPreference(): ChecklistFramework | null { if (typeof window undefined) { return null } const stored window.localStorage.getItem(FRAMEWORK_STORAGE_KEY) return isChecklistFramework(stored) ? stored : null }值得注意的差异点偏好设置属于「非敏感、可恢复」数据适合持久化到localStorage而草稿这类「正在编辑、可能含敏感字段」的数据规则文档明确建议优先存服务端如/api/drafts/:id客户端仅做非敏感回退。仓库的进度追踪apps/web/hooks/use-progress.ts也采用了类似思路——登录用户从/api/progress拉取服务端记录失败时优雅降级为空集合避免前端持久化带来跨设备数据不一致。5.3 状态恢复清单规则文档用一张表格定义了「重新认证后恢复到什么程度」的完整期望这也是测试断言的直接依据需要恢复的状态期望行为路由 Route回到超时的流程本身而不是首页步骤 Step恢复当前向导或结账步骤字段值 Field values重新填充已输入的数据错误与帮助上下文 Error and help context重新展示用户完成任务所需的信息焦点 Focus将焦点移到恢复后的标题、摘要或下一个必需操作上六、警告 UI 的可访问性规范规则文档references/rule.md 的 Best Practices 小节对超时警告 UI 提出了明确要求——超时警告不只是安全 UI而是「可访问性关键对话框」应当与其他重要交互同等对待阻塞式、需要用户响应的警告使用rolealertdialog被动的「会话即将到期」提示使用live region 或rolestatus实时播报需要操作时将焦点移入警告确保警告仅凭键盘即可操作且有清晰的可访问名称不要把唯一的恢复选项藏在仅悬停或仅指针可用的 UI 中。6.1 警告时机的 WCAG 对齐阈值警告应在可能造成数据丢失的动作之前显示理想情况下至少提前 20 秒延长应通过简单的动作完成例如按一个按钮若时间限制由内容控制在可行时允许重复延长提前告诉用户不活跃时间如何计算、数据会发生什么。七、例外场景何时可以不延长规则文档Exceptions 小节基于 WCAG 2.1 SC 2.2.6 Timeouts 的「理解文档」给出基线超时的策略理由可能正当但这并不免除在可能的情况下保留用户控制的责任。例外包括本质性的时间限制实时拍卖、固定时长的考试或延长会令活动失效的任务——此类可豁免延长安全/欺诈/隐私要求不活跃后自动登出是合法的但不免除警告、解释超时策略并在政策允许时保留工作的义务敏感数据持久化的合规约束若法律、隐私或产品审查不允许持久化则保留重新认证恢复所需的最小安全状态或在用户开始前给出明确警告内容外部控制的超时后台的不活跃超时未必完全受页面作者控制但作者编写的前端流程仍应避免可避免的数据丢失。八、验证与测试把恢复流程写进 CI规则文档Verification 小节最重要的方法论是用重新认证指南验证的不只是登出计时器本身而是警告行为与恢复流程的完整闭环。8.1 自动化检查清单在测试环境中把不活跃超时缩短到 60 秒之类的实用值让警告与恢复流程能在 CI 中真正跑起来增加端到端测试等待警告出现并确认它在破坏性超时边界之前出现断言警告拥有可访问名称、可访问描述以及可键盘操作的动作断言选择「Stay signed in」后用户留在同一流程且当前数据完好断言让会话过期后重新认证能恢复之前的草稿、步骤和路由若用户被重定向到登录页、且成功重新认证后先前数据缺失规则判定失败。8.2 手动检查步骤启动一个有意义的认证流程并录入数据停止交互直到警告出现确认它说明了超时及可用的恢复动作仅用键盘延长会话确认焦点逻辑合理重复流程让会话过期重新认证确认草稿与当前步骤被恢复用屏幕阅读器测试确认警告在可操作的时间窗口内被播报只有当用户绝不需要因会话过期而重新输入已录入数据时才判定通过。8.3 仓库测试基建参考仓库的 e2e 基建apps/web/e2e/smoke.spec.ts展示了 Playwright getByRole的可访问性断言风格例如按角色与可访问名称定位元素await expect(page.getByRole(heading, { name: All Rules })).toBeVisible()按这条规则的要求为超时警告写测试时应使用同款风格断言rolealertdialog、警告的可访问名称getByRole(alertdialog, { name: Your session is about to expire })与「Stay signed in」按钮将上述自动化检查清单落地为可回归的用例。九、落地路径从审查到发布综合 SKILL 与规则文档落地这条规则的完整路径为审计列出所有登录态路由、长表单、结账与编辑器组件标记静默超时与无恢复逻辑的位置对应 Code Review 阶段分层防线服务端优先保存草稿G105非敏感字段可加sessionStorage回退登录 URL 携带resume参数G181UI 组件实现带rolealertdialog、焦点管理与倒计时的警告组件提前至少 20 秒出现支持一键延长恢复路由重新认证后回到原路由、原步骤、原字段值并把焦点放到正确位置测试闭环把超时缩短到 60 秒写进 CI e2e覆盖警告出现时机、键盘操作、延长不丢数据、过期后恢复完整状态四类断言人工复核按第八节的手动清单用键盘与屏幕阅读器各走一遍。通过这条链路团队能把「防止数据丢失」从一句口号变成可审查、可测试、可回归的工程规范——这正是 Front-End-Checklist 把该规则定为high 优先级、advanced 难度的原因它同时考验前端状态管理、服务端会话策略与无障碍实现三方面的功底。【免费下载链接】Front-End-Checklist The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表