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

ReactJS首次加载页面触发SignalR未授权错误,二次刷新才正常如何解决

问题原因

你的代码中getURL是异步请求,调用后不会等待接口返回就直接执行了SignalR连接初始化逻辑。首次加载时localStorage里还没存上接口返回的access_token,所以连接校验失败返回Error: Unauthorized。二次刷新时localStorage里已经有了上一次请求成功存储的token,所以可以正常连接。

修复方案

把SignalR连接初始化的逻辑全部移动到getURL的成功回调中,确保拿到有效token之后再初始化连接,参考修复后的代码:

export default class Dashboard extends Component {
  constructor(props) {
    super(props)
    this.state = {
      signalRURL: 'https://****/?hub=broadcast',
      accessToken: '',
      alertData: {}
    }
    // 把连接实例挂到this上方便后续操作
    this.hubConnection = null
  }

  getURL = () => {
    return new Promise((resolve, reject) => {
      return axios({
        url: 'https://*****/api/SignalRConnection',
        method: "get",
        headers: {
          "content-type": "application/json",
          "Access-Control-Allow-Origin": "*"
        },
      })
      .then(response => {
        resolve(response.data);
      })
      .catch(error => {
        reject(error);
      });
    });
  }

  componentDidMount = () => {
    this.getURL().then(signalRConfig => {
      // 拿到token之后再初始化连接
      const options = { 
        // 直接用接口返回的token,不用读localStorage更稳妥
        accessTokenFactory: () => signalRConfig.accessToken
      }; 

      this.hubConnection = new SignalR.HubConnectionBuilder()
        .withUrl(this.state.signalRURL, options)
        .configureLogging(SignalR.LogLevel.Information)
        .build(); 
      
      this.hubConnection.on('notify', data => { 
        this.setState({alertData: data})
        console.log(data); 
      }); 
      this.hubConnection
        .start()
        .catch(error => console.error(error)); 

      this.hubConnection.serverTimeoutInMilliseconds = 6000000; 
      this.hubConnection.keepAliveIntervalInMilliseconds = 3000000;
      this.hubConnection.onclose((error) => {
        this.hubConnection.start(); 
        console.error(`Something went wrong: ${error}`); 
      }); 
    })
    .catch(err => {
      console.log("获取SignalR连接凭证失败", err)
    })
  }

  // 新增组件卸载逻辑,避免内存泄漏
  componentWillUnmount = () => {
    if (this.hubConnection) {
      this.hubConnection.stop()
    }
  }

  render() {
    return (
      <div>
         
      </div>
    )
  }
}
额外优化建议
  • 如果token存在过期逻辑,可以在accessTokenFactory里加刷新token的逻辑,避免连接有效期内token失效
  • 可以给连接初始化添加最多N次重试逻辑,避免偶发的接口波动导致连接失败
  • 不需要的日志可以及时删除,避免生产环境泄露敏感信息

内容的提问来源于stack exchange,提问作者Vishal K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:54:04