HAR 文件——你不知道但需要的 HTTP 调试日志
HAR 文件记录了浏览器发出的每一个 HTTP 请求——请求头、时间信息、响应体、认证令牌。以下内容是其中一个 HAR 文件的内部结构,如何捕获它,以及当出现问题时如何使用它。
您的API调用在生产环境中失败了。在curl和本地环境中都能正常工作。技术支持打开一个工单,并要求您“分享一个HAR文件”。您自信地点头,并在另一个标签页中搜索“HAR文件是什么”。
这就是那个标签页。这里解释了HAR文件是什么,其中包含什么内容,以及如何使用它来真正找到问题所在。
HAR文件是什么
HAR代表HTTP存档。它是一个JSON文件,记录了浏览器在会话期间发出的每一个HTTP请求——URL、方法、状态码、请求和响应头、请求体、响应体、Cookie以及时间分解。所有内容,针对页面上的每一个请求。
该格式由Web性能工作组(版本1.2规范)标准化,并被Chrome、Firefox、Safari和Edge支持。可以将其视为浏览器网络标签页的结构化导出——您可以在不提供SSH访问权限的情况下将其交给正在调试问题的人。
当故障是间歇性的,仅在特定浏览器中重现,或需要向供应商证明其API确实返回了500错误而非人为操作失误时,HAR文件特别有用。
如何捕获一个HAR文件
Chrome和Edge
- 打开开发者工具(F12 或 Cmd+Option+I 在Mac上)
- 转到 网络 标签
- 启用 保留日志 如果故障发生在重定向或页面刷新之后
- 重现问题
- 在请求列表中的任意位置右键点击 → 保存全部为 HAR 并包含内容
Firefox
- 打开开发者工具 → 网络 标签
- 重现该请求
- 点击齿轮图标 → 保存所有为HAR
Safari
- 启用开发菜单: Safari → 设置 → 高级 → 显示开发菜单
- 开发 → 显示网页检查器 → 网络
- 重现问题
- 点击 导出 按钮(网络工具栏中的箭头图标)
有一点值得注意的是 保留日志:如果没有启用,HAR文件只会捕获当前页面加载之后的请求。如果故障发生在身份验证过程中或重定向链中,您将捕获一个空或误导性的文件,从而花费20分钟困惑。在重现问题之前,请务必启用它。
HAR文件中包含什么内容
每个HAR文件都具有相同的顶层结构:
{
"log": {
"version": "1.2",
"creator": { "name": "Chrome", "version": "124.0.6367.82" },
"entries": [ ... ]
}
}
这 entries 数组是所有有用数据所在的地方。每个条目代表一个完整的请求/响应对。一个典型的页面加载会产生50到200个条目;一个复杂的单页应用加载仪表板可能会超过这个数量。
注释条目:关键字段说明
以下是单个HAR条目中关键字段的分解:
| 场地 | 位置 | 它告诉您什么 |
|---|---|---|
startedDateTime | 条目 | 请求发出的时间,以ISO 8601 UTC格式表示。将其与服务器日志关联,以找到确切的日志行。 |
time | 条目 | 从请求开始到响应结束的总耗时(毫秒)。这是在查找慢请求时排序的数值。 |
serverIPAddress | 条目 | 实际处理此请求的IP地址。在负载均衡器后至关重要——它告诉您访问的是哪个实例。 |
request.method | 请求 | GET、POST、PUT、DELETE等方法 |
request.url | 请求 | 完整的URL,包括查询字符串。注意此处可能意外出现双重编码的参数。 |
request.headers | 请求 | 所有请求头。 包含授权头——认证令牌就在其中。 这是隐私问题。 |
request.postData.text | 请求 | 原始请求体。对于JSON API,这就是您的请求负载。如果API拒绝输入,请首先检查此内容。 |
response.status | 回复 | HTTP状态码。0通常表示请求在完成前就被阻止。 |
response.headers | 回复 | 响应头,包括 Content-Type, Cache-Control, Set-Cookie。对CORS调试很有用。 |
response.content.text | 回复 | 响应体。对于JSON API,这是原始JSON。对于二进制响应,可能是base64编码的。 |
timings.blocked | 时间指标 | 等待TCP连接槽的时间。高值表明连接池耗尽。 |
timings.dns | 时间指标 | DNS解析时间。超过50毫秒值得关注;超过200毫秒是问题。 |
timings.connect | 时间指标 | TCP连接时间。高值表示网络延迟或TLS开销,而不是服务器响应慢。 |
timings.wait | 时间指标 | 从请求发送到第一个字节接收的时间(TTFB)。 这是慢API出现的地方。 高TTFB表示您的服务器响应缓慢。 |
timings.receive | 时间指标 | 下载响应体所需的时间。只有在响应负载较大时才会很高。 |
您应该实际寻找的内容
当您打开一个HAR文件时,您通常在寻找以下三种情况之一:
失败的请求
按 response.status筛选或过滤。在Chrome开发者工具中,您可以使用 status-code:4xx 或 status-code:5xx进行实时过滤。一旦找到失败的请求,查看完整的 response.content.text ——服务器返回的错误消息通常比状态码更有用。
缓慢的请求
按 timings.wait (TTFB) 降序排列。高 wait = 服务器响应慢。高 timings.connect 与正常 wait = 瓶颈是网络或TLS握手,而不是您的应用程序。这些指向完全不同的解决方案,因此正确识别这一点可以节省大量时间,避免错误地归因于错误的层级。
缺失的请求
有时错误是缺少请求——一个未触发的Webhook,一个被CORS阻止的预检OPTIONS请求,一个被广告拦截器吃掉的分析调用。将HAR中应存在的内容与实际存在的内容进行比较。请求的缺失是数据。
您应该了解的隐私问题
HAR文件包含所有内容,包括:
Authorization头信息——Bearer令牌、Basic认证凭据Cookie头信息——会话令牌、JWT、Cookie中的任何内容- 请求和响应体——其中可能包含密码、个人身份信息(PII)或API密钥
Chrome在导出时不会删除任何内容。在将HAR文件分享给支持团队、供应商或公司外部同事之前,请删除或屏蔽敏感字段。
最快检查和清理HAR文件以供分享的方法是使用 HAR文件格式化工具 ——将文件粘贴进去,浏览条目,并在发送前进行屏蔽。或者,如果您熟悉 jq:
# Strip Authorization headers from all entries
jq '.log.entries[].request.headers |= map(select(.name | ascii_downcase != "authorization"))' file.har
虽然不是最漂亮的单行命令,但它是有效的。
读取原始HAR文件
HAR文件是JSON,因此理论上可以在任何文本编辑器中读取。实际上它们非常庞大——一个典型的页面加载会产生数百千字节的头信息和体内容,所有内容都嵌套在深层键中。以下是几种导航方式:
- 导入到开发者工具 ——Chrome和Firefox都支持通过齿轮图标将HAR文件导入网络标签页。这提供了与实时捕获相同的筛选和排序界面。
- HAR文件格式化工具 ——基于浏览器,无需安装。当您需要将文件发送给不使用开发者工具的人时非常有用。
jq——用于命令行筛选。jq '.log.entries[] | select(.response.status >= 400) | {url: .request.url, status: .response.status}'提取所有失败请求及其URL时间戳。
为了快速分析和筛选, jq 是最快的。为了分享和视觉检查,使用浏览器导入或在线格式化工具意味着接收方无需了解 jq 是什么。
