You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React页面刷新后Pet-finder API请求无法获取Access Token问题

问题

使用Pet-finder API开发React应用,将Access Token存储在Context中。特定动物页面首次渲染大多正常,但刷新页面时会抛出Axios 401错误(API文档标注为“Access was denied due to invalid credentials”),请求头中Authorization字段显示为“undefined undefined”。尝试将token添加到请求所用useEffect的依赖数组中,虽能成功加载数据,但刷新时控制台仍会报错。当前仅该页面会在渲染后立即发起请求,怀疑此场景与问题相关。

相关代码:

TokenContext.jsx

const TokenContext = createContext();

export const TokenProvider = ({ children }) => {
  const [token, setToken] = useState({});
  let location = useLocation();

  const fetchToken = async () => {
    await axios
      .get("http://localhost:3001/fetchToken")
      .then((res) => {
        const newToken = {
          token: res.data.access_token,
          tokenType: res.data.token_type,
          expires: new Date().getTime() + res.data.expires_in * 1000,
        };

        localStorage.setItem("token", JSON.stringify(newToken));
      })
      .catch((error) => {
        console.log(error);
      });
  };

  useEffect(() => {
    const foundToken = JSON.parse(localStorage.getItem("token"));

    if (!foundToken || token.expires - new Date().getTime() < 10) {
      fetchToken();
    } else {
      setToken(foundToken);
    }
  }, [location.pathname]);

  return (
    <TokenContext.Provider value={{ token }}>{children}</TokenContext.Provider>
  );
};

export default TokenContext;

Pet.jsx

const Pet = () => {
  const { id } = useParams();
  const { token } = useContext(TokenContext);
  const [isLoading, setIsLoading] = useState(false);
  const [pet, setPet] = useState({});

  useEffect(() => {
    setIsLoading(true);

    petFinderApi
      .get(`/animals/${id}`, {
        headers: {
          Authorization: `${token.tokenType} ${token.token}`,
        },
      })
      .then((res) => {
        setPet(res.data.animal);
        setIsLoading(false);
      })
      .catch((error) => {
        console.log(error);
      });
  }, [token]);

  if (!pet) {
    return (
      isLoading ?? (
        //Spinner renders here
      )
    );
  } else {
    return (
//Stuff will render here
)
  }
};

export default Pet;
问题分析
  1. Token初始化时机问题:刷新页面时,Context中的token初始值为空对象{},Pet组件会立即发起请求,导致token.tokenType和token.token均为undefined,Authorization头无效,触发401错误。
  2. fetchToken未同步Context状态:fetchToken仅将token存入localStorage,未调用setToken更新Context状态,导致新token获取后,Context无法同步,后续请求仍可能使用空值。
  3. 有效期判断逻辑异常:初始token为空对象,token.expires为undefined,判断token.expires - new Date().getTime() <10时会产生NaN,导致逻辑判断出错。
  4. 请求未做token有效性校验:Pet组件未判断token是否有效就发起请求,直接使用空token触发错误。
解决方案

1. 修复fetchToken函数,同步Context状态

在获取新token后,不仅存入localStorage,还要更新Context的token状态:

const fetchToken = async () => {
  try {
    const res = await axios.get("http://localhost:3001/fetchToken");
    const newToken = {
      token: res.data.access_token,
      tokenType: res.data.token_type,
      expires: new Date().getTime() + res.data.expires_in * 1000,
    };
    localStorage.setItem("token", JSON.stringify(newToken));
    setToken(newToken); // 同步到Context
  } catch (error) {
    console.log(error);
  }
};

2. 修正Token有效期判断逻辑

改用foundToken的有效期进行判断,避免使用初始空token的属性:

useEffect(() => {
  const foundToken = JSON.parse(localStorage.getItem("token"));
  const currentTime = new Date().getTime();
  if (!foundToken || (foundToken.expires - currentTime) < 10) {
    fetchToken();
  } else {
    setToken(foundToken);
  }
}, [location.pathname]);

3. Pet组件添加Token有效性校验

发起请求前先确认token是否有效,避免空token请求:

useEffect(() => {
  if (!token.tokenType || !token.token) return;

  setIsLoading(true);
  petFinderApi
    .get(`/animals/${id}`, {
      headers: {
        Authorization: `${token.tokenType} ${token.token}`,
      },
    })
    .then((res) => {
      setPet(res.data.animal);
      setIsLoading(false);
    })
    .catch((error) => {
      console.log(error);
      setIsLoading(false); // 出错后终止加载状态
    });
}, [token, id]);

4. 优化加载状态逻辑

修正加载状态判断,避免空值渲染问题:

if (isLoading) {
  return (
    // 渲染加载Spinner
  );
}

if (!Object.keys(pet).length) {
  return <div>暂无宠物信息</div>;
}

return (
  // 渲染宠物详情内容
);

内容的提问来源于stack exchange,提问作者CoffeeSlurper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:55:30