H5 调试实战

H5 调试实战(一):微信 H5 localStorage 调试,在电脑上修改真机缓存

案例:换号后头像一直没变

一次公众号 H5 联调时,测试在群里反馈:

「公众号菜单里的 H5,换了测试号登录,头像还是上一个用户。清微信缓存、重新进菜单,都不行。」

第一反应通常都会怀疑:

  • 登录没成功?
  • 后端缓存了?
  • 微信缓存接口了?

于是先在 DevPeek 里抓包。

GET /api/user/profile

请求头里的 Authorization 已经是新账号的 Token。

响应体里的用户 ID、昵称也都是新用户。

从服务端来看,一切正常。

但是页面上,头像和昵称仍然是上一位测试账号。

这种现象基本可以确定:

接口已经正常,页面却没有使用接口返回的数据。

真正的问题,很可能已经不在 HTTP,而是在页面自己的本地缓存。

抓包正常,不代表页面读到的数据正常

很多 H5 登录流程都会把用户信息写到:

  • localStorage
  • sessionStorage
  • IndexedDB

随后页面渲染直接读取这些缓存,而不是每次重新请求接口。

如果换号时:

  • Token 更新了
  • Cookie 清了
  • 但 storage 没更新

就可能出现:

抓包看到的是新用户,而页面显示的仍然是旧用户。

这里有一个容易忽略的点:

HTTP 请求结束以后,页面如何把响应写进 localStorage、IndexedDB,属于浏览器 JavaScript 的运行时行为,并不属于抓包工具的职责。

抓包列表 擅长看 URL、Header、Body;参数转换 还能把密文 Body 解成明文。但 localStorage.getItem('auth_token') 不会出现在任何一列里。

因此很多:

  • 接口正常
  • 页面异常

的问题,仅靠 Network 很难定位。

真正缺失的信息是:

页面 JavaScript 此刻到底从 storage 里读到了什么。

桌面 DevTools 能看,但微信 WebView 不一样

如果同一个 URL 放到 Chrome 打开,当然可以直接去:

Application → Storage

查看 localStorage。

但测试要求必须在:

  • 微信公众号菜单
  • 微信扫码
  • 微信分享链接

这些真实环境里复现。

桌面 Chrome 和微信内置 WebView 往往不是同一套运行环境。

桌面改掉 storage,并不能证明微信里的问题已经解决。

当时现场就是:

  • 抓包确认 Header 已经是新 Token;
  • 微信页面仍显示旧头像。

两边信息始终对不上。

vConsole 能看日志,但查 Storage 仍然不够方便

团队项目以前集成过 vConsole,也有同事使用 eruda 等页内调试工具。

查看:

  • Console
  • Network
  • JS 报错

它们都非常方便。

真正开始排查 storage 时,就明显进入了另一个阶段。

例如:

  • localStorage 通常只能查看,修改往往需要切到 Console 手写脚本;
  • IndexedDB 虽然有插件支持查看,但 object store 层级较深时,在手机屏幕里浏览效率并不高;
  • 删除一条记录、修改 JSON,经常需要调用 indexedDB.open(...) 自己操作;
  • 手机屏幕有限,抓包窗口、需求文档、Storage 信息分散在不同设备之间,对照效率比较低;
  • 很多团队仍需要在 H5 中提前集成调试工具,临时联调时未必来得及发新版。

