Please enable Javascript to view the contents

HAR 文件详解

 ·  ☕ 8 分钟

前不久做了个视频,介绍了如何使用 Automa 浏览器自动化插件来自动添加得到电子书新书。这个过程涉及到从浏览器开发者工具中获取返回的数据。

《打工人生产力革命!Automa浏览器自动化插件实战:自动添加得到电子书新书》

于是有网友问我,一次只能获取一个请求的返回数据,如何才能批量获取所有请求的返回数据?

Save all XHR requests from Chrome (or other browser) Developer Tools - Stack Overflow

这个问题的答案是使用 HAR 文件。

什么是HAR文件?

HTTP存档格式(HAR)是一种标准化的JSON格式,用于记录Web浏览器与网站交互时发生的HTTP请求和响应的日志。它由Web性能工作组(属于W3C)定义,已成为分析网络性能、调试API调用、审计网站行为和重现问题的事实标准

核心价值

  1. 记录与重现: 完整记录一次网页加载或用户会话期间发生的所有网络活动。
  2. 性能分析: 提供精确的时间戳和计时信息,用于分析页面加载性能瓶颈(DNS查找、连接建立、TTFB、内容下载等)。
  3. 调试: 帮助开发人员检查请求头、响应头、请求体、响应体、状态码、重定向链等,定位前后端问题。
  4. 审计与监控: 检查资源加载情况、第三方请求、安全头设置等。
  5. 自动化测试: 作为测试用例的输入或输出,用于模拟或验证网络行为。
  6. 协作: 易于分享网络跟踪信息,方便团队协作诊断问题。

文件结构详解 (基于规范 v1.2)

HAR文件本质上是一个大的JSON对象。其根结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
  "log": {
    "version": "1.2", // HAR格式版本号
    "creator": {      // 生成此HAR文件的工具信息
      "name": "Chrome", // 工具名称 (e.g., Chrome, Firefox, Fiddler, Charles)
      "version": "120.0.0.0", // 工具版本
      "comment": "" // (可选) 注释
    },
    "browser": {     // (可选) 生成日志时使用的浏览器信息
      "name": "Chrome",
      "version": "120.0.0.0",
      "comment": ""
    },
    "pages": [       // (可选,但强烈推荐) 记录页面相关信息(如页面加载事件)
      {
        "startedDateTime": "2025-06-14T08:15:30.123Z", // 页面加载开始时间 (ISO 8601)
        "id": "page_1", // 页面唯一标识符 (在entries中引用)
        "title": "Example Domain", // 页面标题
        "pageTimings": { // 页面相关计时信息
          "onContentLoad": 172, // (可选) 页面DOMContentLoaded事件耗时 (毫秒)
          "onLoad": 250,        // (可选) 页面load事件耗时 (毫秒)
          "comment": ""         // (可选)
        },
        "comment": "" // (可选)
      }
    ],
    "entries": [     // **核心部分**:按时间顺序记录所有HTTP事务
      { ... },      // 每一个对象代表一个HTTP请求/响应对
      { ... }
    ],
    "comment": ""   // (可选) 整个日志的注释
  }
}

entries 数组详解 (最重要的部分)

