切换后需保留当前页面与状态
别名: 原位语言切换 · 路由本地化 · 表单状态保留 · locale switch state
概念解释
保留状态的语言切换(state-preserving language switch)让用户改变界面语言后仍处于同一任务、等价页面和安全可恢复的进度,而不是被送回首页或清空所有输入。保留对象需要经过明确 allowlist:语言中立的 route 身份、必要 query、筛选与分页、已确认选择,以及适合保留的表单草稿。密码、验证码、支付数据、一次性令牌和未授权内容不能因为“保留状态”而跨边界复制。
机制
把语言编码进路径文本或为每种语言维护独立页面树,容易使切换器只能猜测目标 URL;刷新式切换又会销毁客户端状态。安全实现使用语言中立 route ID 映射各语言路径,把可序列化任务状态与显示字符串分开,并逐项决定哪些 query 和表单字段可以迁移。认证会话可以继续存在,但目标 route、对象和动作必须重新经过授权与内容可用性检查。对未提交表单,迁移草稿不等于重放 POST;否则一次语言切换可能重复付款、上传或其他副作用。
怎么研究
为每条关键旅程建立“切换前状态→允许保留→必须清除→目标内容状态”矩阵,覆盖列表筛选、搜索、分页、滚动、步骤流程、未提交表单、验证错误、上传、结账、受限对象与多标签页。测试匿名、已登录、会话过期、权限变化、目标语言内容缺失和前后端版本不一致。指标包括返回首页率、草稿丢失率、重复提交、越权内容暴露、回退语言出现和任务恢复时间;安全测试针对开放重定向、query 注入、CSRF、敏感字段进入 URL 和对象级授权绕过。
边界
“同一页面”是同一任务语义,不保证每种语言都有逐字等价内容。若目标语言缺页,应留在原任务并明确显示回退语言、可用摘要或不可用原因,而不是假装切换成功或无提示跳首页。高风险流程可有意清除密码、验证码、支付字段或要求重新确认;这属于公开的安全边界,不是状态保留失败。用户生成内容的语言可以与界面语言不同,切换界面不应自动翻译或替换它。语言切换也不能提升认证、授权或地区内容权限。
怎么落地
- 用稳定 route ID 维护语言路径映射;为 query、hash、筛选、分页、滚动和表单字段分别建立迁移 allowlist 与版本,不复制未知参数或任意 return URL。
- 将安全可恢复的表单内容保存在本地组件状态或受保护的服务端草稿中,切换后重新渲染标签与错误。密码、验证码、支付数据和一次性凭证不得序列化到 URL、通用迁移载荷、持久草稿或跨 origin;遇到导航、重新认证、支付提供方或安全上下文变化等边界时清除,同一受信组件中的内存态则按威胁模型决定。绝不自动重放非幂等请求。
- 保持有效认证会话,但在目标 route 重新执行对象级授权、门禁和内容可用性检查。缺少翻译时显示明确语言标记与可返回路径,不静默降级或跳首页。
- 对每条核心旅程执行中途切换的端到端测试,断言 route、允许状态、焦点和任务结果;加入伪造 query、会话过期、权限撤回、语言包失败和重复提交测试,并让用户看见任何有意清除的范围。