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

浏览器中STOMP WebSocket连接报401未授权,Postman可正常连接

STOMP WebSocket连接401未授权问题(浏览器失败/Postman成功)

问题描述

通过STOMP协议实现前后端WebSocket通信时出现异常:登录后在浏览器发起连接返回401(Unauthorized),但Postman中相同连接请求返回200(OK)。JWT已存储在浏览器sessionStorage中,尝试构建Authorization请求头传递给stompClient。

客户端代码(原版本)

async function connect() {
    var socket = new SockJS("http://localhost:8080/api/websocket");
    let stompClient = Stomp.over(socket);
    const token = sessionStorage.getItem("jwtToken");
    const headers = {
      Authorization: "Bearer " + token,
    };
    const headersAuth = { headers };
    console.log(headersAuth);
    stompClient.connect({ headersAuth }, function (frame) {
      stompClient.subscribe("/topic/events", function (messageOutput) {
        const msg = JSON.parse(messageOutput.body);

        if (msg.id_user === sessionStorage.getItem("jwtToken")) {
          setMess(
            "for the client with id " +
              msg.id_user +
              " the max energy for device with ID " +
              msg.id_device +
              " has been EXCEDEED with " +
              msg.diferenta
          );
          setOpen(true);
        }
        console.log(msg.id_user);
      });
    });
  }

问题分析与解决方案

核心问题:请求头传递格式错误

原代码中错误地将headers包装在嵌套对象headersAuth中传递给stompClient.connect,导致服务器无法正确识别Authorization头——这是浏览器返回401的直接原因。Postman中你应该是直接正确设置了请求头,所以连接成功。

其他潜在问题

  1. 用户ID判断逻辑错误:直接用JWT Token与msg.id_user比较,Token本身不是用户ID,需解析JWT Payload获取用户标识。
  2. 缺少错误回调:未添加连接失败的回调函数,无法直观排查连接错误细节。

修正后的代码

async function connect() {
    var socket = new SockJS("http://localhost:8080/api/websocket");
    let stompClient = Stomp.over(socket);
    const token = sessionStorage.getItem("jwtToken");
    
    // 先验证Token是否存在
    if (!token) {
        console.error("sessionStorage中未找到JWT Token");
        return;
    }
    
    const headers = {
        Authorization: "Bearer " + token,
    };
    
    console.log("连接请求头:", headers);
    
    // 直接传递headers对象,而非嵌套结构
    stompClient.connect(headers, function (frame) {
        console.log("连接成功:", frame);
        stompClient.subscribe("/topic/events", function (messageOutput) {
            const msg = JSON.parse(messageOutput.body);
            
            // 解析JWT获取用户ID(需根据实际Payload字段调整)
            const parsedToken = parseJwt(token);
            const userId = parsedToken?.id_user;
            
            if (msg.id_user === userId) {
                setMess(
                    `客户端ID ${userId} 的设备ID ${msg.id_device} 已超出最大能耗,超出值:${msg.diferenta}`
                );
                setOpen(true);
            }
            console.log("收到消息目标用户ID:", msg.id_user);
        });
    }, function(error) {
        // 添加错误回调,便于排查问题
        console.error("连接失败:", error);
    });
}

// 辅助函数:解析JWT Payload
function parseJwt(token) {
    try {
        return JSON.parse(atob(token.split('.')[1]));
    } catch (e) {
        console.error("JWT解析失败:", e);
        return null;
    }
}

额外验证步骤

  1. 在浏览器开发者工具的网络面板中,查看SockJS发起的请求,确认Authorization头是否正确携带。
  2. 验证sessionStorage中的jwtToken是否有效(未过期、签名正确)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:45:28