每个 entry 对象代表一个完整的HTTP事务(请求 + 响应 + 元数据)。其结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{
  "pageref": "page_1", // (可选) 关联的page id (如果pages存在)
  "startedDateTime": "2025-06-14T08:15:30.456Z", // 请求开始时间 (ISO 8601)
  "time": 47.5,        // **总耗时** (毫秒),从请求开始到响应接收完成
  "request": {         // 请求详情
    "method": "GET",   // HTTP方法 (GET, POST, PUT, DELETE等)
    "url": "https://www.example.com/main.js", // 请求的完整URL
    "httpVersion": "HTTP/1.1", // HTTP协议版本
    "cookies": [       // 随请求发送的Cookie列表
      {
        "name": "sessionid",
        "value": "abc123xyz",
        "path": "/",
        "domain": ".example.com",
        "expires": null, // (可选) Cookie过期时间 (ISO 8601)
        "httpOnly": false,
        "secure": true,
        "comment": ""
      }
    ],
    "headers": [       // 请求头列表
      {
        "name": "User-Agent",
        "value": "Mozilla/5.0 ... Chrome/120.0.0.0"
      },
      {
        "name": "Accept",
        "value": "application/javascript,*/*;q=0.8"
      },
      ... // 其他请求头
    ],
    "queryString": [   // (可选) URL查询参数列表 (已解析)
      {
        "name": "search",
        "value": "har"
      }
    ],
    "postData": {      // (可选) 仅当请求包含正文时存在 (e.g., POST, PUT)
      "mimeType": "application/x-www-form-urlencoded", // 正文的MIME类型
      "params": [      // (可选) 如果mimeType是表单类型,存储键值对
        {
          "name": "username",
          "value": "john_doe"
        }
      ],
      "text": "username=john_doe&password=secret", // 正文原始文本
      "comment": ""
    },
    "headersSize": 253, // (估算) 请求头的大小 (字节),包括请求行
    "bodySize": 33,    // 请求正文的大小 (字节)
    "comment": ""
  },
  "response": {        // 响应详情
    "status": 200,     // HTTP状态码
    "statusText": "OK", // HTTP状态文本
    "httpVersion": "HTTP/1.1", // HTTP协议版本
    "cookies": [       // 响应设置的Cookie列表 (格式同request.cookies)
      ...
    ],
    "headers": [       // 响应头列表
      {
        "name": "Content-Type",
        "value": "application/javascript; charset=utf-8"
      },
      {
        "name": "Cache-Control",
        "value": "public, max-age=3600"
      },
      ... // 其他响应头
    ],
    "content": {       // 响应正文详情
      "size": 1234,    // **从网络接收**的正文大小 (字节) (解码前)
      "compression": 0, // (可选) 压缩节省的大小 (字节) 如果响应被压缩
      "mimeType": "application/javascript; charset=utf-8", // 从Content-Type推断的MIME类型
      "text": "console.log('Hello HAR!'); ...", // (可选) 解码后的响应正文文本。二进制数据通常被省略或Base64编码。
      "encoding": "base64", // (可选) 如果text是二进制数据的Base64编码,则指定
      "comment": ""
    },
    "redirectURL": "", // (可选) 如果发生重定向,这里是目标URL
    "headersSize": 312, // (估算) 响应头的大小 (字节),包括状态行
    "bodySize": 1234,   // **从网络接收**的响应正文大小 (字节) (解码前)。等于`content.size`。
    "comment": ""
  },
  "cache": {},         // (可选) 与缓存相关的信息,使用较少
  "timings": {         // **关键性能指标**
    "blocked": 1.5,    // (可选) 等待空闲网络连接的时间 (可能包括代理协商)。-1表示未知。
    "dns": 5.0,        // (可选) DNS查找时间。-1表示未知。
    "connect": 25.0,   // (可选) 建立连接时间 (TCP/SSL)。-1表示未知。
    "send": 0.3,       // 发送请求数据的时间 (上传)
    "wait": 15.7,      // 等待服务器响应的时间 (TTFB - Time To First Byte)
    "receive": 5.0,    // 接收响应数据的时间 (下载)
    "ssl": -1,         // (可选) SSL/TLS握手时间 (包含在connect中,如果适用)。-1表示未知。
    "comment": ""
  },
  "serverIPAddress": "192.0.2.1", // (可选) 服务器的IP地址
  "connection": "12345",         // (可选) 连接标识符
  "comment": ""                  // (可选) 此条目的注释
}

关键计时点关系:
timetimings.blocked + timings.dns + timings.connect + timings.send + timings.wait + timings.receive

相关工具

  1. 生成HAR文件:

    • 浏览器开发者工具:
      • Chrome/Edge: F12 -> Network 标签 -> 进行页面操作 -> 右键点击请求列表 -> Save all as HAR with content / 点击导出按钮 (💾图标)。
      • Firefox: F12 -> Network -> 进行页面操作 -> 右键点击请求列表 -> Save All As HAR / 点击导出按钮 (💾图标)。
      • Safari: 需先启用开发者菜单 (Preferences -> Advanced -> Show Develop menu)。Develop -> Show Web Inspector -> Network -> 进行页面操作 -> Export 按钮。
    • 网络代理工具:
      • Fiddler Classic/Everywhere: 强大的抓包工具,捕获所有HTTP(S)流量,可清晰导出HAR (File -> Export Sessions -> All Sessions -> Format HTTPArchive (.har))。
      • Charles Proxy: 功能类似Fiddler,也支持导出HAR (File -> Export Session -> HTTP Archive (.har) format)。
    • API测试工具:
      • Postman: 在运行集合(Collection Runner)或监控器(Monitor)后,可以将运行结果导出为HAR (View Results -> Export Results -> Export as HAR).
      • JMeter: 可以通过插件或后处理器将测试结果保存为HAR格式。
    • 命令行工具:browsertime (结合Selenium) 可以生成包含HAR的性能测试结果。
  2. 查看与分析HAR文件:

    • 浏览器开发者工具:
      • Chrome/Edge: Network 标签 -> 点击导入按钮 (📂图标) -> 选择HAR文件。文件内容将加载到Network面板,可以像实时捕获一样查看、过滤、排序和分析每个请求。
      • Firefox: Network -> 点击导入按钮 (📂图标) -> 选择HAR文件。功能类似Chrome。
    • 在线分析器:
    • 桌面应用:
      • Fiddler/Charles: 导入HAR文件 (File -> Import Sessions...),功能强大,可深度分析。
      • Visual Studio Code: 安装 HAR Viewer 等扩展,方便在编辑器内查看。
    • 命令行工具:har-to-curl (将HAR条目转换为cURL命令), jq (强大的JSON处理工具,可用于筛选、提取HAR数据)。

