You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebSocket upgrade阶段socket.write返回401时ws客户端无法接收响应问题

ws客户端鉴权失败响应问题解答

1. socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n') 代码作用

WebSocket连接建立的第一步是客户端向服务端发送HTTP协议升级请求,只有服务端返回101 Switching Protocols状态码,才会完成协议升级,建立长连接。
这行代码的作用是在HTTP层面直接拒绝客户端的升级请求:

  • 按照HTTP协议格式返回401未授权的响应状态行
  • 末尾的\r\n\r\n是HTTP协议规定的响应头结束标记,告诉客户端响应头已经发送完毕
  • 后续调用socket.destroy()直接断开TCP连接,不会进入WebSocket协议处理流程,本质就是明确告知客户端本次请求鉴权失败,拒绝建立WebSocket连接。

2. 客户端无法在error回调中拿到响应内容的原因

ws库的error事件仅用于通知连接过程出现通用错误,不会暴露HTTP升级阶段的原始响应细节。鉴权失败时服务端返回的是HTTP层的响应,还没进入WebSocket协议交互阶段,所以error事件回调里的event对象不会携带这段HTTP响应内容。

3. 客户端正确获取鉴权失败响应的方法

监听ws实例的unexpected-response事件即可,该事件专门在HTTP升级阶段未返回101状态码时触发,回调中可以拿到原生HTTP响应对象,直接读取状态码、状态信息和响应内容:

const WebSocket = require('ws');
const ws = new WebSocket('wss://your-service-address');

// 监听HTTP升级阶段的非预期响应
ws.on('unexpected-response', (req, res) => {
  // 直接读取HTTP状态码和状态信息,无需手动解析原始响应字符串
  console.log('请求失败,状态码:', res.statusCode);
  console.log('状态信息:', res.statusMessage); // 此处会输出 Unauthorized

  // 如果服务端返回了响应体,可通过以下方式读取
  let responseBody = '';
  res.on('data', chunk => {
    responseBody += chunk.toString();
  });
  res.on('end', () => {
    console.log('响应体内容:', responseBody);
  });
});

ws.onerror = (err) => {
  // 此处仅能拿到通用连接错误信息,无法获取HTTP响应细节
  console.log('连接异常:', err.message);
};

注意:示例服务端代码中仅返回了401响应头,没有写入任何响应体内容,所以上述代码读取responseBody会得到空字符串,属于正常情况,直接通过res.statusCode === 401即可判定为鉴权失败。

内容的提问来源于stack exchange,提问作者Sever

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:36:23