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
相关产品推荐
相关产品推荐

