
做H5/WAP开发的人应该都有过这种体验桌面上把页面调得妥妥当当一扔到手机里就“原形毕露”报错信息看不到、接口状态不知道、元素位置对不上。PC端一个F12能解决的事到移动端要同时面对浏览器兼容、真机差异、WebView内核差异连个console日志都只能靠alert去猜。vConsole、Eruda、Spy-Debugger这三款工具分别覆盖了移动端调试最刚需的三件事页面内看日志、页面内看网络、用PC远程操作真机。这篇把我实际用这三款工具的经验、选型思路和踩坑记录整理出来适合刚接触移动端调试的前端开发也适合做混合App或H5活动页的团队参考。1. H5/WAP端调试为什么这么折腾移动端调试难难在环境不透明。你写的代码跑在手机浏览器里或者在某App的WebView里这层壳把很多信息挡住了。PC端开发者工具能看到完整的DOM、样式、控制台、网络瀑布移动端默认什么都没有。报错可能被发布版吞掉错误对象可能被打包工具压缩成一行乱码。就算打开手机浏览器的“开发者模式”又能做的也相当有限而且不同系统、不同内核的调试入口还不一样想统一一套流程并不容易。1.1 移动端和PC端调试环境的差距PC端调试是所见即所得。按F12打开开发者工具Elements面板直接改样式Console面板看任何日志Network能查请求头、响应体、耗时鼠标悬停就能看盒模型。移动端如果要复现同样的事情至少面临三个落差。第一个落差是没有稳定的调试入口。不同浏览器、不同WebView暴露的能力不一致同一个H5页面在A浏览器里能打开调试在B浏览器里可能完全找不到入口。第二个落差是网络请求只能靠WeakNetwork工具或者服务端日志间接观察拿不到完整的请求参数和响应体前后端一扯皮就得翻日志。第三个落差是真机上的手势、软键盘、屏幕尺寸、安全区域这些因素PC模拟器永远模拟不完整。比如某个输入框在iPhone上获取焦点调起软键盘后整个页面被顶上去底部按钮被安全区遮住这种问题在PC上无论如何都复现不了。这三个落差直接导致移动端调试的典型路径先alert弹值再console.log然后在手机屏幕上截图发给后端。遇到接口参数对不上、页面渲染异常还得开远程调试通道有时候一根调试线不行、驱动不对半天就没了。所以移动端调试工具要解决的本质上是把PC端开发的“确定性”带回移动端让你在手机上也能快速看到可读的报错、请求和页面结构。1.2 从“alert弹窗”到“页面内调试台”的进化早先的一些H5项目里移动端调试几乎就是alert大法。alert能显示字符串于是所有怀疑的变量都塞进一个alert里然后一句一句地删。这种方式不是不能用而是效率和表达能力太差。对象打出来是[object Object]数字和字符串混在一起容易看错网络请求完全看不到也没法动态执行代码。那时候遇到“页面白屏”只能在代码里到处加alert一遍遍刷新运气好找到了运气不好改一次刷一次一下午就没了。后来出现了一批注入页面的调试工具思路是在页面里插入一段脚本由这段脚本动态渲染出一个控制台面板。vConsole和Eruda就属于这一类。它们的优势非常明显不依赖外部调试通道只要页面能加载脚本就能看日志兼容Android和iOS的主流浏览器与WebView同时可以通过发布开关控制是否加载测试环境打开、正式环境关掉。Spy-Debugger则走了另一条路它把手机和PC连接起来让开发者用PC的键盘鼠标操作手机页面相当于给真机开了一个远程开发的通道。这两类工具并不冲突。我这里的实际用法是日常联调用Eruda看页面日志和DOM状态定位请求瓶颈用Spy-Debugger抓完整请求链路。先搞清楚它们各自能做什么、不能做什么后面接入才不会手忙脚乱。2. 选型之前先搞懂三款工具的工作原理三款工具都是解决移动端调试的方案但实现思路和适用场景差别很大。如果只是知道怎么引入不理解它们的数据流和边界遇到问题就容易乱。下面分开拆解。2.1 vConsole一个注入页面的轻量级控制台vConsole的思路很直接在页面加载一段JS这段JS会在页面角落生成一个悬浮按钮点击后展开一个类似PC控制台的面板。面板分成几个页签包括Log、System、Network、Element等可以看console日志、打印对象、查看网络请求的URL、状态码和耗时还能看cookie和localStorage。实现上它本质是把全局console方法包装了一层同时通过钩子捕获XMLHttpRequest和fetch的请求把请求信息透传到面板上。使用vConsole的好处是轻整包非常小接入成本极低。不过它默认只显示自身存活期间产生的日志如果你希望看到页面初始化早期的日志必须确保脚本在业务代码之前执行最好放在head里。另外vConsole的Element面板并不是完整DOM树浏览更多是查看元素基本信息不像PC开发者工具那样可以精确选中元素改样式。所以它更适合快速定位JS报错、确认接口返回不太适合做精细的样式调整。我最早在一个移动端活动页里用vConsole主要就是看接口返回。活动页的倒计时逻辑和领券结果都要依赖后端响应当时后端说“接口没问题是前端渲染错了”我用vConsole的Network页签把请求参数和响应一截发现确实有一个字段在服务端返回了空字符串。问题定位又快又清楚比alert强太多。2.2 Eruda把开发者工具搬进手机屏幕Eruda在定位上更像一个“移动端开发者工具套件”。它的默认面板包括Console、Elements、Network、Resources、Sources、Sensors等功能覆盖比vConsole更全面。Elements面板可以像PC一样查看DOM树、修改属性Sources可以查看页面加载的脚本并打断点部分场景下可用Sensors可以模拟地理位置、重力感应等。它还提供插件机制按需扩展功能比如加载Vue插件时可以直接检查组件实例状态。Eruda的使用方式也基本是注入一段脚本但默认面板是固定在页面底部的一块区域可以通过配置调整主题、大小和是否自动打开。相比vConsoleEruda体积更大、能力更强也更接近桌面浏览器的开发体验。代价是如果业务代码先加载了同样会漏掉部分早期日志而且它的大型面板在某些低端机或小屏设备上会占用不少可视区域需要注意及时折叠。选型的时候如果只是想看日志和请求vConsole已经足够如果需要频繁查看DOM、在线改样式、处理跨端页面Eruda更合适。我后来在混合App项目里就把Eruda打进了测试包测试人员报问题时能直接截图面板上的报错信息比复制一串乱码有用得多。2.3 Spy-Debugger用PC接管手机页面的远程调试Spy-Debugger跟上面两个不一样它跑在PC上通过npm安装后启动一个本地服务这个服务会开启一个代理端口。手机和PC连在同一个局域网手机网络代理指向PC的IP和端口之后手机上的所有HTTP和HTTPS请求都会经过Spy-Debugger转发。开发者可以在PC的浏览器里打开一个控制页面看到请求列表、请求详情、响应内容甚至能用“远程inspect”能力操作手机上的页面在PC端输入命令在手机页面里执行JavaScript、查看元素、截屏。它本质上承担了“代理转发远程控制”两层职责。这种方案最大的价值是它不需要在目标页面里注入任何脚本所以对线上页面、第三方页面、甚至App内页面都能做接入。哪怕页面是打包后的压缩代码也可以抓包。需要注意的是调试过程中手机流量全部走代理如果代理断开页面会立刻无法加载。这个坑很多人踩过我也是后来才习惯先检查代理状态。另外它只能看到由代理客户端发出的请求。如果某个App内嵌页面使用了不走系统代理的网络库单独设置系统代理是抓不到的后面我会专门说这种场景的替代方案。2.4 三款工具对比与选型建议工具部署位置主要能力体积/性能适用场景vConsole页面内注入日志、网络请求、系统信息轻量自家H5快速看日志、确认接口Eruda页面内注入DOM、网络、资源、传感器等较重需要类桌面调试的复杂页面Spy-DebuggerPC端代理抓包、远程操作、HTTPS解密无需注入线上/第三方页面、全流程排查选型建议上自研H5优先考虑vConsole或ErudavConsole看重简洁Eruda看重功能调试过程中需要看后端返回和请求头优先Spy-Debugger混合App内页面调试推荐把Eruda内嵌进测试包同时配合Spy-Debugger排查真机网络差异。三款工具不是互斥的我通常在测试环境同时开着Eruda和Spy-DebuggerEruda负责前端表现Spy-Debugger负责完整请求链路两边对照着看很多“魔幻bug”都能快速收敛。3. 从接入到日常调试的完整实操这一部分直接给步骤按我实际用的流程写。下面分别说三款工具怎么接、怎么配、日常怎么用。3.1 vConsole接入与上线开关控制接入vConsole最简单的方式是直接引入脚本并初始化。可以放在页面head里保证在业务代码之前执行。示例!DOCTYPE html html head script srchttps://example.com/vconsole.min.js/script script var isDev location.hostname.indexOf(test) -1; if (isDev) { window.vConsole new VConsole(); } /script /head注意脚本加载地址只是一个示例实际部署时应该把vConsole打包进项目或者放到自己的CDN避免调试器本身成为性能瓶颈。上线开关非常重要。我见过不止一次调试工具被直接打包上线结果用户手机上出现了一个悬浮按钮既难看又有安全隐患。正确做法是构建时通过环境变量注入开关测试包默认打开生产包不引入脚本。如果只能用域名判断记得区分二级域名和正式域名不要用简单的includes匹配比如“test.example.com”可能误伤正式域名。初始化的时机同样有讲究。vConsole必须在业务代码前初始化才能捕获业务脚本里的早期console和网络请求。如果业务代码已经执行完再new VConsole之前的日志就彻底看不到了。有些团队为了省事把初始化函数放在全局异常处理里做兜底这只能捕获运行期错误初始化之前的日志还是丢。日常使用里我最常用的是Network页签。接口请求顺序、返回状态、耗时都列在里面接口出错时能一眼看出是不是后端问题。Log页签可以按级别过滤error、warn、info定位报错很方便。它还支持在面板底部输入表达式直接执行相当于一个实时控制台改页面状态、调函数都很方便。3.2 Eruda接入与插件按需加载Eruda的接入类似直接在页面加载时初始化。默认配置下它会在页面底部展开一个工具条点击后弹出完整面板。基础用法script srchttps://example.com/eruda.min.js/script script if (isDev) { window.eruda.init({ container: document.body, tool: [console, elements, network, resources], useNativeConsole: true }); } /script这里的tool数组是控制台、DOM、网络、资源几个基础面板不需要的可以去掉避免面板过重。如果项目用了某个前端框架还可以按需引入对应的插件包比如Vue插件这样在面板里能直接看到组件实例和状态。插件通常也是在init之前加载然后通过配置注册进去。不要一次性把所有插件都装上低端机实在扛不住先上最常用的。实际使用中Eruda面板打开后可以在Elements面板点击任意DOM节点右侧会显示当前节点属性直接修改style属性就能即时生效。这个能力在做移动端样式微调时非常实用不用改代码、刷新、再截图。另外它的Network面板会聚合请求数量和总耗时方便判断页面里哪个接口拖了后腿。有一次我做了一个长列表页首屏接口和数据渲染都很顺利但滑动时明显卡顿用Eruda一查才发现某个像素图被重复加载了几十次。这类性能问题光看页面表现很难定位有工具就能节省大量时间。一个小经验Eruda默认面板高度可能太高可以把panelAutoHeight设为false并指定maxHeightRatio让它只占屏幕一半左右既能看到页面又能操作面板。多页面切换时如果每个页面都初始化一遍面板会闪一下建议在入口文件统一初始化并且设置session配置持久化避免每次进来都要手动打开。3.3 Spy-Debugger安装、代理配置与证书信任Spy-Debugger是基于Node环境的命令行工具使用前需要先确认电脑已安装Node。安装命令npm install -g spy-debugger启动时可以直接指定端口和业务地址spy-debugger -p 9888 -i 手机IP启动后终端会打印出PC的局域网IP和代理端口把手机WiFi设置里的HTTP代理指到这个IP和端口。完成这一步手机上访问任意HTTP页面请求都会转发到PC端控制页面里能看到对应的请求列表。HTTPS页面如果要看到明文必须在手机上安装并信任证书。Spy-Debugger会生成自己的根证书控制页面里通常有证书下载入口。iOS和Android的安装信任路径不太一样iOS系统默认在“设置-描述文件”里安装描述文件后还必须到“证书信任设置”里打开完全信任开关否则HTTPS请求会失败。Android系统需要根据版本不同在“安全-加密与凭据-安装证书”或“CA证书”入口安装部分系统还要在应用的网络配置里允许用户证书否则App内WebView仍不信任。证书安装成功后在PC控制页面里就能看到HTTPS请求的完整明文包括POST参数、Cookie、响应体。这个能力做接口联调非常方便不用再去后端日志里翻参数。不过要提醒一点证书只在调试期间使用调试完一定要恢复手机的代理设置和移除证书不然手机后续访问HTTPS会有安全隐患。这里我踩过最深的坑是“安卓7以上版本”的差异。某次在真机App内调试HTTPS接口代理和证书都装好了浏览器页面可以解出明文但App里的WebView请求还是失败。后来才发现是App网络配置默认不信任用户CA证书需要单独在AndroidManifest或网络安全配置里加上信任。调试到这种问题时不要急着怀疑工具先确认你的目标环境允不允许抓包。3.4 日常调试的几个高频操作实际调试中除了看日志和抓包还有几个动作我几乎每次都会用到。第一个是修改请求参数重新发送。在Spy-Debugger控制页面里可以对某个请求做编辑和重放方便验证后端对不同参数的响应。第二个是Network面板里的耗时时间线。如果某个接口首次加载特别慢可以通过它区分是DNS、连接、还是响应体过大。第三个是在页面内模拟弱网Eruda的Sensors面板和Spy-Debugger提供的命令行都可以设置网络限速模拟2G/3G环境不需要单独装弱网工具。还有一个容易被忽略的操作把手机屏幕投到PC上。Spy-Debugger的远程inspect可以截取手机屏幕甚至远程点击这比让同事拿着手机口述问题要高效得多。遇到页面白屏可以在PC端控制页面直接执行location.reload()看报错输出基本就知道是脚本崩了还是接口返回异常。我自己的日常节奏是打开Eruda先过滤一下error日志再切到Network看耗时如果发现某个请求异常立刻去Spy-Debugger里看完整请求头和响应体。两个工具配合起来前端报错和后端返回基本都能在几分钟内确认。4. 常见问题与排查技巧实录这部分整理的是我在实际项目中反复遇到的问题有些有明确的解决方案有些需要结合环境判断。写出来给大家做个参考。4.1 页面工具不显示、按钮点不透用vConsole或Eruda时最常遇到的是“页面里看不到悬浮按钮”。检查顺序是脚本是否真的加载成功、初始化是否执行、是否被生产环境开关过滤掉。可以在PC模拟器的Console里手动执行window.vConsole或window.eruda如果返回undefined说明脚本没进来。另一个常见问题是工具按钮被页面上的元素遮挡这时候打开工具的“拖动模式”或者调整z-index配置把面板层级抬高。还有一次遇到Eruda在低版本WebView里打不开是因为项目中用了高版本ES语法低端机解析不了。解决方法是把调试脚本单独用ES5编译产物或者用动态script加载并保留降级。这类问题往往跟工具本身无关而是环境兼容问题排查时先把工具脚本独立出来测能少走很多弯路。遇到过“按钮出来了但面板打开是白屏”的情况多半是面板容器样式被全局CSS重置了。检查一下项目里是否写了类似*{margin:0;padding:0}或者对z-index做过统一覆盖必要时可以在初始化配置里指定独立容器并加一个高优先级样式。调试工具得保证自己不被业务样式污染。4.2 请求抓不到、证书不生效Spy-Debugger抓不到请求先确认手机代理是否设置成功在手机上访问一个HTTP页面看PC控制页面有没有请求记录。如果没有检查手机和PC是否在同一网段、代理端口是否被防火墙拦截。常见原因是手机连接了不同WiFi或者PC上有多个网卡导致IP绑定错误尝试用-i参数指定手机实际网段对应的IP。HTTPS请求抓不到或报证书错误大部分是证书信任步骤不完整。iOS尤其要注意“证书完全信任”开关只安装描述文件还不够。如果是Android高版本系统许多App默认不信任用户CA证书需要在网络配置或App内开启“允许用户证书”。如果正在调试的是某个App内嵌页面代理要设置到系统级而不是仅浏览器否则应用内部的HTTP库不走代理。还有一个容易忽略的点Spy-Debugger的代理只对设置了代理的客户端生效如果App强制使用固定IP或者不读系统代理就需要用透明代理方式绕开。这种场景建议换用独立的WiFi热点方案把PC做成热点手机连上热点后流量全部经过PC抓包成功率会高很多。4.3 真机远程调试连接不稳定怎么办远程调试时最烦的就是连接断开。载体是局域网无线信号不好手机网络代理就会频繁失效。我通常的解决办法是把PC和手机放在同一个房间尽量靠近路由器如果PC本身用的是无线网卡建议改用有线网络减少链路抖动。Spy-Debugger还可以设置超时时间和重连参数出现断连时不必重启整个服务只要手机代理重新指一下就行。还有一个策略调试线上问题时先抓包、后注入。如果线上页面不能随意加调试脚本先用Spy-Debugger抓完整请求和响应定位接口层问题需要看页面内部状态时再通过远程inspect临时执行脚本获取。这样可以把连接时间压缩到最短减少断连风险。碰到页面反复崩溃的情况记得把Spy-Debugger的日志级别调低避免大量日志跨网络传输反而把页面拖死。最后分享一个我个人的习惯不管用哪种调试工具都一定把“生产环境不加载、测试环境默认开”这条规则固化成构建模板并在每次发布前检查一遍产物里有没有调试面板的关键词。调试工具是给开发用的流到用户手里就是事故。日常项目里vConsole、Eruda和Spy-Debugger各有各的活儿我现在的组合是Eruda做日常页面检查Spy-Debugger做请求链路兜底基本上覆盖了移动端开发里绝大多数调试场景。如果你刚接触移动端调试建议从vConsole开始成本最低跑通流程后再上Eruda和Spy-Debugger会顺很多。