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

如何在React中基于给定urql代码为GraphQL请求设置全局请求头

为urql客户端的所有GraphQL请求添加全局请求头

针对你的场景,分HTTP请求(查询/突变)和WebSocket订阅两种场景,提供具体的实现方式:

一、给HTTP请求(查询/突变)添加全局头

方法1:自定义fetchExchange配置

fetchExchange支持通过fetchOptions直接配置全局请求头,修改你现有代码中的fetchExchange初始化即可:

const client = new Client({
  url: senseopsHTTPServerURL,
  exchanges: [
    cacheExchange,
    authExchange(async utils => {
      let token = initializeAuthState();
      return { 
        addAuthToOperation(operation){
          if(!token) return operation;
          return utils.appendHeaders(operation,{
            Authorization: token,
          })
        },
      }
    }),
    // 自定义fetchExchange,添加全局请求头
    fetchExchange({
      fetchOptions: () => ({
        headers: {
          'X-App-Version': '1.0.0', // 替换为你的实际全局头字段
          'X-Client-Type': 'web'
        }
      })
    }),
    // 注意:defaultExchanges已包含cacheExchange和fetchExchange,重复添加会冗余,建议移除
    subscriptionExchange({
      forwardSubscription: (operation) => ({
        subscribe: (sink) => ({
          unsubscribe: wsClient.subscribe(operation, sink),
        }),
      }),
    }),
  ],
});

方法2:使用mapExchange统一拦截操作

如果需要动态生成全局头(比如根据当前应用状态),可以用mapExchange拦截所有请求操作并添加头:

import { mapExchange } from '@urql/core';

const client = new Client({
  url: senseopsHTTPServerURL,
  exchanges: [
    cacheExchange,
    authExchange(async utils => {
      let token = initializeAuthState();
      return { 
        addAuthToOperation(operation){
          if(!token) return operation;
          return utils.appendHeaders(operation,{
            Authorization: token,
          })
        },
      }
    }),
    // 添加mapExchange统一处理全局头
    mapExchange({
      onOperation(operation, utils) {
        return utils.appendHeaders(operation, {
          'X-App-Version': '1.0.0',
          'X-Client-Id': 'react-app'
        });
      }
    }),
    fetchExchange,
    subscriptionExchange({
      forwardSubscription: (operation) => ({
        subscribe: (sink) => ({
          unsubscribe: wsClient.subscribe(operation, sink),
        }),
      }),
    }),
  ],
});

二、给WebSocket订阅添加全局头

订阅请求的头需要在WebSocket客户端初始化时配置,以graphql-ws为例,修改wsClient的创建逻辑:

import { createClient } from 'graphql-ws';

// 创建WebSocket客户端时设置连接参数(即订阅请求头)
const wsClient = createClient({
  url: '你的WebSocket服务地址',
  connectionParams: () => ({
    Authorization: initializeAuthState(), // 复用现有token逻辑
    'X-App-Version': '1.0.0' // 订阅的全局头字段
  }),
});

// 将配置好的wsClient传入subscriptionExchange
const client = new Client({
  // ...其他原有配置
  exchanges: [
    // ...其他exchange
    subscriptionExchange({
      forwardSubscription: (operation) => ({
        subscribe: (sink) => ({
          unsubscribe: wsClient.subscribe(operation, sink),
        }),
      }),
    }),
  ],
});

注意事项

  • 你的现有代码中重复添加了cacheExchange、fetchExchange和...defaultExchanges,而defaultExchanges本身已包含前两者,建议移除...defaultExchanges,避免重复执行导致的潜在问题。
  • 如果全局头需要动态更新(比如用户切换账号后更新token),可以在authExchange或mapExchange的逻辑中加入状态监听,实时更新请求头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:13:25