← 返回文章列表
所属专题:AI 外骨骼

繁体中文闪一下又变英文?我让 AI 当“跑腿翻译”,自己专心钉死 LocalStorage 那条线

更新于 2025-06-10年份:2025字数:2,680阅读时长:8 分钟

一桩很土、很烦、很真实的 SPA:zh_HK 用户登录完像被英文附体。不写“赋能”小作文,只记我怎么把几小时的骂娘换成半小时能动手验证的节奏——AI 帮着列单子,我喂日志和代码;再补几句大实话:模型是在猜下一个词,不是你的线上替身;跳转前同步 lang 进 LS、多源优先级写死,真能救命。

TL;DR · 核心结论

  • 1模型是副驾驶:你给事实(日志、代码、复现),它帮你排假设;方向盘和事故报告还在你手里。
  • 2跳转前把 lang 写进 LS,URL 再带一份;优先级钉死,别让三年前的 key 骑在用户脸上。
  • 3资源包不认 zh_HK 就老老实实映射到现有包(例如简体顶着),别让 silent fallback 半夜替你做主。

那次 Bug 不尖叫、不抛栈,只在心里捅一刀:用户在繁体商品页点购买,跳完登录回来,界面礼貌地闪过一秒“像中文的东西”,然后非常体贴地回到英文默认。没有红字报错,只有你自己知道又输了。

我盯着 LocalStorage 和 `URLSearchParams` 盯到酸,才把另一位“同事”拽进群:大语言模型。下文两句就够——它到底能帮啥,以及咋用才不糟蹋电


先说人话:没人“思考”,大家都在接龙

自回归模型干的事很无聊:根据上文猜下一个 token。堆栈干净、重定向顺序写清楚,它接的话就更像隔壁 senior,而不是算命先生。

有人会塞文档片段进去(常说的 RAG):不是开光,是减少胡编文件名的概率,少开十个 Tab 也是赚的。

但它没有你的运行时:可以写漂亮优先级,却闻不到登录域和商城共用一个 origin、LS 里还躺着三年前 A/B 测试写的 `language: en_US`。我的习惯:让它吐假设和验证步骤,我来断点、看 Network、记谁先在谁头上踩了一脚。


一、案发现场:繁體中文去哪儿了

第一步: 用户在 zh_HK 商品页点 `login()`,心里以为稳了。

第二步: 跳转账大概是 `https://.../login?lang=zh_HK`,看上去人畜无害。

第三步: 登录成功,认证中心抡回业务域——你以为老乡见老乡,实际像被人偷偷按了“恢复默认”。

我当时的咆哮压成气音,只对显示器负责。


二、真凶往往不叫丢参,叫“谁覆盖谁”

断点一加,两个老六浮上来,都不配写进 README 自豪栏:

同域混用_LS: 商城和登录共用一个“客厅”LocalStorage。登录初始化若先舔一口残留的 `language: en_US`,再假装没看见 URL 上的 `?lang=zh_HK`,你就会拿下一局静默覆盖。用户眼里是闪一下;debugger 里是时序赢了,气质输光

i18n 不认账: 资源里只有 `zh_CN`,没有 `zh_HK`,框架温柔地英文兜底——温柔得你想请客吃饭换成请写检讨。

一句话收束:没有可信的“状态信任链”,只剩一堆“你肯定懂我”的幻觉。


三、和 AI 怎么分工,补丁才贴得牢

1. 让它打小票,你来盖章

我会丢:读语言的函数片段、跳转前后两行日志、Network 里 302 排队姿势。它常吐这类东西:

可能 A: URL 先读还是 LS 先读。

可能 B: 哪些 key 名跨项目容易撞车。

可能 C: 要不要在重定向前强行 `setItem`。

我不让它判死刑,但少按几次 F5也是实在的。Copilot 同理:省的是敲样板和翻旧 PR,脑力留给竞态,别留给和模型吵架。

2. 修起来很土,但要土得统一

共识写墙上:LocalStorage(用户明确选择)> URL(这一轮想说啥)> 默认 fallback。 别指望口耳相传能挡住线上翻车。

跳转前别装优雅,同步一锤子最实在:

const lang =
  getUrlValue("lang") || getAppLocale() || "en_US";