另外,微信 WebView 的 Remote Debug(chrome://inspect、Safari Web Inspector)虽然可以使用,但受微信版本、系统版本、USB 连接等因素影响,实际联调时可用性并不稳定。

下面是我们整理的一份对比(vConsole 类包含 vConsole、eruda 及常见 Storage 插件能力,不同版本可能略有差异):

能力 vConsole / eruda DevPeek · Session
localStorage 查看 一般支持 桌面表格查看
localStorage 修改 需 Console 脚本 图形界面修改并下发真机
sessionStorage 因插件而异 独立 Tab 查看与修改
document.cookie 部分支持 可查看可修改(HttpOnly 不可见)
IndexedDB 查看 支持查看 树形浏览
IndexedDB 修改 多数需脚本 JSON 编辑并下发
与抓包联动 Network 与 Session 同页
接入方式 通常需集成进 H5 代理注入,见 移动端网页调试

vConsole 并不是不好。

看日志、定位 JS 报错,它依然很好用。

只是这次真正卡住的问题是:

需要在真机微信环境里,反复修改、删除、核对 storage 与 IndexedDB。

这时候,小屏幕操作明显没有电脑端高效。

用 Session 面板定位:旧数据仍在 localStorage

手机 Wi‑Fi 代理指向 DevPeek,信任根证书,业务域名在 SSL 解密范围 里。完整清单见 移动端网页调试;若预览区一直停在「等待设备连接」,可对照 常见问题 排查注入与 WebSocket。

连接成功后,调试 Tab 会镜像微信里的 H5 页面;切到下方自研面板的 Session 分区:

  1. 抓包 Tab 确认该手机已有解密的 HTML 流量。
  2. 调试 Tab 选中对应 客户端 Tab;让测试从公众号菜单重新进入(旧标签页可能未注入脚本)。
  3. Session → localStorage,逐项确认:先看 Token,再看用户缓存。
  4. 发现 auth_token 仍保存的是上一位测试账号的 JWT。

抓包里的 Header 已经是新 Token,是因为请求阶段有时从内存变量读取了最新值;而页面头像读取的,却仍然是 localStorage——两边来源不同步。

DevPeek Session:localStorage 列表与编辑

在桌面直接改 key 的值并下发真机,不必在 Console 里手写 localStorage.setItem

修改 auth_token 为新账号对应值并确认下发后,再删除:

user_profile_cache

刷新页面,头像立即恢复正常。

这一刻,也基本确认了真正的问题所在。

DevPeek Session 面板展示的是当前页面 JavaScript 可访问的数据,而不是浏览器底层所有存储。因此 HttpOnly Cookie、微信 JSBridge、小程序原生 Storage 等内容仍然不在可编辑范围内;可见 Cookie 可在 Cookies 子 Tab 核对。

第二个问题:草稿订单始终删不掉

头像恢复后,测试顺手又提了另一个问题:

「草稿订单删除以后,重新打开列表,它又出现了。」

这种现象就不像 localStorage 了。

切到 IndexedDB,展开:

orders

很快发现:对应记录仍然保存在数据库里,状态字段也没有更新。

DevPeek Session:IndexedDB 库表与记录详情

树形展开 object store,选中记录后在详情区改 JSON 并下发——比在手机屏上手写 indexedDB API 省事。

确认字段后,直接修改 JSON 并下发;再次刷新页面,草稿订单终于真正消失。

很多「删除失败」「列表残留」「离线数据异常」的问题,本质上都属于 IndexedDB 数据没有同步,而不仅仅是接口返回异常。

联调时,我通常这样交叉验证

定位 storage 问题以后,我一般还会继续确认两件事:

  1. 回到调试面板的 Network,核对后续请求 Header 是否与 Session 里改过的值一致;
  2. 如果需要验证不同参数,切回 抓包 Tab,对同一行开「调试 API」改参重发,而不用再复制到 Postman。

这样 Session → Network → 页面 三部分始终保持同一条调试链路;批量清 key 或复杂脚本时,同一上下文里的 Console 也能远程 eval,删之前先确认 key 名。

边界与注意事项

并不是所有缓存问题都能通过修改 Storage 解决。完整边界见 移动端网页调试 文档。

例如:

  • localStorage 已修改,但接口仍返回 401,说明 Token 可能来自 HttpOnly Cookie 或其他登录状态——对照 Network 与 Session;
  • 微信仍缓存旧 HTML,可以重新进入公众号菜单,或增加 Query 参数强制刷新页面;
  • iframe 内页面属于另一 Origin,需要单独打开对应 URL 调试。

下一篇

《H5 调试实战(二):待整理》——系列后续会继续收录真实联调案例(Console 远程脚本、Network 与 Mock 联动等),而不只介绍工具本身。


若你也在微信 H5 联调里反复改 localStorage 和 IndexedDB,欢迎 下载 DevPeek 试用,或到 GitHub Discussions 聊聊——上手步骤见 移动端网页调试,代理与证书见 代理与 SSL 证书

相关文档