实用技巧与最佳实践

  1. 包含内容: 导出时务必勾选包含请求/响应正文的选项 (如浏览器中的 “Save with content”),否则 request.postData.textresponse.content.text 可能为空,失去调试意义。
  2. 清理敏感数据: HAR文件可能包含:
    • 认证信息: Cookies (request.cookies, response.cookies), Authorization 头 (request.headers), URL中的token/API key (request.url, request.queryString), 登录表单数据 (request.postData.text)。
    • 个人身份信息 (PII): 用户名、邮箱、地址等。
    • 内部信息: 内部API地址、服务器IP、调试信息。
    • 在分享HAR文件前,务必手动编辑或使用工具(如 Fiddler 的 Remove > Headers/Cookies 功能或专门脚本)清除这些敏感数据!
  3. 关注性能指标 (timings):
    • wait (TTFB): 服务器处理慢或网络延迟高。
    • dns: DNS解析慢。
    • connect: 建立TCP连接慢 (或SSL握手慢 ssl)。
    • receive: 下载内容慢 (内容大或带宽低)。
    • 结合瀑布图分析依赖关系和阻塞。
  4. 利用过滤与搜索: 导入到浏览器或分析工具后,充分利用URL过滤、状态码过滤、类型过滤 (XHR, JS, CSS, Img)、关键词搜索等功能快速定位问题请求。
  5. 分析请求/响应细节:
    • 请求头: 检查 User-Agent, Accept-*, Cache-Control, Cookie 是否正确。
    • 响应头: 检查 Cache-Control, Content-Type, Set-Cookie, 安全头 (CSP, HSTS), 状态码/重定向。
    • 请求体 (postData): 验证发送的表单数据、JSON payload是否正确。
    • 响应体 (content.text): 查看API返回数据、错误信息、HTML/JS/CSS内容。
  6. 处理大文件: 大型HAR文件 (几十MB+) 在浏览器中打开可能卡顿。考虑:
    • 使用性能更强的工具 (如 Fiddler/Charles)。
    • 使用命令行工具 (jq) 提取特定信息。
    • 利用在线分析器的处理能力。
    • 在生成HAR时进行过滤(如只记录特定域名)。
  7. 理解大小字段:
    • request.bodySize / response.bodySize: 网络上传输的原始(压缩后)数据大小。
    • response.content.size: 同 response.bodySize
    • response.content.text.length: (如果存在) 表示解码解压后的文本长度(字节数,不是字符数)。
  8. 导出时机: 在问题复现后立即导出HAR,避免浏览器清理缓存或开发者工具刷新丢失记录。在浏览器中勾选 “Preserve log” 选项有助于在页面跳转时保持记录。
  9. 用于API测试:
    • 录制: 使用Postman或Fiddler录制API调用生成HAR。
    • 回放/模拟: 一些工具(如Postman, MockServer)可以导入HAR来生成Mock服务或回放请求序列进行测试。

总结

HAR文件是分析和调试Web应用网络行为的宝贵资产。理解其结构(特别是 log.entries 中的 request, response, timings)是利用它的基础。掌握浏览器开发者工具、Fiddler/Charles等工具的导出导入功能,并熟练运用在线或离线分析器查看瀑布图、检查头信息和内容,是高效使用HAR的关键。务必牢记清理敏感信息,并善用过滤和性能指标分析来定位问题。无论是前端工程师、后端工程师、测试工程师还是性能优化专家,HAR都是一个不可或缺的标准化工具。

参考资料

分享

码农真经
作者
码农真经
Web Developer