在第二个axios api调用上获取错误400错误的请求

时间:2019-10-17 20:02:35

标签: javascript reactjs axios

我正在尝试使用Axios从API获取数据。我有两个API调用。第一次调用运行良好,我得到了我期望的数据。但是,第二个错误请求返回400错误。

我已经搜索了多个论坛以尝试找到解决方案,但是我不太理解所找到的代码。

    const [player, setPlayer] = useState([]);
    const [newPlayer, setNewPlayer] = useState([]);

    const FindLoadout = async () => {
        await axios.get(`http://api.paladins.com/paladinsapi.svc/getmatchidsbyqueueJson/${devId}/${generateSignature('getmatchidsbyqueue')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/428/${moment.utc().format('YYYYMMDD')}/-1,00`).then((response) => {
                const playerData = response.data;
                playerData.map((el) => {
                    player.push(el.Match)
                })
                console.log(player);
                for(let i = 0; i < 50; i++) {
                    newPlayer.push(player[i]);
                }
                console.log(newPlayer);
            }).catch((error) => {
                console.log(error);
            });
            axios.get(`http://api.paladins.com/paladinsapi.svc/getmatchdetailsbatchJson/${devId}/${generateSignature('getmatchdetailsbatch')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/${newPlayer.join(",")}`).then((response) => {
                console.log(response);
            }).catch((error) => {
                console.log(error);
            });
    }

错误消息是:

  

错误:请求失败,状态码为400       在createError(createError.js:17)       在解决时(settle.js:19)       在XMLHttpRequest.handleLoad(xhr.js:60)

3 个答案:

答案 0 :(得分:2)

我不知道它是否能完全解决您的问题,但是在使用async / await进行数据提取时,通常的做法是这样做:

const FindLoadout = async () => {

  const playerData= await axios
    .get(`http://api.paladins.com/player/154`)
    .then(response => response.data);

  const gameData= await axios
    .get(`http://api.paladins.com/game/788`)
    .then(response => response.data);

  return {player: playerData, game: gamedata}
}

也就是说,您将通过API调用获取的数据分配给,然后返回从变量中获得所需的数据(在您认为适当的任何操作之后)必要)。

以这种同步语法编写异步代码的能力是async / await最具吸引力的特征之一。

我怀疑您收到的错误是因为您的第二个呼叫在触发之前没有await关键字。

编辑:同样,正如其他人所说,您肯定会因错误使用钩子而遇到问题,但这不是问题的范围。

答案 1 :(得分:0)

首先,您将异步和传统的承诺混在一起

[编辑:您还直接在改变状态,而不是使用setState]

[EDIT2:为此,状态不是立即设置的,在setState之后直接生成状态的控制台日志(以及axios get请求依赖于状态值)通常不会记录您期望的值,因此应将其包含在回调中传递给setState的函数-或-在状态确实更新时利用useEffect]

[EDIT3:在循环外建立新状态,然后在setState之后建立

const [player, setPlayer] = useState([]);
const [newPlayer, setNewPlayer] = useState([]);
const FindLoadout = async () => {
    useEffect(()=>{
        if (!player.length) return
        const newState = [...newPlayer]
        for(let i = 0; i < 50; i++) {
            newState.push(player[i]);
        }
        setNewPlayer(newState)
    }, [player]);
    useEffect(() => {
        if (!newPlayer.length) return 
         axios
            .get(`http://api.paladins.com/paladinsapi.svc/getmatchdetailsbatchJson/${devId}/${generateSignature('getmatchdetailsbatch')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/${newPlayer.join(",")}`)
            .then((gameData)=>{
                console.log(gameData)
            }).catch((error)=>{
                console.error(error)
            })
    }, [newPlayer]);
    try {
        const playerData= await axios.get(`http://api.paladins.com/paladinsapi.svc/getmatchidsbyqueueJson/${devId}/${generateSignature('getmatchidsbyqueue')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/428/${moment.utc().format('YYYYMMDD')}/-1,00`)
        const newState = [...player]
        playerData.map((el) => newState.push(el.Match))
        setPlayer(newState)
    }catch(error) {
        console.error(error);
    } 
}

如果您想继续使用asyc作为第二个useEffect,还可以改用回调: https://dev.to/n1ru4l/homebrew-react-hooks-useasynceffect-or-how-to-handle-async-operations-with-useeffect-1fa8

useEffect(() => {
        if (!newPlayer.length) return
        const myCallback = async ()=>{
            try{
                const gameData = await axios.get(`http://api.paladins.com/paladinsapi.svc/getmatchdetailsbatchJson/${devId}/${generateSignature('getmatchdetailsbatch')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/${newPlayer.join(",")}`)
                console.log(gameData)
            }catch(error){
                console.error(error)
            }
        }
        myCallback()
}, [newPlayer]);

如果这样不能解决问题,

  

400 Bad Request错误是HTTP状态代码,表示   您发送到网站服务器的请求某种程度上不正确或已损坏,服务器无法理解。

ie:您的URL对于API调用不正确,我将再次检查“ generateSignature”函数是否返回正确的值。如果是这种情况,我将检查以确保newPlayer.join(“,”)返回正确的值。

答案 2 :(得分:0)

我认为问题在于您如何为 playernewPlayer 赋值。由于您使用的是 useState 钩子,因此您应该使用 setPlayersetNewPlayer

你能告诉我在第二次 api 调用之前 newPlayer 的值是多少吗?

也许你可以这样更新:

const FindLoadout = async () => {
        await axios.get(`http://api.paladins.com/paladinsapi.svc/getmatchidsbyqueueJson/${devId}/${generateSignature('getmatchidsbyqueue')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/428/${moment.utc().format('YYYYMMDD')}/-1,00`).then((response) => {
                const playerData = response.data;
                //playerData.map((el) => {
                //    player.push(el.Match)
                //})
                setPlayer(playerData.map(el) => el.Match);
                console.log(player);
                //for(let i = 0; i < 50; i++) {
                //    newPlayer.push(player[i]);
                //}
                // I'm not sure how to update this assignment
                console.log(newPlayer);
            }).catch((error) => {
                console.log(error);
            });
            axios.get(`http://api.paladins.com/paladinsapi.svc/getmatchdetailsbatchJson/${devId}/${generateSignature('getmatchdetailsbatch')}/${props.sess}/${moment.utc().format('YYYYMMDDHHmmss')}/${newPlayer.join(",")}`).then((response) => {
                console.log(response);
            }).catch((error) => {
                console.log(error);
            });
    }

关于更新 newPlayer:由于状态是异步更新的,当您尝试使用 newPlayer 中的值更新 player 时,player 中没有任何内容。< /p>

尝试使用一些硬编码值发出请求,以查看问题是出在 api 请求上还是出在变量中的值上。