try {
  localStorage.setItem("language", lang);
} catch (e) {
  // 隐身模式、策略禁存:别让整个登录陪葬
  console.error("Storage sync failed:", e);
}

window.location.href = `${loginUrl}?lang=${encodeURIComponent(lang)}`;

别省 `encodeURIComponent`:有的语言码长得刁钻,不作不一定会死,作一下比较像干这行的。

3. i18n:可以偷懒,别对用户偷懒

给 `zh_HK`、`zh_MO` 一条台阶——先用简体包顶着也比陡然英文强,长期该补资源还是补:

const i18nConfig = {
  "zh-HK": messages["zh-CN"],
  "zh-MO": messages["zh-CN"],
};

文档写“已支持繁体”,代码 fallback 到 en,这种冷笑话我见得多了。AI 可以帮你扫一遍 locale 字符串、拉张现状表,省的是怨气,不是责任。


四、收尾:脏活各干各的,才像成年人干活

复杂 SPA 要问的不止“数据躺哪”,还有啥时候被谁顺手改了一刀

偏机器的: 拼清单、对坑、把 Slack 碎嘴整理成能执行的步骤——像招了个文员。

偏人的: 对真实用户拍板、盯时序、拒掉“看起来很对但跟日志分手”的结论——像项目经理兼半个肇事司机。

再加几条 hygiene:LS 用 try-catch 包一下;同域多应用 key 加 namespace;优先级画张图贴墙上,比口头祖传靠谱。

送给深夜的你:AI 不会让你一夜封神,只会让你更快发现——跟你在抢 LocalStorage 的,往往是六个月前那个觉得“先这样上”的自己。

本文属于 AI 实用主义流派 的第 3 篇肉身实战。

阅读时长:8 分钟


文档信息

版权声明:自由转载-非商用-非衍生-保持署名(CC BY-NC-ND 3.0)

原文链接:https://yijinlee.com/articles/article-3

作者:李奕锦

商业用途或修改衍生请联系授权。


李奕锦
李奕锦

全栈工程师,业余马拉松选手。

TL;DR

  • 模型是副驾驶:你给事实(日志、代码、复现),它帮你排假设;方向盘和事故报告还在你手里。
  • 跳转前把 lang 写进 LS,URL 再带一份;优先级钉死,别让三年前的 key 骑在用户脸上。
  • 资源包不认 zh_HK 就老老实实映射到现有包(例如简体顶着),别让 silent fallback 半夜替你做主。
Tags:状态管理LocalStorageURL SearchParamsI18n竞态条件 (Race Condition)LLM 辅助排障

参考文章:相关链接

权威引文 · 官方文档 · 站内深度文

  1. locale 响应式与 Composition API 切换点,便于对照 URL 参数竞态。

  2. 同源存储读写与配额边界,锁定「闪一下又变英文」的状态线。

  3. 容器与 H5 双端 locale 不同步的升级版案例。

  4. 从个案排障上升到可复用的 i18n 兜底架构。

该专题下的阅读路径

AI Coding架构排障

常见问题 FAQ

Q1. 为什么登录重定向后语言像被“鬼打墙”一样回到英文?
十有八九不是“参数丢了”,而是 URL、LocalStorage、i18n 三套叙事谁嗓门大没讲清楚:LS 里躺着上周的 en_US、URL 上的 zh_HK 被当空气、或者资源包压根不认 zh_HK 悄悄英文兜底——叠在一起,用户就看到“闪一下中文又变英文”的廉价悬疑片。
Q2. 这时候找 AI,它能替你断案吗?
能省时间,不能替你扛事故认定书。重定向链、读语言的顺序、各项目用的 key 名,贴全了它像个嘴碎的实习生:帮你列清单、对照常见翻车姿势。最后谁在什么时间覆盖了谁,还是得你自己开断点、画时序;它擅长把瞎试的范围收一收。
Q3. URL 和 LocalStorage 到底谁先谁后?
写进团队备忘录别客气:**用户亲手选的语言(LS)> 这一轮 URL 想宣布的 lang > 默认兜底。** 登录页若只信 LS,跳转前就乖乖把对的值写进去,URL 再捎一份双保险,别赌“下游会自己懂事”。

发表评论

分享你的想法和反馈

支持 Markdown 格式

0/5000