# WebSocket 抓包

> 使用 Proxyman 从 Web 浏览器、iOS 设备和模拟器、Android、NodeJS 或 Python 服务器抓取并解密 WebSocket（WS/WSS）流量。

## 1. 这是什么？ {#1-whats-it}

Proxyman 可以抓取 WebSocket（WS）和安全 WebSocket（WSS）流量，并让你轻松预览。

* 从 iOS 真机和 iOS 模拟器抓取 WS/WSS（需要 [Atlantis framework](https://github.com/ProxymanApp/atlantis)）
* 从 Web 浏览器和 Mac 应用中抓取 WS/WSS。
* 从 Android 真机或 Android 模拟器中抓取 WS/WSS。
* 格式化显示 WebSocket 消息。
* 按 All / Sent / Received 过滤消息。
* 以 JSON / Tree Preview / HEX 格式查看内容。
* 自定义列：Frame、Length、Data、Time 等。
* 在可能的情况下，自动将二进制消息解码为 JSON。
* 在 Sublime 或 VS Code 等外部编辑器中打开 WebSocket 消息。
* 通过 [Scripting](#7-modify-websocket-messages-with-scripting) 编辑、丢弃或发送 WebSocket 消息（需要 macOS 版 Proxyman 26.2.0 或更高版本，或 Windows/Linux 版 Proxyman 26.1.0 或更高版本）。

## 2. 从 Web 浏览器抓取 WS/WSS {#2-capture-wswss-from-web-browsers}

### 本地 WebSocket {#localhost-websocket}

借助 [Automatic Setup](https://proxyman.com/docs/zh-cn/automatic-setup/automatic-setup)，Proxyman 可以从 Google Chrome 中抓取本地 WebSocket，例如 ws://localhost:3000。

1. 进入 **Setup** 菜单 -> **Automatic Setup…**
2. 选择 Google Chrome（New Profile 或 Current Profile）。随即会打开一个新的 Google Chrome 窗口。
3. 在该窗口中打开你的本地 WebSocket 页面。Proxyman 会将其抓取下来。

### 生产环境 WebSocket {#production-websocket}

Proxyman 无需任何设置，即可自动抓取你在 Google Chrome 中的 WS/WSS 流量。

1. 打开 Proxyman 和 Google Chrome
2. 产生一些 WS/WSS 流量，例如访问 [https://echo.websocket.org/.ws](https://echo.websocket.org/.ws)
3. 在 Proxyman 中查看 WS/WSS 数据

### 带 Protobuf 负载的 WebSocket {#websocket-with-protobuf-payload}

从 macOS 版 Proxyman 6.5.0 或更高版本开始，Proxyman 可以解码 WebSocket 消息中的 Protobuf。

1. 先确保 Proxyman 能够抓取你的 WebSocket 流量
2. 右键点击 WebSocket Protobuf 消息 -> **Protobuf** -> **Decode Raw Text…** 或 **Decode with Message Type…**

* **Raw mode**：如果你没有 Protobuf desc 文件，可以使用此模式。
* **Message Type**：使用 Protobuf desc 文件中的 Message Type。

![Proxyman 右键菜单，作用于二进制 WebSocket 消息，包含 Protobuf、Decode Raw Text 和 Decode with Message Type](https://proxyman.com/docs/assets/Screenshot%202026-01-30%20at%2015.11.30.jpg)

_使用 Protobuf 解码 WebSocket 负载_

## 3. 从 iOS 抓取 WS/WSS {#3-capture-wswss-from-ios}

如果你的 iOS 应用使用 URLSessionWebSocketTask，或使用 Starscream、SocketRocket 等 iOS WebSocket 库，Proxyman 可能无法抓取 WS/WSS 流量。

* **原因**：这是 Apple 的设计。**URLSessionWebSocketTask** 不遵循系统 HTTP 代理，所有 WS/WSS 流量都会直接发送到互联网，因此 Proxyman 或 Charles Proxy 都无法抓取。
* 示例应用：[https://github.com/ProxymanApp/websocket-example-ios-app](https://github.com/ProxymanApp/websocket-example-ios-app)

### ✅ 方案 1（推荐用于 iOS 17 或更高版本） {#-solution-1-recommended-for-ios-17-or-later}

1. 请按照 [iOS 设备](https://proxyman.com/docs/zh-cn/debug-devices/ios-device) 或 [iOS 模拟器](https://proxyman.com/docs/zh-cn/debug-devices/ios-simulator) 的设置指南操作。确保证书已安装并在设备上受信任。
2. 在 Proxyman 中：**Tools** -> **Proxy Settings** -> **SOCKS Proxy Settings…** -> 启用。记下端口号。
3. 在 Proxyman 主窗口中，记下工具栏中的当前 IP。

![Proxyman 状态弹出框，显示 IP 192.168.64.4、Proxy Port 9090，以及 Recording、macOS proxy 和 Network Extension 开关](https://proxyman.com/docs/assets/proxyman-status-popover.jpg)

_获取 Proxyman 当前 IP_

4. 在你的应用中配置 SOCKS 代理。确保仅在 Debug 构建中启用，例如通过开关控制。你不希望这个设置出现在 Release 构建中。

* 适用于 NWConnection

```swift
let parameters = webSocketURL.scheme == "wss" ? NWParameters.tls : NWParameters.tcp

let options = NWProtocolWebSocket.Options()
options.autoReplyPing = true

parameters.defaultProtocolStack.applicationProtocols.insert(options, at: 0)

if #available(iOS 17.0, *) {
    let socksv5Proxy = NWEndpoint.hostPort(host: "x.x.x.x", port: 8889) //  Please replace x.x.x.x with a real Proxyman IP
    let config = ProxyConfiguration.init(socksv5Proxy: socksv5Proxy)
    let context = NWParameters.PrivacyContext(description: "my socksv5Proxy")
    context.proxyConfigurations = [config]

    parameters.setPrivacyContext(context)
}

let connection = NWConnection(to: .url(webSocketURL), using: parameters)
connection.start(queue: .main)
```

* 适用于 URLSession 和 URLSessionWebSocketTask

```swift
private lazy var urlSession: URLSession = {
    let config = URLSessionConfiguration.default
    if #available(iOS 17.0, *) {
        let socksv5Proxy = NWEndpoint.hostPort(host: "x.x.x.x", port: 8889) //  Please replace x.x.x.x with a real Proxyman IP
        let proxyConfig = ProxyConfiguration.init(socksv5Proxy: socksv5Proxy)
        config.proxyConfigurations = [proxyConfig]
    }

    return URLSession(configuration: config, delegate: nil, delegateQueue: nil)
}()
```

5. 完成 ✅

![Proxyman 在 iOS 模拟器中抓取 URLSessionWebSocketTask 应用发出的 wss://echo.websocket.org 消息](https://proxyman.com/docs/assets/Screenshot%202024-11-29%20at%201.17.23%E2%80%AFPM.jpg)

_使用 Proxyman 从 iOS 抓取 WebSocket_

* 感谢 [**FranklinSamboni**](https://github.com/FranklinSamboni) **->** [https://github.com/ProxymanApp/Proxyman/issues/586#issuecomment-2125082129](https://github.com/ProxymanApp/Proxyman/issues/586#issuecomment-2125082129)
* 教程：[如何在 iOS 模拟器或设备上拦截和调试 WebSocket](https://proxyman.com/posts/2019-10-18-WebSocket-Debugging)

### ✅ 方案 2 {#-solution-2}

使用 [Atlantis Framework](https://github.com/ProxymanApp/atlantis#features)（由 Proxyman 开发）从 iOS 抓取 **URLSessionWebSocketTask** 的 WS/WSS 流量。

更多内容请参阅 [Atlantis WS/WSS 流量指南](https://github.com/ProxymanApp/atlantis#wswss-traffic)。

## 4. 从 Web 浏览器（Chrome、Safari 等）抓取 WebSocket {#4-capture-websockets-from-your-web-browser-chrome-safari-etc}

* Proxyman 开箱即可从 Web 浏览器抓取 WS/WSS，无需任何配置。
* 使用方法：打开 Google Chrome -> 访问建立 WS/WSS 连接的网站 -> 打开 Proxyman -> 找到你的 WebSocket 域名 -> 在 Response 面板中，对这些域名点击 **Enable SSL Proxying**。在浏览器中重新加载网站。Proxyman 会抓取并解密 WS/WSS ✅

## 5. 从 NodeJS、Golang、Python 服务器抓取 WebSocket {#5-capture-websocket-from-nodejs-golang-python-server}

* Proxyman 可以抓取来自 NodeJS、Golang、Python 和 Ruby 服务器的 WS/WSS。
* 使用方法：阅读 [automatic-setup.md](https://proxyman.com/docs/zh-cn/automatic-setup/automatic-setup)，了解如何在其打开的终端中启动服务器 -> 建立 WS/WSS 连接 -> Proxyman 会自动抓取并解密 ✅

## 6. 在 localhost <-> 线上环境之间映射 WebSocket {#6-map-websocket-from-localhost---production}

你可以在 localhost <-> 线上环境之间映射 WebSocket 流量。请参阅 [Map Remote 工具](https://proxyman.com/docs/zh-cn/advanced-features/map-remote#74-map-websocket-from-localhost-to-production)。

## 7. 使用 Scripting 修改 WebSocket 消息 {#7-modify-websocket-messages-with-scripting}

从 macOS 版 Proxyman 26.2.0 和 Windows/Linux 版 Proxyman 26.1.0 开始，你可以用几行 JavaScript 实时修改 WebSocket 消息。在 Scripting 规则中勾选 **Modify WebSocket Messages**，然后使用 `onWebsocket()` 来：

* 编辑文本或二进制消息，两个方向均可。
* 丢弃消息，使对端永远收不到它。
* 向客户端或服务器发送新消息。
* 关闭 WebSocket，以测试你的应用如何重新连接。

```javascript
function onWebsocket(context, url, request, response, message) {
  if (message.from === "server" && message.type === "text") {
    message.data = message.data.replace("staging.example.com", "api.example.com");
  }
  return message;
}
```

- [修改 WebSocket 消息](https://proxyman.com/docs/zh-cn/scripting/modify-websocket-messages)

## 了解更多 {#learn-more}

* [如何使用 Scripting 修改 WebSocket 消息](https://proxyman.com/posts/2026-10-23-modify-websocket-messages-with-scripting)
* [如何抓取 WebSocket 并解码 Protobuf 消息](https://proxyman.com/posts/how-to-capture-websocket-with-protobuf-message)
* [Proxyman 与 mitmproxy 对比：解码 Protobuf WebSocket 消息](https://proxyman.com/posts/2026-07-21-Proxyman-vs-mitmproxy-Protobuf-WebSocket)
