在 React Js 中收到授权令牌之前如何防止提取请求?

How prevent fetch request before auth token is received in React Js?

我有一个单独的获取请求功能,用于登录用户并将授权令牌保存到 localStorage,然后我的数据请求获取应该与保存的令牌持有者一起发送,但数据获取不等待令牌并接收未经授权的访问代码.

我的数据请求提取如下所示:


// to check for fetch err

function findErr(response) {
    try {
        if (response.status >= 200 && response.status <= 299) {
            return response.json();
        } else if (response.status === 401) {
            throw Error(response.statusText);
        } else if (!response.ok) {
            throw Error(response.statusText);
        } else {
            if (response.ok) {
                return response.data;
            }
        }
    } catch (error) {
        console.log("caught error: ", error);
    }
}



const token = JSON.parse(localStorage.getItem("token"));

// actual fetch request

export async function getData() {
    const url = `${URL}/data`;

    var obj = {
        method: "GET",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            Authorization: "Bearer " + `${token}`,
        },
    };

    const data = await fetch(url, obj)
        .then((response) => findErr(response))
    
        .then((result) => {
            return result.data;
        });

    return data;
}


我的获取请求在不同的 js 文件中,我将它们导入到我的组件中,如下所示:

import React, { useState, useEffect } from "react";


function getInfo() {

const [info, setInfo] = useState()

const importGetDataFunc = async () => {
        const data = await getData();

        setInfo(data);
    };

useEffect(() => {
        importGetDataFunc();
    
    }, []);
    return (
        <div>
            
        </div>
    )
}

export default getInfo


现在,当我在第一次获取请求 returns 401 登录后转到 getInfo 组件时,但是在我刷新页面后,获取请求与令牌承载一起进行,并且数据被返回。我的问题是我不知道如何让 getData() 获取请求等待它从 localStorage 获取令牌或在 401 代码上重试获取请求。我试图实现这样的 if 语句


useEffect(() => {

if(token){
        importGetDataFunc();
}
    }, []);

其中 useEffect 会检查令牌是否在 localStorage 中,然后才会触发提取请求,但它不起作用。非常感谢任何有关我如何处理此问题的帮助。

你很接近。您需要将 token 添加为 useEffect 的依赖项。此外,您需要将令牌获取逻辑移至组件中。

像这样的东西应该可以工作:

import React, { useState, useEffect } from "react";


function getInfo() {

const [info, setInfo] = useState()
const token = JSON.parse(localStorage.getItem("token"));

const importGetDataFunc = async () => {
        const data = await getData();

        setInfo(data);
    };

useEffect(() => {
        if(token) {
           importGetDataFunc(token);
        }
    
    }, [token]);

    return (
        <div>
            
        </div>
    )
}

export default getInfo

您还可以修改 importGetDataFunc 以接收令牌作为参数。

const importGetDataFunc = async (token) => {
        const data = await getData(token);

        setInfo(data);
    };
export async function getData(token) {
    const url = `${URL}/data`;

    var obj = {
        method: "GET",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            Authorization: "Bearer " + `${token}`,
        },
    };

    const data = await fetch(url, obj)
        .then((response) => findErr(response))
    
        .then((result) => {
            return result.data;
        });

    return data;
}

真正帮助我的是创建一个函数来检查 get fetch 请求中的令牌,如下所示:


export const findToken = () => {
    const token =localStorage.getItem("token") 

    return token;
};
export async function getData(token) {
    const url = `${URL}/data`;

    var obj = {
        method: "GET",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            Authorization: "Bearer " + `${findToken()}`,
        },
    };

    const data = await fetch(url, obj)
        .then((response) => findErr(response))
    
        .then((result) => {
            return result.data;
        });

    return data;
}