React应用Service Layer创建后API异常:登录JWT格式错误刷新恢复
问题描述
在React应用中创建Service Layer后,Node.js API出现连接异常:登录时返回500内部服务器错误,提示jwt malformed,但刷新页面后可正常获取服务器响应。
项目文件夹结构
index.html └── src ├── Components │ ├── Pages │ │ ├── Home.jsx │ │ ├── Provider.jsx │ │ ├── login.jsx │ │ ├── signup.jsx │ │ ... │ ├── ProviderComponents │ │ ├── WorkListProvider.jsx │ │ ... ├── Context │ └── UserContext.jsx └── Services └── Api ├── authService.js ├── config │ └── axiosConfig.js └── providerService.js
相关代码
src/Services/Api/config/axiosConfig.js
import axios from "axios"; import Cookies from "js-cookie"; const token = Cookies.get("token"); // 创建axios实例 export const api = axios.create({ baseURL: import.meta.env.VITE_API_URL, headers: { Authorization : `Bearer ${token}` }, }); const errorHandler = (error) => { const statusCode = error.response?.status; if (statusCode && statusCode !== 401) { throw error } return Promise.reject(error); }; api.interceptors.response.use(undefined, (error) => { return errorHandler(error); });
src/Services/Api/providerService.js
import { api } from "./config/axiosConfig"; export const providerService = { getJobs: async () => { const response = await api.request({ url: "/provider/myJobs", method: "GET", }); return response.data; }, // 其他服务方法 }
src/Components/providerComponents/WorkListProvider.jsx(服务调用逻辑)
useEffect(() => { providerService .getJobs() .then((workList) => { setWorkData(workList); }) .catch((error) => { console.error(error); }); }, []);
src/Services/Api/authService.js
import { api } from "./config/axiosConfig"; export const authService = { login: async (data) => { const response = await api.request({ url: `/login`, data, method: "POST", }); console.log(response.data) return response.data; }, // 其他服务方法 };
src/Components/Pages/login.jsx(登录逻辑)
const handleSubmit = (e) => { e.preventDefault(); authService .login(values) .then((response) => { Cookies.set("token", response.token, { expires: 1 }); changeLoggedIn(true); navigate("/"); }) .catch((error) => setErrorMessage(error.response.data.data.error)); };
问题原因及修复
核心原因
axios实例创建时,直接将Cookies.get("token")赋值给Authorization头。此时用户尚未登录,token不存在,导致请求头中出现Bearer undefined,后端解析JWT时触发jwt malformed错误。刷新页面后,cookie已存在,token被正确读取,请求恢复正常。
修复方案
方案1:用请求拦截器动态注入token(推荐)
修改axiosConfig.js,移除实例初始化时的Authorization配置,添加请求拦截器,每次请求前动态获取并注入token:
import axios from "axios"; import Cookies from "js-cookie"; // 创建axios实例,不预设Authorization头 export const api = axios.create({ baseURL: import.meta.env.VITE_API_URL, }); // 请求拦截器:每次请求前自动添加token(如果存在) api.interceptors.request.use( (config) => { const token = Cookies.get("token"); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => Promise.reject(error) ); const errorHandler = (error) => { const statusCode = error.response?.status; if (statusCode && statusCode !== 401) { throw error; } return Promise.reject(error); }; api.interceptors.response.use(undefined, errorHandler);
方案2:登录成功后手动更新axios默认头
修改login.jsx的登录成功逻辑,手动更新axios实例的默认Authorization头:
const handleSubmit = (e) => { e.preventDefault(); authService .login(values) .then((response) => { const token = response.token; Cookies.set("token", token, { expires: 1 }); // 更新axios实例的默认授权头 api.defaults.headers.common.Authorization = `Bearer ${token}`; changeLoggedIn(true); navigate("/"); }) .catch((error) => setErrorMessage(error.response.data.data.error)); };
内容的提问来源于stack exchange,提问作者Nestor Gonzalez
相关产品推荐
相关产品推荐

