跳到主要内容

修改 WebSocket 消息

在 Proxyman Scripting 中使用 onWebsocket 实时编辑、丢弃或发送 WebSocket(WS/WSS)消息,支持双向传输,支持文本和二进制消息。

1. 这是什么?​

勾选 Modify WebSocket Messages 选项后,脚本中的 onWebsocket() 函数即可实时修改 WebSocket 消息。只需几行 JavaScript,你可以:

  • 编辑消息,例如修改 JSON 字段或替换文本。
  • 丢弃消息,使对端永远收不到它。
  • 向客户端或服务器发送新消息。
  • 在两端同时关闭 WebSocket。

它支持 WS 和 WSS,并且双向生效:从客户端到服务器,以及从服务器到客户端。

信息

macOS 版 Proxyman 26.2.0 或更高版本和 Windows/Linux 版 Proxyman 26.1.0 或更高版本支持 Modify WebSocket Messages,iOS 不支持。

服务器发送的是真实的 BTC 价格,但应用收到的是 $1。包含密码的消息被丢弃,应用还收到了脚本发出的警告。

2. 面临的问题​

聊天、交易、游戏和实时仪表盘等应用使用 WebSocket 获取实时数据,测试起来很困难:

  • 你无法控制服务器。 它发送的是真实数据。要让它发送边界情况,例如价格为 0 或错误消息,就得修改服务器代码。
  • 有些情况很难复现。 消息丢失、异常回复或连接断开,往往不会在你需要的时候出现。
  • 其他工具无法修改消息。 Breakpoint 和 Map Local 作用于 HTTP 握手阶段,而不是握手之后的消息。未启用该选项时,onWebsocket() 只能读取消息。

3. 优势​

  • 无需修改服务器,即可测试应用应处理的每一种消息。
  • 模拟服务器回复:使用 sendToClient() 回复客户端发出的消息,服务器永远不会收到它。
  • 在数据发送到服务器之前,隐藏敏感数据或拦截统计分析事件。
  • 模拟连接断开,测试应用如何重新连接。
  • 只有匹配规则的 WebSocket 会等待脚本处理,其他流量照常传输。

4. 如何使用?​

  1. 抓取你的 WebSocket 连接。对于 wss://,请像处理 HTTPS 一样,为该域名启用 SSL Proxying。
  2. 右键点击 ws:// 或 wss:// 请求 -> Tools -> Scripting…。Proxyman 会创建一条已填入 URL 的规则,以及一个包含 onWebsocket() 的脚本。
  3. 保持 Request 已勾选,并勾选 Modify WebSocket Messages。
  4. 编写 onWebsocket() 代码,然后点击 Save & Activate(macOS 按 ⌘S,Windows/Linux 按 Ctrl+S)。
  5. 重新连接 WebSocket。Proxyman 在 WebSocket 连接时读取该选项,而不是在每条消息到达时读取。
Proxyman Script Editor,已勾选 Modify WebSocket Messages,并包含 onWebsocket() 脚本

在 Script Editor 中勾选 Modify WebSocket Messages

这段脚本会将服务器发来的每个 BTC 价格改为 $1,并丢弃客户端发出的包含密码的消息:

function onWebsocket(context, url, request, response, message) {
// Only change text messages. Binary, ping, pong, and close messages pass through
if (message.type !== "text") {
return message;
}

const json = JSON.parse(message.data);

// 1. Server -> client: every BTC price becomes $1
if (message.from === "server" && json.type === "price") {
json.price = 1;
json.note = "edited by Proxyman";
message.data = JSON.stringify(json);
return message;
}

// 2. Client -> server: drop a message with a password, and warn the client
if (message.from === "client" && json.text.includes("password")) {
sendToClient(JSON.stringify({ type: "warning", text: "Proxyman blocked a password" }));
return null;
}

// 3. Everything else: send it as it is
return message;
}

Websocket 标签页会显示被编辑的消息、脚本发送的消息,以及被丢弃的消息:

Proxyman 主窗口,显示 ws://localhost:3456/prices 请求及其被编辑的 WebSocket 消息

在 Websocket 标签页中查看被编辑和被丢弃的消息

