为什么请求头管理在React里很重要
你在写一个React做的后台管理系统,用户登录后要拉取个人数据。这时候每个请求都得带上token,不然接口直接返回401。手动给每个fetch加headers?写两次就烦了。更别说还有Content-Type、Accept这些通用设置。
实际开发中,很多人一开始图省事,在useEffect里直接fetch,结果越往后越乱。不同组件重复设置header,token更新了老的还留着,调试起来头疼。
用Axios拦截器统一处理
Axios是React项目里最常用的HTTP工具之一。它的拦截器机制特别适合做请求头的集中管理。
const apiClient = axios.create({
baseURL: 'https://api.example.com',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
// 请求拦截器
apiClient.interceptors.request.use(
(config) => {
const token = localStorage.getItem('authToken');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);这样配置完,以后所有通过apiClient发出去的请求,自动带上token和基础header。你再也不用在每个API调用里重复写了。
结合React状态动态更新请求头
有时候token不是一开始就有的,用户登录才生成。这时候你可以配合React的context或者自定义hook来刷新拦截器行为。
比如你有个useAuth的hook管理登录状态,登录成功后把token存localStorage,同时可以触发一次全局的“请求头刷新”。虽然拦截器本身不会监听state变化,但localStorage的变化对下一次请求是可见的。
function useLogin() {
const login = async (credentials) => {
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify(credentials)
});
const data = await response.json();
// 存token
localStorage.setItem('authToken', data.token);
// 下次apiClient请求会自动带上新token
};
return { login };
}自定义Hook封装API调用
如果你不想用第三方库,也可以用原生fetch + 自定义hook来实现类似效果。
function useApi() {
const request = async (url, options = {}) => {
const defaultHeaders = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('authToken')}`
};
const config = {
...options,
headers: {
...defaultHeaders,
...options.headers
}
};
const response = await fetch(url, config);
if (!response.ok) throw new Error(response.statusText);
return response.json();
};
return { request };
}然后在组件里:
function UserProfile() {
const { request } = useApi();
useEffect(() => {
request('/user/profile').then(data => {
console.log(data);
});
}, [request]);
return <div>加载用户信息</div>;
}这种方式把请求头逻辑收拢到一个地方,后期改起来也方便。比如公司换了鉴权方式,从Bearer换成Custom-Token,只改useApi就行,不用翻十几个文件。
避免常见坑
有些团队喜欢在每个API函数里手动拼headers,看着灵活,其实埋雷。一个人改了格式,别人不知道,接口就开始报错。
另一个问题是跨域时预检请求(OPTIONS)失败。记得后端要允许你自定义的header字段,比如Authorization、X-Tenant-Id这类,不然浏览器直接拦掉,前端根本拿不到错误原因。
最后提醒一句,敏感信息别往header里乱塞。曾经有项目把完整用户信息编码后塞进请求头传,既浪费带宽又不安全。token够用了,别画蛇添足。