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

