从“不存在”的重复请求,聊到 Web 存储的深坑

在 Web 开发中,有些 Bug 的隐蔽性极高,它们往往藏在浏览器的底层机制和复杂的交互链路中。最近我们遇到了一个关于"邀请码重复绑定"的诡异问题,最终溯源发现,这不仅涉及前端的存储选择,还涉及浏览器对网络请求的展示逻辑。


问题背景

项目中有个典型的裂变需求:用户 A 分享链接给用户 B,B 点击链接进入站点(URL 携带邀请码),点击登录后调起微信授权,登录成功后前端调用 /invites/bind 接口完成绑定。

现象: 后端数据库出现了同一个用户被重复绑定的两条记录。 初步排查: 后端日志显示,两个 /invites/bind 请求几乎在同一秒(间隔仅几十毫秒)到达服务器。


疑点一:消失的"第二次请求"

前端最初的结论是: "后端背锅" 。理由看似非常充分:

  1. 控制台证据 :Network 面板从头到尾只显示了一条 bind 请求。
  2. 逻辑自洽 :前端代码对 bind 请求做了严格控制,执行前会判断 SessionStorage 中是否存在邀请码,请求发出的那一刻会立即清空该值。理论上,第二次请求根本过不了判断逻辑。

然而,后端日志是铁证。为什么控制台只显示一条请求,后端却收到了两条?

真相: 在极短的时间内(毫秒级)发送两个完全相同的请求,部分浏览器(或特定环境下的网络代理)在控制台中会将其合并显示,或者其中一个请求因为网络链路的并发特性被归类为同一条记录的重试/后续。这导致了开发者被 Network 面板"欺骗"了。


疑点二:SessionStorage 的"隐身双胞胎"

既然请求确实发了两次,那前端的 SessionStorage 清空逻辑为什么失效了?

我们重新梳理了业务链路:

  1. 用户进入页面,邀请码存入 SessionStorage。
  2. 用户点击登录,页面拉起微信授权窗口。
  3. 关键点:在微信环境或模拟环境下,授权过程可能涉及窗口的派生或重定向。

SessionStorage 的生命周期虽然局限于"标签页",但有一个容易被忽视的特性:通过 window.open 或特定重定向方式打开的新页面,会复制父页面的 SessionStorage。

在这个业务场景中,由于微信授权的交互逻辑,实际上在某一瞬间存在两个"窗口上下文"。它们各自拥有独立的 SessionStorage 副本。

  • 窗口 A :触发登录逻辑,发出 bind 请求,清空了自己的邀请码。
  • 窗口 B :由于是并行触发或瞬间创建,它也持有一份邀请码,几乎在同一时间也发出了 bind 请求。

因为两个窗口是独立的执行环境,窗口 A 的清空操作无法影响到窗口 B,导致防重逻辑在多环境并发下彻底失效。


解决方案:从 SessionStorage 切换到 LocalStorage

针对这个坑,最直接的解法是将存储介质从 SessionStorage 切换为 LocalStorage。

为什么有效?

  • 全局唯一性 :LocalStorage 在同源的所有标签页和窗口之间是共享的。
  • 同步状态 :当窗口 A 发出请求并执行 localStorage.removeItem('invite_code') 时,窗口 B 在纳秒级的时间内再次读取时,该值已经不复存在。

总结

这两个 Bug 给我们的启示是:

  1. 不要盲目迷信控制台:当后端日志与前端控制台冲突时,优先信任后端原始日志,或者使用抓包工具(如 Charles/Fiddler)查看底层的 TCP/HTTP 流量,那是不会骗人的。
  2. 慎用 SessionStorage 做关键校验 :在涉及多窗口、弹窗授权或重定向的复杂链路中,SessionStorage 的隔离性往往会带来意想不到的并发问题。对于需要"全局一次性"的业务标记,LocalStorage 或配合后端的分布式锁才是更稳妥的选择。
相关推荐
ss27312 分钟前
AI全栈实战 | 3.5-01 Python 全栈前端最小集:不会 React 也能做出能看的后台,关键就一条线
前端·python·react.js
人工智能培训16 分钟前
数字孪生驱动大模型工业知识库:为具身机器人植入领域专业经验
大数据·linux·服务器·前端·人工智能
维克兜率天29 分钟前
【维克】通道突破:画出趋势的“轨道线“
前端·数据库·人工智能
Ai-_Man30 分钟前
从聊天框到正式文档:AI导出鸭瞄准AI大模型应用的“最后一公里”
开发语言·前端·javascript·人工智能·小程序
乌暮38 分钟前
拆解网页的底层逻辑:用费曼学习法讲透 HTML 与 CSS
前端·css·学习·html
陈随易10 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
福兮说11 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
传人once13 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.4613 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
库拉镜像AI牛牛15 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别