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

添加WebSocket与Subscription后React Apollo Client请求返回空数据

React连接带WebSocket订阅的GraphQL服务器返回空数据(Apollo Studio正常)

问题概述

给React项目添加WebSocket和GraphQL订阅功能后,所有GraphQL请求都返回空数组/无数据;该问题仅在Node.js服务器新增订阅功能后出现,但Apollo Studio Sandbox中请求可正常返回数据。

可能的问题及修复方案

1. React客户端未配置WebSocket订阅链接

当前你的Apollo Client仅配置了HTTP链接处理查询/突变,但订阅请求需要通过WebSocket发送。需添加拆分链接,根据操作类型自动选择HTTP或WebSocket:

修改React端apollo.js:

import { ApolloClient, InMemoryCache, split } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import { createUploadLink } from "apollo-upload-client";
import { getMainDefinition } from '@apollo/client/utilities';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';

// 定义存储token的键(确保与localStorage存储的键一致)
const TOKEN = 'token';
const ADMINTOKE = 'admintoken';

// HTTP链接:处理查询、突变和文件上传
const uploadLink = createUploadLink({ 
  uri: "http://localhost:8000/graphql" 
});

// WebSocket链接:处理订阅请求
const wsLink = new GraphQLWsLink(createClient({
  url: 'ws://localhost:8000/graphql',
  connectionParams: {
    token: localStorage.getItem(TOKEN),
    admintoken: localStorage.getItem(ADMINTOKE)
  },
}));

// 拆分链接:根据操作类型选择对应传输方式
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  uploadLink,
);

// 认证链接:添加请求头
const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      token: localStorage.getItem(TOKEN),
      admintoken: localStorage.getItem(ADMINTOKE)
    }
  }
});

export const client = new ApolloClient({
  link: authLink.concat(splitLink), // 使用拆分后的链接
  cache: new InMemoryCache(),
});

2. 客户端认证token未正确传递

检查TOKEN和ADMINTOKE常量是否定义:如果未声明,localStorage.getItem(TOKEN)会获取undefined对应的存储值,导致请求头的token为空。而Apollo Studio中你手动输入了正确的token,所以能正常返回数据。

在apollo.js顶部添加常量定义即可解决(如上代码所示)。

3. 服务器上下文日志错误

server.js中requestDidStart插件打印的contextValue.token不存在,你的context返回的是LogedInUser和LogedInAdmin,修正日志便于调试:

// 替换server.js中的对应插件
{
  async requestDidStart({ contextValue }) {
    console.log('当前登录用户:', contextValue.LogedInUser);
    console.log('当前登录管理员:', contextValue.LogedInAdmin);
  },
}

4. 服务器端口日志错误

server.js监听8000端口,但日志输出的是4000,修正后避免混淆:

httpServer.listen(8000, () => { 
  console.log(`🚀 Server ready at http://localhost:8000/graphql`) 
});

验证步骤

  1. 重启Node.js服务器和React项目
  2. 打开浏览器开发者工具→Network标签,查看GraphQL请求的Request Headers,确认token和admintoken是否正确传递
  3. 查看服务器控制台日志,确认LogedInUser是否正确获取到用户信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:20:33