必须先调用 json.stringify() 将对象转为字符串,否则 send() 会发送 "[object object]" 或报错;websocket 协议本身不解析 json,收发均需手动序列化与反序列化。

必须先 JSON.stringify(),否则会报错或发空消息。 WebSocket 的 send() 方法只接受 string 或 ArrayBuffer / Blob / TypedArray,直接传入 JS 对象(如 {type: "login", user: "Alice"})不会报语法错误,但服务端收到的是 [object Object] 或空字符串——这是最常踩的坑。
前端发送 JSON:必须 stringify,且建议加 try-catch
客户端用原生 WebSocket 发送结构化数据时,核心就一条:对象 → 字符串。不封装、不省略、不依赖“自动转换”。
-
socket.send()不会自动序列化对象,传入对象等于传入String(obj),结果是"[object Object]" - 必须显式调用
JSON.stringify(message),且建议包裹在try...catch中,避免因循环引用、undefined、Date等非法值导致send()失败静默丢包 - 示例中
timestamp: Date.now()是安全的,但new Date()或function字段会抛TypeError
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => {
const msg = { type: 'auth', token: 'abc123', expires_at: Date.now() + 3600000 };
try {
socket.send(JSON.stringify(msg)); // ✅ 正确
} catch (e) {
console.error('JSON serialization failed:', e);
}
};
Java 后端接收 JSON:Decoder.Text 是绕不开的配置项
Spring WebSocket 或原生 javax.websocket 默认不解析 JSON。若想让 @OnMessage 方法直接接收 Java 对象(如 User),必须注册自定义 Decoder.Text<user></user>,否则只能拿到原始字符串再手动解析。
- 没配
decoders时,@OnMessage参数只能是String、byte[]或ByteBuffer - 配了
decoders后,WebSocket 容器会在调用@OnMessage前自动调用你实现的decode()方法,把字符串转成目标对象 - 常见错误:忘记在
@ServerEndpoint注解里声明decoders = {UserDecoder.class},或willDecode()返回false导致跳过解码
关键代码片段(非完整类):
@ServerEndpoint(value = "/ws", decoders = {UserDecoder.class})
public class ChatEndpoint {
@OnMessage
public void onMessage(User user, Session session) { // ✅ 这里能直接收 User 对象
System.out.println(user.getName());
}
}
跨语言/跨库兼容性:别依赖“自动 JSON 检测”
不同语言的 WebSocket 库对 JSON 的处理策略差异很大——Python 的 websockets、C 的 libwebsockets、.NET 的 WebSocket4Net 全都不识别内容类型,也不会尝试解析 JSON。所谓“发送 JSON”,本质只是发送一串符合 JSON 语法规则的文本。
- 服务端不能假设客户端发的是 JSON;客户端也不能假设服务端返回的是可直接
JSON.parse()的字符串(比如可能混着二进制帧或带前缀协议头) - 如果用
fastjson或ObjectMapper解析,注意反序列化时字段名大小写、null 值处理、时间格式等细节,和前端JSON.stringify()的输出要对齐 - C 语言示例里用
cJSON_AddStringToObject()构建对象再cJSON_Print()转字符串,就是最朴素也最可靠的路径
真正容易被忽略的点是:WebSocket 协议层根本不关心你传的是 JSON、XML 还是纯文本。所有“JSON 支持”都是应用层自己加的序列化/反序列化逻辑。一旦前后端约定不一致(比如前端漏了 stringify,后端却硬解),问题往往表现为“收不到”或“字段为空”,而不是明显报错。










