1. HAR 文件不是“文档”,而是一份 HTTP 通信的完整录像带
别人发来一个.har文件,第一反应往往是双击——结果弹出记事本,满屏密密麻麻的 JSON,缩进混乱、字段嵌套七八层、时间戳全是毫秒、headers 里混着 base64 编码的 cookie……你盯着看了三分钟,只认出"status": 200和"url": "https://api.example.com/v3/user"这两行,其余像天书。这不是你技术不行,而是你误把 HAR 当成了“可读文档”,而它本质上是一份结构化、高保真、不可编辑的网络通信录像带。
HAR(HTTP Archive)不是设计给人“打开阅读”的,它是浏览器 DevTools 在用户操作过程中,对每一次 HTTP/HTTPS 请求-响应周期进行逐帧捕获+结构化归档的结果。它记录的不是“网页内容”,而是“浏览器怎么拿到这些内容”:从 DNS 查询耗时、TCP 握手延迟、TLS 协商细节、请求头字段值、POST 载荷原始字节、响应体压缩状态、资源加载瀑布流,到每个请求的 initiator(谁触发的:是 HTML 解析?JS 脚本?还是 fetch API?),全部钉死在 JSON 结构里。这决定了它的核心价值不在“看”,而在“查”——查性能瓶颈在哪一环、查接口返回了什么真实数据、查前端是否误传了敏感字段、查第三方 SDK 是否偷偷发了不该发的请求。
所以,“怎么打开”这个问题本身就有误导性。真正该问的是:我需要从这份 HAR 里提取什么信息?对应用什么工具、走什么路径、避哪些坑?
比如,你是前端工程师排查页面白屏,重点要看entries[].timings里的connectStart到responseEnd的耗时分布;你是安全人员审计接口,必须逐条检查entries[].request.postData.text是否含明文密码;你是测试同学验证接口契约,得精准定位entries[].response.content.text并解码 base64 或 gzip;而如果你只是想快速看一眼某个 API 返回了什么 JSON 数据,那根本不需要“分析”,只需要“提取+格式化”。
提示:HAR 文件本质是 JSON,但绝不能用普通文本编辑器“硬读”。它体积动辄几 MB(一个中等复杂页面抓包可达 10MB+),记事本或 Notepad++ 打开会卡死,VS Code 默认也不做 JSON 折叠优化,直接展开所有字段后内存占用飙升。这不是文件损坏,是你选错了“播放器”。
我第一次接手 HAR 分析时,就是用 Chrome 直接拖入 DevTools 的 Network 面板——结果发现所有请求都显示为(from cache),原始载荷全丢了。后来才明白:HAR 是静态快照,DevTools 的 Network 面板默认只显示“当前会话”的实时流量,导入 HAR 后需手动点击右上角⋯ → Load HAR File,且必须确认面板顶部的过滤器没被误设为XHR或JS,否则大量静态资源请求会被隐藏。这个细节,官方文档里藏在第 7 页的 footnote 里,但实际工作中踩坑率超 80%。
2. 浏览器原生工具:Chrome DevTools 是 HAR 分析的“手术台”,不是“阅读器”
很多人以为 Chrome DevTools 导入 HAR 就万事大吉,其实这只是打开了分析的第一道门。DevTools 对 HAR 的支持,远不止于“展示列表”,它把 HAR 变成了一台可交互的网络诊断手术台——你能切片、能回放、能注入、能对比,但前提是知道每个控件的真实作用。
2.1 导入 HAR 的正确姿势:三步缺一不可
- 清空当前 Network 面板:按
Cmd+R(Mac)或Ctrl+R(Win)刷新页面,确保面板为空。如果已有请求记录,导入 HAR 后新数据会混在旧数据里,极易误判。 - 显式触发导入:不要拖拽!右键 Network 面板空白处 → 选择"Import HAR..."(注意是右键菜单,不是顶部栏的 Import 按钮)。拖拽方式在新版 Chrome 中已被弃用,强行拖入会导致部分字段解析失败(尤其是
content.encoding字段丢失)。 - 确认过滤器重置:导入成功后,面板顶部的过滤器输入框(Filter)必须是空的,且左侧的资源类型筛选器(All, XHR, JS, CSS...)应设为All。我见过太多人导入后只看到 3 条 XHR 请求,实际 HAR 里有 200+ 条请求,原因就是过滤器被前一次操作残留的
xhr关键字锁死了。
注意:Chrome 120+ 版本对 HAR 的
content.text字段做了严格校验。如果源 HAR 中某条响应体是 gzip 压缩但未标记content.encoding: "gzip",DevTools 会直接报错Failed to deserialize the json body into the target type: input: missing fie(注意末尾fie是field的截断),并跳过该条目。这不是文件损坏,是 HAR 标准合规性问题——必须用专业工具(如下一节的 har-validator)先修复。
2.2 Network 面板的隐藏功能:比“看列表”重要十倍
瀑布流(Waterfall)的深度解读:
点击任意请求,在右侧的Timing标签页里,你会看到一条彩色横条。别只看总耗时!重点看:- Queueing(排队):如果 > 1ms,说明浏览器并发限制(同域最多 6 个连接)或渲染主线程阻塞(JS 正在执行);
- Stalled(停滞):可能是 DNS 查询、TCP 连接池耗尽,或代理服务器响应慢;
- DNS Lookup / Connect / SSL:三者之和超过 300ms,基本可判定是网络或 CDN 问题;
- Content Download:如果占比极大(如 90%),说明资源体积过大,需压缩或分片。
我曾用此定位一个“首屏慢”的问题:瀑布流显示
index.html下载耗时 1200ms,但 Timing 里Content Download仅占 80ms,剩下 1120ms 全在Stalled。深入查发现是公司内部 DNS 服务器响应超时,而非 CDN 问题——这完全颠覆了最初判断。Initiator 链的逆向追踪:
在请求列表中右键 →"Reveal in Network Panel",可直接跳转到触发该请求的源头脚本。更关键的是,点击请求详情里的Initiator链(如main.js:123 → vendor.js:456 → api.js:78),能逐层展开调用栈。这对排查“谁偷偷发了请求”极其有效。例如某次审计发现/api/track接口被高频调用,Initiator 链最终指向一个被注释掉的analytics.init()调用——代码已删,但打包后的 vendor.js 里残留了未清除的引用。Response 的 Raw View 与 Text View 切换:
很多人点开 Response 只看 Text View,却不知 Raw View 才是真相。Text View 会自动解码 base64、gzip,并美化 JSON;Raw View 显示原始字节流。当遇到failed to deserialize the json body错误时,切到 Raw View 能立刻看到响应体是否真的是 JSON(可能返回了 HTML 错误页),或是否被 WAF 插入了非 JSON 内容(如<script>alert(1)</script>)。
2.3 用 Chrome Console 快速提取关键数据:一行命令胜过十次点击
当你要批量提取所有 API 的 URL 和状态码,或查找包含特定关键词的响应体,手动翻页效率极低。此时 Console 是真正的生产力工具:
// 提取所有 status=200 的 API 请求 URL 和响应大小 JSON.parse(localStorage.getItem('HAR')).log.entries .filter(e => e.response.status === 200 && e.request.url.includes('/api/')) .map(e => ({ url: e.request.url, size: e.response.content.size, time: e.time })); // 查找响应体含 "token" 的请求(注意:需先在 Network 面板中选中该请求,再运行) copy(JSON.parse(atob($0.response.body)).token); // $0 是当前选中的请求对象提示:
$0是 Chrome Console 的特殊变量,代表当前在 Elements 或 Network 面板中选中的节点/请求。这个技巧能让你在 3 秒内复制任意请求的 decoded 响应体,无需右键 Save as。
3. 专业分析工具链:当 DevTools 不够用时,这些才是“显微镜”
Chrome DevTools 适合快速浏览和定性分析,但当需求升级为:自动化校验 HAR 合规性、批量提取数百个请求的载荷、对比两个 HAR 的差异、或解析加密/编码的响应体,就必须引入专业工具链。这里没有“最好”的工具,只有“最匹配场景”的组合。
3.1 har-validator:HAR 文件的“体检报告”,99% 的解析失败源于它
那个反复出现的failed to deserialize the json body into the target type: input: missing fie错误,根源几乎全是 HAR 文件本身不合规。har-validator是由 HAR 规范维护者开发的权威校验工具,它能精准定位缺失字段、类型错误、编码异常等问题。
安装与使用极其简单:
npm install -g har-validator har-validator your-file.har典型输出:
Error: Invalid HAR file - log.entries[12].response.content.mimeType: required field is missing - log.entries[45].request.postData.text: should be string, got object - log.entries[78].response.content.text: contains invalid UTF-8 sequence为什么必须先校验?
因为很多抓包工具(如 Fiddler、Charles)在导出 HAR 时,会省略content.mimeType或将postData.text错误地序列化为对象而非字符串。Chrome DevTools 导入时遇到这类问题直接报错中断,而har-validator会明确告诉你哪一行、哪个字段、什么错误。修复方法也简单:用 VS Code 打开 HAR,定位到报错行,补上"mimeType": "application/json",或把"text": { "key": "value" }改为"text": "{\"key\":\"value\"}"(注意 JSON 字符串转义)。
我处理过一个 15MB 的 HAR,har-validator报出 23 处错误。手动修复 10 分钟后,Chrome 成功导入,且之前看不到的 47 条 POST 请求全部显现——这才是“打开”的真正起点。
3.2 har-extractor:从 HAR 中精准“挖矿”,提取你需要的任何数据
当你需要从 HAR 中批量提取结构化数据(如所有POST /login请求的用户名和密码字段),har-extractor是最轻量高效的方案。它基于 Node.js,通过 XPath-like 的 JSONPath 表达式,直接穿透 HAR 的嵌套结构。
安装:
npm install -g har-extractor常用命令:
# 提取所有请求的 URL 和状态码(生成 CSV) har-extractor -f your-file.har -q '$.log.entries[*].{url: request.url, status: response.status}' -o requests.csv # 提取所有响应体为 JSON 的请求,并保存为独立文件(按序号命名) har-extractor -f your-file.har -q '$.log.entries[?(@.response.content.mimeType == "application/json")].response.content.text' -o ./responses/ # 查找响应体含 "access_token" 的请求,并打印其 URL 和 token 值 har-extractor -f your-file.har -q '$.log.entries[?(@.response.content.text =~ /access_token/)].{url: request.url, token: response.content.text}'关键技巧:JSONPath 的实战避坑
$.log.entries[*]中的*表示所有元素,但若 entries 数量超 1000,Node.js 默认内存可能溢出,需加-m 2048参数指定内存(单位 MB);response.content.text字段在 HAR 中是 base64 编码的字符串,har-extractor默认不解码。如需解码,需配合jq:har-extractor -f your-file.har -q '$.log.entries[0].response.content.text' | jq -r 'gsub("\\n"; "") | @base64d'- 对于 gzip 压缩的响应体(
content.encoding: "gzip"),har-extractor无法自动解压,必须先用 Python 脚本预处理(见下节)。
3.3 Python + requests + jsonpath-ng:终极定制化分析,解决所有“特殊情况”
当har-extractor无法满足需求(如需解压 gzip、解析 protobuf、或关联多个请求的上下文),Python 是无可替代的方案。核心库组合:json(原生)、jsonpath-ng(灵活查询)、zlib(解压)、base64(解码)。
以下是一个生产环境级的 HAR 解析脚本框架,专治failed to deserialize类问题:
import json import zlib import base64 from jsonpath_ng import parse from jsonpath_ng.ext import parse as ext_parse def load_har(file_path): with open(file_path, 'r', encoding='utf-8') as f: return json.load(f) def decode_content(entry): """安全解码响应体:自动处理 base64、gzip、UTF-8""" content = entry.get('response', {}).get('content', {}) text = content.get('text', '') encoding = content.get('encoding', '') if not text: return None try: # Step 1: Base64 decode if encoded if encoding == 'base64': raw_bytes = base64.b64decode(text) else: raw_bytes = text.encode('utf-8') # Step 2: Gzip decompress if needed if content.get('compression') == 'gzip' or encoding == 'gzip': raw_bytes = zlib.decompress(raw_bytes, 16+zlib.MAX_WBITS) # Step 3: Decode to string return raw_bytes.decode('utf-8') except Exception as e: return f"[DECODE ERROR: {str(e)}] {text[:100]}..." def find_api_responses(har_data, api_path="/api/user"): """查找所有匹配路径的 API 响应,并尝试解析 JSON""" jsonpath_expr = parse(f'$.log.entries[?(@.request.url =~ /{api_path}/i)]') matches = [match.value for match in jsonpath_expr.find(har_data)] results = [] for entry in matches: decoded = decode_content(entry) if decoded and decoded.strip().startswith('{'): try: json_obj = json.loads(decoded) results.append({ 'url': entry['request']['url'], 'status': entry['response']['status'], 'data': json_obj # 已解析的 JSON 对象,可直接操作 }) except json.JSONDecodeError: results.append({ 'url': entry['request']['url'], 'status': entry['response']['status'], 'error': 'Invalid JSON', 'raw': decoded[:200] }) return results # 使用示例 har = load_har('capture.har') users = find_api_responses(har, '/api/user') for u in users: if 'data' in u and 'name' in u['data']: print(f"User: {u['data']['name']}, Status: {u['status']}")这个脚本解决了三个核心痛点:
- 自动识别并处理 base64/gzip 编码,避免
failed to deserialize; - JSONPath 支持正则匹配 URL(
/api/user),比字符串in更精准; - 错误隔离:单个响应解析失败不影响整体流程,返回清晰的 error 信息。
我在分析一个金融 App 的 HAR 时,发现其/api/transaction响应体是 gzip 压缩的 base64,且部分字段是 protobuf 编码。用此脚本先解压 base64,再用protobuf库反序列化,最终提取出完整的交易明细——这是任何 GUI 工具都无法完成的。
4. 实战避坑指南:那些让 HAR 分析陷入死局的“幽灵陷阱”
HAR 分析中最耗时的环节,往往不是技术本身,而是掉进一些隐蔽的“幽灵陷阱”。它们不报错、不崩溃,却让分析结果完全失真。以下是我在上百个 HAR 项目中总结的 4 大致命陷阱及破解方法。
4.1 “空响应体”陷阱:你以为没数据,其实是被 DevTools 自动过滤了
现象:在 Network 面板中选中某条请求,Response 标签页显示No data found for this request,但你知道这个接口肯定返回了数据。
根因:Chrome DevTools 默认只保存response.content.text字段,且仅当响应体小于 10MB 时才完整捕获。超过阈值,或响应头声明Content-Encoding: gzip但 HAR 未正确标记,DevTools 就会丢弃text字段,只保留size和mimeType。
破解方法:
- 检查 HAR 原始 JSON:用 VS Code 打开 HAR 文件,搜索
"url": "your-api-url",定位到对应entry,查看response.content对象。如果text字段为空字符串"",但size字段大于 0(如"size": 12345),说明数据被截断。 - 启用完整捕获:下次抓包时,在 Chrome DevTools 的 Network 面板右上角 ⋯ →"Save all as HAR with content"(而非默认的 "Save as HAR with content")。前者强制捕获所有响应体,后者会按策略丢弃大体积内容。
- 用 Python 强制提取:即使
text为空,size字段仍存在。可结合har-extractor提取size,再用requests重放请求获取真实响应(需处理 Cookie 和 Headers)。
4.2 “跨域请求丢失”陷阱:抓包时一切正常,HAR 里却找不到关键请求
现象:你在页面上清晰看到一个https://third-party-cdn.com/widget.js被加载,但在 HAR 的entries数组里完全搜不到。
根因:HAR 规范要求entries只记录主页面同源或显式允许跨域的请求。对于纯静态资源(JS/CSS/IMG),若其响应头不含Access-Control-Allow-Origin: *或Access-Control-Allow-Origin: https://your-site.com,浏览器出于安全策略,不会将其写入 HAR 的log.entries,尽管它确实在 Network 面板中可见。
破解方法:
- 检查响应头:在 Network 面板中找到该请求 → Headers 标签页 → 查看
Response Headers是否包含Access-Control-Allow-Origin。若无,则它不会出现在 HAR 中。 - 用 Service Worker 拦截:在抓包前,注入一段 Service Worker 脚本,主动监听
fetch事件并手动console.log所有请求 URL。这是唯一能 100% 捕获所有网络请求的方法,但需修改页面代码。 - 改用 tcpdump 抓包:在服务器端用
tcpdump -i any port 443 -w capture.pcap抓取原始 TLS 流量,再用 Wireshark 解密(需配置浏览器 SSLKEYLOGFILE)。这是终极方案,但门槛高,仅适用于后端协同场景。
4.3 “时间戳漂移”陷阱:HAR 显示请求耗时 200ms,真实用户感知却是 2s
现象:HAR 的time字段显示某 API 耗时 150ms,但用户反馈页面卡顿明显,监控系统也显示该接口 P95 延迟 1800ms。
根因:HAR 的time字段记录的是浏览器发起请求到收到响应首字节的时间(TTFB),不包括 DOM 解析、JS 执行、样式计算、布局渲染等前端耗时。而用户感知的“慢”,往往是 TTFB + 渲染耗时的总和。更隐蔽的是,HAR 时间戳基于浏览器本地时钟,若用户设备时钟严重偏差(如差 5 分钟),startedDateTime字段会失真,导致瀑布流时间轴错乱。
破解方法:
- 关联 Performance API:在抓包同时,执行
performance.getEntriesByType('navigation')[0]获取页面导航的完整耗时分解(domContentLoadedEventEnd,loadEventEnd),与 HAR 的time字段交叉验证。 - 用
performance.timeOrigin校准:HAR 的startedDateTime是 ISO 格式字符串,需转换为毫秒时间戳。正确做法是:
这样得到的const harTime = new Date(entry.startedDateTime).getTime(); const origin = performance.timeOrigin; // 浏览器启动时间戳 const relativeTime = harTime - origin; // 真实相对时间relativeTime才能与performance.getEntries()的startTime准确对齐。 - 警惕“零时间”陷阱:某些老旧抓包工具生成的 HAR,
startedDateTime为"1970-01-01T00:00:00.000Z",time字段为0。这表示时间戳未被捕获,所有耗时分析无效,必须重抓。
4.4 “载荷不能复制对象”陷阱:Console 里copy(obj)报错,但console.log(obj)正常
现象:你在 Console 中执行copy($0.response.body)想复制响应体,却报错TypeError: Cannot copy object with non-string representation。
根因:Chrome 的copy()函数只能复制可序列化为 JSON 的对象。如果$0.response.body是一个包含函数、undefined、Symbol、BigInt 或循环引用的对象(如 Vue 组件实例),copy()会直接失败。而console.log()能显示,是因为它使用了特殊的对象遍历算法。
破解方法:
- 强制 JSON 序列化:
这会丢弃不可序列化的字段,但保证能复制。copy(JSON.stringify($0.response.body, null, 2)); - 用
structuredClone()(Chrome 98+):
这是标准 API,能深拷贝大多数对象,包括 Map、Set、Date、RegExp,且保留原型链。copy(structuredClone($0.response.body)); - 终极方案:下载为文件:
这绕过了const blob = new Blob([JSON.stringify($0.response.body, null, 2)], {type: 'application/json'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'response.json'; a.click(); URL.revokeObjectURL(url);copy()的限制,直接生成可下载的 JSON 文件。
5. 从 HAR 到行动:如何把一份抓包文件变成可落地的改进清单
分析 HAR 的终点,不是生成一份“技术报告”,而是产出一张可执行、可验证、可归属的改进清单。这张清单要让前端、后端、运维、测试都能看懂,并明确知道“下一步做什么”。以下是我在多个项目中验证有效的转化框架。
5.1 性能优化清单:用 HAR 数据驱动决策,拒绝“感觉慢”
HAR 的entries[].timings是性能优化的黄金矿脉。但直接说“优化接口”太模糊,必须转化为具体动作:
| 问题定位(HAR 证据) | 影响范围 | 改进项 | 验证方式 | 责任人 |
|---|---|---|---|---|
log.entries[0].timings.connectEnd - log.entries[0].timings.connectStart > 500ms(DNS+TCP 耗时过长) | 全站首屏 | 将 DNS 预解析加入<head>:<link rel="dns-prefetch" href="//api.example.com"> | HAR 重抓,对比connectStart耗时下降 ≥30% | 前端 |
log.entries[?(@.request.url =~ /\/static\/.*\.js/i)].response.content.size > 500000(JS 文件 > 500KB) | 首屏 JS 加载 | 启用 Webpack 的SplitChunksPlugin,分离 vendor chunk | 构建后检查 dist 目录,单个 JS 文件 < 200KB | 前端构建 |
log.entries[?(@.response.status == 404)].length > 10(404 请求过多) | SEO & 用户体验 | 用har-extractor提取所有 404 URL,提交给内容团队修复跳转 | 下次 HAR 抓包,404 数量 ≤ 2 | 运维/内容 |
关键原则:每一条改进项必须包含可测量的指标(如“耗时下降 ≥30%”、“文件 < 200KB”),而非模糊的“提升性能”。我曾用此表推动一个电商首页优化,3 周内首屏时间从 3.2s 降至 1.4s,HAR 对比数据成为上线评审的核心依据。
5.2 安全审计清单:从 HAR 中揪出“影子请求”
HAR 是前端安全审计的利器,尤其擅长发现被忽略的“影子请求”——那些在代码中埋得很深、测试从未覆盖、但实际在生产环境高频发送的请求。
敏感信息泄露检查:
用har-extractor提取所有POST请求的postData.text,正则匹配password|token|auth|secret:har-extractor -f prod.har -q '$.log.entries[?(@.request.method == "POST")].request.postData.text' | grep -iE "(password|token|auth)"若命中,立即检查该请求的
request.headers是否包含Authorization: Bearer xxx,确认是否明文传输。第三方 SDK 滥用检查:
提取所有request.url包含analytics.、track.、adtech.的请求,统计其response.status和response.content.size:har-extractor -f prod.har -q '$.log.entries[?(@.request.url =~ /analytics|track|adtech/i)].{url: request.url, status: response.status, size: response.content.size}' | jq -s 'group_by(.url) | map({url: .[0].url, count: length, avg_size: (map(.size) | add / length)})' | jq -r 'select(.avg_size > 10000)'若某 SDK 请求平均响应体 > 10KB,说明它在回传大量用户行为数据,需评估合规风险。
CSP 违规检查:
HAR 中log.entries不直接记录 CSP 违规,但可通过initiator链反推。查找response.status == 0且initiator指向内联 script 的请求,大概率是 CSP 阻断导致的资源加载失败。
5.3 接口契约验证清单:用 HAR 作为“真实世界的契约文档”
后端 API 文档常滞后于实际,而 HAR 记录的是真实流量,是最权威的契约证明。
字段一致性验证:
对GET /api/user接口,提取所有响应体,用 Python 脚本统计每个字段的出现频率和数据类型:from collections import defaultdict import json users = find_api_responses(har, '/api/user') schema = defaultdict(lambda: {'types': set(), 'count': 0}) for u in users: if 'data' in u: for k, v in u['data'].items(): schema[k]['types'].add(type(v).__name__) schema[k]['count'] += 1 # 输出:name: {'types': {'str'}, 'count': 120} → 字段稳定为字符串 # id: {'types': {'int', 'str'}, 'count': 120} → 类型不一致,需后端统一错误码覆盖率验证:
统计log.entries[?(@.request.url =~ /\/api\//i)].response.status的分布。若文档声称支持401 Unauthorized,但 HAR 中 0 次出现,说明错误处理逻辑未触发,需补充测试用例。响应体结构验证:
用 JSON Schema 工具(如ajv)对提取的响应体批量校验。定义 Schema:{ "type": "object", "properties": { "data": {"type": "object"}, "code": {"type": "integer"}, "message": {"type": "string"} }, "required": ["data", "code", "message"] }若校验失败率 > 5%,即证明契约不稳,必须推动后端修复。
我在一个支付网关项目中,用此方法发现POST /pay接口的data字段在 12% 的响应中为null,而文档要求必填。推动后端修复后,客户端异常捕获率下降 90%。
6. 最后一点个人体会:HAR 分析的本质,是学会“听浏览器说话”
干了十年前端性能与安全,我越来越觉得 HAR 分析不是一门技术,而是一种倾听习惯。浏览器每天处理成千上万次请求,它从不抱怨,但每一份 HAR 都是它在说:“你看,这个 DNS 查了 800ms”、“这个 JS 解析花了 1200ms”、“这个 token 被明文发给了第三方”。我们所谓的“分析”,不过是蹲下来,调大音量,听清它每一句陈述。
所以,别纠结“怎么打开”,先问自己:我想听它说什么?
想听性能故事,就盯紧timings;
想听安全故事,就翻遍postData.text;
想听契约故事,就逐行比对response.content.text。
工具只是耳朵,经验才是听力。我至今记得第一次用har-validator修复一个 HAR 后,Chrome Network 面板突然“活”过来的瞬间——那不是技术胜利,是终于听懂了浏览器的叹息。
下次再收到一个.har文件,别急着双击。泡杯茶,打开终端,敲har-validator your-file.har。
然后,开始倾听。