Next.js中使用SWR与Axios发起请求时如何正确传递自定义请求头
问题原因
你的代码存在几个核心错误,直接导致运行报错和请求无效:
- 违反React Hook使用规则:
useSession是React Hook,仅允许在React组件、自定义Hook的顶层作用域调用,你在普通函数fetcher内调用Hook,就是截图报错的直接原因。 fetcher函数没有返回请求的Promise实例,SWR无法获取到接口返回结果。- 请求头缺少必填的
Client-Id字段,Authorization字段的拼接逻辑错误,额外拼接了无意义的token参数。 useSWR中传入的auth.token属于未定义变量,不存在对应值。- 未处理session加载状态,session未初始化完成时直接取
session.accessToken会触发空值报错。
修复后的完整代码
import axios from "axios"; import Link from "next/link"; import { VStack, Heading, Divider, Text, Box, Badge, Center, } from "@chakra-ui/react"; import { useSession } from "next-auth/react" import useSWR from 'swr' // 通用fetcher,接收请求所需的所有参数,不在内部调用Hook const fetcher = (url, accessToken, clientId) => { return axios .get(url, { headers: { Authorization: `Bearer ${accessToken}`, 'Client-Id': clientId } }) .then((res) => res.data) } function Dash () { // Hook必须放在组件顶层调用 const { data: session, status: sessionStatus } = useSession() // session未完成认证时传入null作为key,SWR会自动跳过请求 const { data, error } = useSWR( sessionStatus === 'authenticated' ? [ 'https://api.twitch.tv/helix/streams/key?broadcaster_id=630124067', session.accessToken, process.env.TWITCH_CLIENT_ID ] : null, fetcher ) // 优先处理session加载状态 if(sessionStatus === 'loading' || !data) return <div>loading...</div> if(error) return <div>Error {error.message}</div> return ( <VStack> <Text>{data.data.stream_key}</Text> </VStack> ) } export default Dash
SWR传递请求头的正确实现方式
SWR没有内置的请求头配置参数,所有请求相关的参数都可以通过useSWR的第一个参数(key数组)传递给fetcher,在fetcher内部组装headers即可:
- 单个请求配置:把当前请求需要的token、clientId等参数放到key数组中,数组内的所有参数会按顺序传入fetcher。
- 全局通用配置:如果多个请求都需要携带相同的headers,可以封装全局axios实例,在实例上配置默认headers,所有fetcher复用该实例发起请求即可,无需每个请求单独传参。
示例全局封装:
// 全局封装带公共配置的axios实例 const twitchAxios = axios.create({ baseURL: 'https://api.twitch.tv/helix', headers: { 'Client-Id': process.env.TWITCH_CLIENT_ID } }) // 复用实例的fetcher,无需每次传Client-Id const fetcher = (url, accessToken) => { return twitchAxios.get(url, { headers: { Authorization: `Bearer ${accessToken}` } }).then(res => res.data) }
内容的提问来源于stack exchange,提问作者MatDoak
相关产品推荐
相关产品推荐

