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

React.js Apollo不同查询自定义动态请求头方案问询

在Apollo中为不同查询设置自定义请求头的方案

我正在寻求在Apollo中为不同查询设置自定义请求头的方法。当前使用Apollo文档中的代码会为该client变量发起的所有HTTP请求统一设置请求头。请问是否可以全局声明authLink或其他变量,以便在不同文件和函数中修改它?或是有更优的请求头设置方案?

用户当前使用的全局请求头配置代码:

import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
  uri: '/graphql',
});

const authLink = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  const token = localStorage.getItem('token');
  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  }
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache()
});

方案1:为单个查询/突变单独设置请求头

不需要修改全局Link,直接在发起查询或突变时通过context参数传入自定义请求头,该参数的优先级会覆盖全局设置的头:

import { useQuery, gql } from '@apollo/client';

const GET_DATA = gql`
  query GetData {
    data { id name }
  }
`;

function MyComponent() {
  const { data } = useQuery(GET_DATA, {
    context: {
      headers: {
        'X-Custom-Header': 'custom-value',
        // 也可以直接覆盖全局的authorization头
        // authorization: `Bearer another-token`
      }
    }
  });
}

方案2:全局动态修改请求头

如果需要在多个文件中动态调整全局请求头,可以把需要变更的头信息存到一个可全局访问的变量中,让authLink读取这个变量而非固定读取localStorage:

// 单独创建authState.js文件
export const authState = {
  token: localStorage.getItem('token'),
  customHeaders: {}
};

// Apollo Client初始化文件中
import { authState } from './authState';

const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      ...authState.customHeaders,
      authorization: authState.token ? `Bearer ${authState.token}` : ""
    }
  }
});

// 在其他任意文件中修改全局请求头
import { authState } from './authState';

// 更新token
authState.token = 'new-token';
// 添加全局自定义头
authState.customHeaders['X-Global-Header'] = 'global-value';

后续所有请求都会自动使用更新后的头信息。

方案3:按查询类型拆分Link(多场景适配)

如果需要针对特定类型的查询(比如某类业务查询)设置专属请求头,可以用split函数将请求分流到不同的Link:

import { split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';

// 针对特殊查询的自定义Link
const customLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      'X-Special-Header': 'special-value'
    }
  }
});

// 判断是否是需要特殊头的查询(这里按查询名称匹配)
const isSpecialQuery = ({ query }) => {
  const definition = getMainDefinition(query);
  return (
    definition.kind === 'OperationDefinition' &&
    definition.name?.value.includes('Special')
  );
};

// 拆分Link:符合条件的用customLink,否则用默认authLink
const combinedLink = split(
  isSpecialQuery,
  customLink.concat(httpLink),
  authLink.concat(httpLink)
);

const client = new ApolloClient({
  link: combinedLink,
  cache: new InMemoryCache()
});

这样就能自动为指定查询应用特殊请求头,其他查询沿用全局配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:32:37