如何在 TanStack Query 中为 API 请求添加 bearer header?
在 queryFn 中,为 fetch 的第二个参数添加 headers,设置 “Authorization: Bearer ${token}```。TanStack Query 负责管理查询状态、缓存和重试,请求头则在实际发送请求的 fetch` 中配置。
这种写法要求目标 API 支持 Bearer 认证。API key 的传递方式由服务端规定,有些接口要求使用 x-api-key,不能统一加上 Bearer 前缀。
修改请求代码
保留原有的 QueryClientProvider 和 QueryClient,将 Example 替换为下面的 React TS 组件。示例假设登录流程已取得非空的 token,并通过 props 传入组件。
import { useQuery } from '@tanstack/react-query'
type Repository = {
full_name: string
description: string | null
subscribers_count: number
stargazers_count: number
forks_count: number
}
type ExampleProps = {
token: string
}
function Example({ token }: ExampleProps) {
const { isPending, error, data, isFetching } = useQuery({
queryKey: ['repoData'],
queryFn: async (): Promise<Repository> => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github+json',
},
},
)
if (!response.ok) {
throw new Error(
`Request failed: ${response.status} ${response.statusText}`,
)
}
return (await response.json()) as Repository
},
})
if (isPending) return <p>Loading...</p>
if (error) {
return <p>An error has occurred: {error.message}</p>
}
return (
<div>
<h1>{data.full_name}</h1>
<p>{data.description}</p>
<strong>👀 {data.subscribers_count}</strong>{' '}
<strong>✨ {data.stargazers_count}</strong>{' '}
<strong>🍴 {data.forks_count}</strong>
<div>{isFetching ? 'Updating...' : ''}</div>
</div>
)
}
在原来渲染 <Example /> 的位置,传入登录流程取得的 accessToken:
<Example token={accessToken} />
等 token 就绪后再渲染这个组件。accessToken 来自你的认证状态,TanStack Query 不会自动生成它。
这几处修改的作用
Authorization 是认证请求头,Bearer 和 token 之间需要一个空格。token 变量只保存令牌本身,不要包含 Bearer ,否则会重复拼接。
Accept 用于说明期望的响应格式,与认证无关。这个 GET 请求没有请求体,无需为了添加认证而设置 Content-Type。
检查 response.ok 是为了处理 HTTP 错误响应。fetch 收到 401、403 等响应时,通常仍会正常返回 Response。显式抛出错误后,TanStack Query 才能通过 error 暴露这类失败,避免把错误响应当作仓库数据。
Repository 描述了组件使用的字段。as Repository 只是 TypeScript 类型断言,不会在运行时验证 JSON 的结构。
使用时需要注意什么
不要把真实的私密 API key 或长期 token 写进前端源码,也不要放进公开的 StackBlitz 示例。前端构建环境变量最终也可能进入浏览器代码,不能用来保管服务端密钥。必须保密的密钥应由后端保存,并由后端代为调用 API。
示例使用了 ['repoData']。如果接口结果随登录用户变化,应把用户 ID 等非敏感身份信息加入 queryKey,并在退出登录或切换账号时清理相应缓存。不要把原始 token 放进 queryKey。仅修改请求头也不会自动触发重新请求。
跨域请求携带 Authorization 时,浏览器通常会先发送 CORS 预检请求,目标服务需要允许该请求头。如果控制台报告 CORS 错误,需要检查服务端的跨域配置。
备注:内容仅供参考。