如果想跟着步骤操作,并自己运行一个本地 WebSocket 服务器,请阅读 如何使用 Scripting 修改 WebSocket 消息。

5. onWebsocket() 的返回值​

启用该选项后,Proxyman 会暂存每条文本和二进制消息,直到 onWebsocket() 返回。你的返回值决定后续操作:

在 onWebsocket() 中结果
return message发送消息(包括你做的修改)。
return null丢弃消息,对端永远收不到它。
不返回任何值发送原始消息。
abort()在两端关闭 WebSocket。
sendToClient(data) / sendToServer(data)发送新消息。String 发送文本消息,Uint8Array 发送二进制消息。

message 对象包含以下字段:

字段值
message.from"client" 或 "server"。
message.type"text"、"binary"、"ping"、"pong" 或 "close"。
message.data消息的文本内容。修改它即可编辑文本消息。
message.rawData二进制消息的字节,类型为 Uint8Array。设置一个新的 Uint8Array 即可编辑二进制消息。
message.closeCode数字,仅 close 消息可用,例如 1000。

其他参数请参阅 Scripting 的 WebSocket 说明。

信息

该选项默认关闭。关闭时,onWebsocket() 的行为与以前一样:只读取消息,从不延迟消息。

6. 模板​

无需从零编写脚本。在 Script Editor 中点击 Templates,然后搜索 “websocket”:

  • Log WebSocket Messages:在 Console Log 中打印每条消息。它只读取消息。
  • Modify JSON WebSocket Messages:修改服务器发来的 JSON 消息中的某个字段。
  • Replace Text in WebSocket Messages:在两个方向上查找并替换文本。
  • Drop WebSocket Messages:丢弃匹配正则表达式的消息,例如统计分析事件。
  • Reply to a WebSocket Message:使用 sendToClient() 回复客户端的消息,服务器永远不会收到它。
  • Simulate a WebSocket Disconnect:在收到若干条消息后关闭 WebSocket。

点击 Replace 即可使用模板。Proxyman 还会自动勾选所需的选项,包括 Modify WebSocket Messages。

Proxyman 中的 Script Templates 面板,已筛选出 WebSocket 模板

Script Editor 中的 WebSocket 模板

更多示例请参阅 Snippet Code 页面。

7. 注意事项​

  • 你可以编辑和丢弃文本消息及二进制消息。Ping、pong 和 close 消息始终会被发送:onWebsocket() 可以读取它们,但其返回值会被忽略。
  • 消息保持其类型不变:你无法将文本消息改为二进制消息。
  • 如果脚本抛出错误,或在 30 秒内没有返回,Proxyman 会发送原始消息,并在 Console Log 中打印错误。
  • onWebsocket() 之外的代码每个连接运行一次,因此脚本顶部的计数器会分别统计每个连接的消息数。
  • 通过 sendToClient() 和 sendToServer() 发送的消息不会再次触发 onWebsocket(),因此回复消息的脚本不会陷入无限循环。
  • 当多个启用了该选项的脚本匹配同一个 WebSocket 时,它们会按顺序运行:每个脚本都接收前一个脚本的返回结果。被丢弃的消息不会传给后面的脚本。
  • 超过 16 MB 的消息会原样发送,不经过脚本处理。
  • 支持 async 函数,因此你可以在 onWebsocket() 中使用 await 和 $http。
  • AI 智能体可以通过 Proxyman MCP 创建相同的规则:create_scripting_rule 接受 modify_websocket_messages: true 参数。

8. 故障排除​

消息没有变化​

  • 检查是否已勾选 Modify WebSocket Messages,然后点击 Save & Activate(macOS 按 ⌘S,Windows/Linux 按 Ctrl+S)。
  • 重新连接 WebSocket。该选项在 WebSocket 连接时读取。
  • Request 和 Response 中至少勾选一项。两者都未勾选的规则完全不会运行,包括 onWebsocket()。
  • 修改后请返回 message。如果不返回,Proxyman 会发送原始消息。
  • 在 Script Editor 中打开 Console Log,查看是否有错误。

在 Proxyman 中看不到我的 WebSocket​

请按照你所用平台的 WebSocket 指南操作。许多应用和库会对 localhost 跳过代理。