[{"data":1,"prerenderedAt":30},["ShallowReactive",2],{"case-wechat-h5-storage-debug-zh":3,"blog-list-zh":13},{"slug":4,"title":5,"summary":6,"date":7,"featured":8,"seoDescription":9,"series":10,"seriesOrder":11,"html":12},"wechat-h5-storage-debug","H5 调试实战（一）：微信 H5 localStorage 调试，在电脑上修改真机缓存","微信 H5 换测试号后头像仍显示旧用户，抓包确认接口正常，却定位到 localStorage 遗留旧数据。本文记录一次真实联调过程，以及如何在电脑上查看、修改微信 WebView 的 localStorage、sessionStorage 和 IndexedDB。","2026-07-11",true,"微信 H5 调试实战：通过真实案例定位 localStorage、sessionStorage、IndexedDB 导致的数据缓存问题，对比 vConsole、Remote Debug 等方案，介绍真机 WebView 调试思路。","h5-debug",1,"\u003Ch2>案例：换号后头像一直没变\u003C\u002Fh2>\n\u003Cp>一次公众号 H5 联调时，测试在群里反馈：\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>「公众号菜单里的 H5，换了测试号登录，头像还是上一个用户。清微信缓存、重新进菜单，都不行。」\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>第一反应通常都会怀疑：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>登录没成功？\u003C\u002Fli>\n\u003Cli>后端缓存了？\u003C\u002Fli>\n\u003Cli>微信缓存接口了？\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>于是先在 DevPeek 里抓包。\u003C\u002Fp>\n\u003Cp>\u003Ccode>GET \u002Fapi\u002Fuser\u002Fprofile\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cp>请求头里的 \u003Ccode>Authorization\u003C\u002Fcode> 已经是\u003Cstrong>新账号\u003C\u002Fstrong>的 Token。\u003C\u002Fp>\n\u003Cp>响应体里的用户 ID、昵称也都是新用户。\u003C\u002Fp>\n\u003Cp>从服务端来看，一切正常。\u003C\u002Fp>\n\u003Cp>但是页面上，头像和昵称仍然是上一位测试账号。\u003C\u002Fp>\n\u003Cp>这种现象基本可以确定：\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>接口已经正常，页面却没有使用接口返回的数据。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>真正的问题，很可能已经不在 HTTP，而是在页面自己的本地缓存。\u003C\u002Fp>\n\u003Ch2>抓包正常，不代表页面读到的数据正常\u003C\u002Fh2>\n\u003Cp>很多 H5 登录流程都会把用户信息写到：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>localStorage\u003C\u002Fli>\n\u003Cli>sessionStorage\u003C\u002Fli>\n\u003Cli>IndexedDB\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>随后页面渲染直接读取这些缓存，而不是每次重新请求接口。\u003C\u002Fp>\n\u003Cp>如果换号时：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Token 更新了\u003C\u002Fli>\n\u003Cli>Cookie 清了\u003C\u002Fli>\n\u003Cli>但 storage 没更新\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>就可能出现：\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>抓包看到的是新用户，而页面显示的仍然是旧用户。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>这里有一个容易忽略的点：\u003C\u002Fp>\n\u003Cp>\u003Cstrong>HTTP 请求结束以后，页面如何把响应写进 localStorage、IndexedDB，属于浏览器 JavaScript 的运行时行为，并不属于抓包工具的职责。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"\u002Fdocs\u002Fcapture\u002F\">抓包列表\u003C\u002Fa> 擅长看 URL、Header、Body；\u003Ca href=\"\u002Fdocs\u002Fparam-transform\u002F\">参数转换\u003C\u002Fa> 还能把密文 Body 解成明文。但 \u003Cstrong>\u003Ccode>localStorage.getItem(&#39;auth_token&#39;)\u003C\u002Fcode> 不会出现在任何一列里。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>因此很多：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>接口正常\u003C\u002Fli>\n\u003Cli>页面异常\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>的问题，仅靠 Network 很难定位。\u003C\u002Fp>\n\u003Cp>真正缺失的信息是：\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>页面 JavaScript 此刻到底从 storage 里读到了什么。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2>桌面 DevTools 能看，但微信 WebView 不一样\u003C\u002Fh2>\n\u003Cp>如果同一个 URL 放到 Chrome 打开，当然可以直接去：\u003C\u002Fp>\n\u003Cp>Application → Storage\u003C\u002Fp>\n\u003Cp>查看 localStorage。\u003C\u002Fp>\n\u003Cp>但测试要求必须在：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>微信公众号菜单\u003C\u002Fli>\n\u003Cli>微信扫码\u003C\u002Fli>\n\u003Cli>微信分享链接\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>这些真实环境里复现。\u003C\u002Fp>\n\u003Cp>桌面 Chrome 和微信内置 WebView 往往不是同一套运行环境。\u003C\u002Fp>\n\u003Cp>桌面改掉 storage，并不能证明微信里的问题已经解决。\u003C\u002Fp>\n\u003Cp>当时现场就是：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>抓包确认 Header 已经是新 Token；\u003C\u002Fli>\n\u003Cli>微信页面仍显示旧头像。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>两边信息始终对不上。\u003C\u002Fp>\n\u003Ch2>vConsole 能看日志，但查 Storage 仍然不够方便\u003C\u002Fh2>\n\u003Cp>团队项目以前集成过 \u003Cstrong>vConsole\u003C\u002Fstrong>，也有同事使用 \u003Cstrong>eruda\u003C\u002Fstrong> 等页内调试工具。\u003C\u002Fp>\n\u003Cp>查看：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Console\u003C\u002Fli>\n\u003Cli>Network\u003C\u002Fli>\n\u003Cli>JS 报错\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>它们都非常方便。\u003C\u002Fp>\n\u003Cp>真正开始排查 storage 时，就明显进入了另一个阶段。\u003C\u002Fp>\n\u003Cp>例如：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>localStorage 通常只能查看，修改往往需要切到 Console 手写脚本；\u003C\u002Fli>\n\u003Cli>IndexedDB 虽然有插件支持查看，但 object store 层级较深时，在手机屏幕里浏览效率并不高；\u003C\u002Fli>\n\u003Cli>删除一条记录、修改 JSON，经常需要调用 \u003Ccode>indexedDB.open(...)\u003C\u002Fcode> 自己操作；\u003C\u002Fli>\n\u003Cli>手机屏幕有限，抓包窗口、需求文档、Storage 信息分散在不同设备之间，对照效率比较低；\u003C\u002Fli>\n\u003Cli>很多团队仍需要在 H5 中提前集成调试工具，临时联调时未必来得及发新版。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>另外，微信 WebView 的 Remote Debug（\u003Ccode>chrome:\u002F\u002Finspect\u003C\u002Fcode>、Safari Web Inspector）虽然可以使用，但受微信版本、系统版本、USB 连接等因素影响，实际联调时可用性并不稳定。\u003C\u002Fp>\n\u003Cp>下面是我们整理的一份对比（vConsole 类包含 vConsole、eruda 及常见 Storage 插件能力，不同版本可能略有差异）：\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>能力\u003C\u002Fth>\n\u003Cth>vConsole \u002F eruda\u003C\u002Fth>\n\u003Cth>DevPeek · Session\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>localStorage 查看\u003C\u002Ftd>\n\u003Ctd>一般支持\u003C\u002Ftd>\n\u003Ctd>桌面表格查看\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>localStorage 修改\u003C\u002Ftd>\n\u003Ctd>需 Console 脚本\u003C\u002Ftd>\n\u003Ctd>图形界面修改并下发真机\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>sessionStorage\u003C\u002Ftd>\n\u003Ctd>因插件而异\u003C\u002Ftd>\n\u003Ctd>独立 Tab 查看与修改\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>document.cookie\u003C\u002Ftd>\n\u003Ctd>部分支持\u003C\u002Ftd>\n\u003Ctd>可查看可修改（HttpOnly 不可见）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>IndexedDB 查看\u003C\u002Ftd>\n\u003Ctd>支持查看\u003C\u002Ftd>\n\u003Ctd>树形浏览\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>IndexedDB 修改\u003C\u002Ftd>\n\u003Ctd>多数需脚本\u003C\u002Ftd>\n\u003Ctd>JSON 编辑并下发\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>与抓包联动\u003C\u002Ftd>\n\u003Ctd>否\u003C\u002Ftd>\n\u003Ctd>Network 与 Session 同页\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>接入方式\u003C\u002Ftd>\n\u003Ctd>通常需集成进 H5\u003C\u002Ftd>\n\u003Ctd>代理注入，见 \u003Ca href=\"\u002Fdocs\u002Fdebug-replay\u002F\">移动端网页调试\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>vConsole 并不是不好。\u003C\u002Fp>\n\u003Cp>看日志、定位 JS 报错，它依然很好用。\u003C\u002Fp>\n\u003Cp>只是这次真正卡住的问题是：\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>需要在真机微信环境里，反复修改、删除、核对 storage 与 IndexedDB。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>这时候，小屏幕操作明显没有电脑端高效。\u003C\u002Fp>\n\u003Ch2>用 Session 面板定位：旧数据仍在 localStorage\u003C\u002Fh2>\n\u003Cp>手机 Wi‑Fi 代理指向 DevPeek，信任根证书，业务域名在 \u003Ca href=\"\u002Fdocs\u002Fproxy-ssl\u002F\">SSL 解密范围\u003C\u002Fa> 里。完整清单见 \u003Ca href=\"\u002Fdocs\u002Fdebug-replay\u002F\">移动端网页调试\u003C\u002Fa>；若预览区一直停在「等待设备连接」，可对照 \u003Ca href=\"\u002Fdocs\u002Ffaq\u002F\">常见问题\u003C\u002Fa> 排查注入与 WebSocket。\u003C\u002Fp>\n\u003Cp>连接成功后，\u003Cstrong>调试\u003C\u002Fstrong> Tab 会镜像微信里的 H5 页面；切到下方自研面板的 \u003Cstrong>Session\u003C\u002Fstrong> 分区：\u003C\u002Fp>\n\u003Col>\n\u003Cli>在 \u003Cstrong>抓包\u003C\u002Fstrong> Tab 确认该手机已有解密的 HTML 流量。\u003C\u002Fli>\n\u003Cli>在 \u003Cstrong>调试\u003C\u002Fstrong> Tab 选中对应 \u003Cstrong>客户端 Tab\u003C\u002Fstrong>；让测试从公众号菜单\u003Cstrong>重新进入\u003C\u002Fstrong>（旧标签页可能未注入脚本）。\u003C\u002Fli>\n\u003Cli>Session → \u003Cstrong>localStorage\u003C\u002Fstrong>，逐项确认：先看 Token，再看用户缓存。\u003C\u002Fli>\n\u003Cli>发现 \u003Ccode>auth_token\u003C\u002Fcode> 仍保存的是上一位测试账号的 JWT。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>抓包里的 Header 已经是新 Token，是因为请求阶段有时从内存变量读取了最新值；而页面头像读取的，却仍然是 localStorage——两边来源不同步。\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fdocs\u002Ffigures\u002Fdebug_local_storage.png\" alt=\"DevPeek Session：localStorage 列表与编辑\">\u003C\u002Fp>\n\u003Cp>\u003Cem>在桌面直接改 key 的值并下发真机，不必在 Console 里手写 \u003Ccode>localStorage.setItem\u003C\u002Fcode>。\u003C\u002Fem>\u003C\u002Fp>\n\u003Cp>修改 \u003Ccode>auth_token\u003C\u002Fcode> 为新账号对应值并确认下发后，再删除：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>user_profile_cache\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>刷新页面，头像立即恢复正常。\u003C\u002Fp>\n\u003Cp>这一刻，也基本确认了真正的问题所在。\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>DevPeek Session 面板展示的是当前页面 JavaScript 可访问的数据，而不是浏览器底层所有存储。因此 HttpOnly Cookie、微信 JSBridge、小程序原生 Storage 等内容仍然不在可编辑范围内；可见 Cookie 可在 Cookies 子 Tab 核对。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2>第二个问题：草稿订单始终删不掉\u003C\u002Fh2>\n\u003Cp>头像恢复后，测试顺手又提了另一个问题：\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>「草稿订单删除以后，重新打开列表，它又出现了。」\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>这种现象就不像 localStorage 了。\u003C\u002Fp>\n\u003Cp>切到 \u003Cstrong>IndexedDB\u003C\u002Fstrong>，展开：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>orders\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>很快发现：对应记录仍然保存在数据库里，状态字段也没有更新。\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fdocs\u002Ffigures\u002Fdebug_indexeddb.png\" alt=\"DevPeek Session：IndexedDB 库表与记录详情\">\u003C\u002Fp>\n\u003Cp>\u003Cem>树形展开 object store，选中记录后在详情区改 JSON 并下发——比在手机屏上手写 \u003Ccode>indexedDB\u003C\u002Fcode> API 省事。\u003C\u002Fem>\u003C\u002Fp>\n\u003Cp>确认字段后，直接修改 JSON 并下发；再次刷新页面，草稿订单终于真正消失。\u003C\u002Fp>\n\u003Cp>很多「删除失败」「列表残留」「离线数据异常」的问题，本质上都属于 IndexedDB 数据没有同步，而不仅仅是接口返回异常。\u003C\u002Fp>\n\u003Ch2>联调时，我通常这样交叉验证\u003C\u002Fh2>\n\u003Cp>定位 storage 问题以后，我一般还会继续确认两件事：\u003C\u002Fp>\n\u003Col>\n\u003Cli>回到调试面板的 \u003Cstrong>Network\u003C\u002Fstrong>，核对后续请求 Header 是否与 Session 里改过的值一致；\u003C\u002Fli>\n\u003Cli>如果需要验证不同参数，切回 \u003Cstrong>抓包\u003C\u002Fstrong> Tab，对同一行开「调试 API」改参重发，而不用再复制到 Postman。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>这样 \u003Cstrong>Session → Network → 页面\u003C\u002Fstrong> 三部分始终保持同一条调试链路；批量清 key 或复杂脚本时，同一上下文里的 \u003Cstrong>Console\u003C\u002Fstrong> 也能远程 eval，删之前先确认 key 名。\u003C\u002Fp>\n\u003Ch2>边界与注意事项\u003C\u002Fh2>\n\u003Cp>并不是所有缓存问题都能通过修改 Storage 解决。完整边界见 \u003Ca href=\"\u002Fdocs\u002Fdebug-replay\u002F\">移动端网页调试\u003C\u002Fa> 文档。\u003C\u002Fp>\n\u003Cp>例如：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>localStorage 已修改，但接口仍返回 401，说明 Token 可能来自 HttpOnly Cookie 或其他登录状态——对照 Network 与 Session；\u003C\u002Fli>\n\u003Cli>微信仍缓存旧 HTML，可以重新进入公众号菜单，或增加 Query 参数强制刷新页面；\u003C\u002Fli>\n\u003Cli>iframe 内页面属于另一 Origin，需要单独打开对应 URL 调试。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>下一篇\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>《H5 调试实战（二）：待整理》\u003C\u002Fstrong>——系列后续会继续收录真实联调案例（Console 远程脚本、Network 与 Mock 联动等），而不只介绍工具本身。\u003C\u002Fp>\n\u003Chr>\n\u003Cp>若你也在微信 H5 联调里反复改 localStorage 和 IndexedDB，欢迎 \u003Ca href=\"\u002F\">下载 DevPeek 试用\u003C\u002Fa>，或到 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FGYPengDev\u002Fdevpeek\u002Fdiscussions\">GitHub Discussions\u003C\u002Fa> 聊聊——上手步骤见 \u003Ca href=\"\u002Fdocs\u002Fdebug-replay\u002F\">移动端网页调试\u003C\u002Fa>，代理与证书见 \u003Ca href=\"\u002Fdocs\u002Fproxy-ssl\u002F\">代理与 SSL 证书\u003C\u002Fa>。\u003C\u002Fp>\n\u003Ch2>相关文档\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Ca href=\"\u002Fdocs\u002Fdebug-replay\u002F\">移动端网页调试\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"\u002Fdocs\u002Fcapture\u002F\">抓包界面与请求详情\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"\u002Fdocs\u002Fproxy-ssl\u002F\">代理与 SSL 证书\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"\u002Fdocs\u002Ffaq\u002F\">常见问题\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n",{"items":14},[15,16,24],{"slug":4,"title":5,"summary":6,"date":7,"featured":8,"seoDescription":9,"series":10,"seriesOrder":11},{"slug":17,"title":18,"summary":19,"date":20,"featured":8,"seoDescription":21,"series":22,"seriesOrder":23},"why-we-built-devpeek-h5-debug","我们为什么做 DevPeek（二）：App 里那页 H5，在电脑上也能对着查","登录接口用参数转换啃下来了，活动页 H5 却在 App WebView 里才崩。真机 remote debug 折腾一圈，DOM 和抓包还是两拨窗口——于是把镜像和自研调试面板收进 DevPeek。","2026-07-10","DevPeek 起源系列第二篇：App 内嵌 H5 只在真机出问题、remote debug 与抓包割裂的联调痛点，以及调试 Tab 如何把页面镜像到电脑并用自研面板查 DOM、Console 与 Network。","origin",2,{"slug":25,"title":26,"summary":27,"date":28,"featured":8,"seoDescription":29,"series":22,"seriesOrder":11},"why-we-built-devpeek","我们为什么做 DevPeek（一）：HTTPS 解密了，Body 还是天书","版本日前那晚，TLS 早就解开了，改请求里一个字段却还要翻脚本加解密。于是萌生做一个把业务加解密收进代理的工具——DevPeek 从这儿开始。","2026-07-09","DevPeek 起源系列第一篇：联调时请求体加解密的手工折腾，以及为什么先做一款把业务加解密收进代理的工具。",1783708287052]