Axios 承诺解决飞行前请求响应,这使得关联的 GET 与应用程序的其余部分无序执行

Posted

技术标签:

【中文标题】Axios 承诺解决飞行前请求响应,这使得关联的 GET 与应用程序的其余部分无序执行【英文标题】:Axios promise resolving on pre-flight request response which makes associated GET execute out of order with rest of app 【发布时间】:2020-04-25 04:19:02 【问题描述】:

早安,

我正在开发一个使用 React-Redux(带有 Thunk)和 Axios 的 React 应用程序。

我有一个我调度的操作,它进行了经过身份验证的 API 调用。由于我在跨域请求上有授权标头,因此有一个飞行前请求。

我遇到的问题是,一旦飞行前请求返回,而不是关联的 GET 请求返回时,Axios 似乎正在运行 .then() 代码。这会导致 Reducer 函数在 API GET 请求的结果返回之前更新状态。

我添加了一些 console.logs 来提供更多细节来说明问题。如您所见,飞行前请求是在第一个条目中发送的。 .then 执行一个飞行前请求返回 200 的操作。然后该操作触发,reducer 更新状态。我的应用程序通过重新渲染连接到 Redux 的容器来响应。子组件随后也会更新。然后 GET 请求完成并返回 200。此时没有进一步的事情发生,因为 reducer 已经在前面提到的 .then() 中更新了。

动作代码如下所示。我没有粘贴所有其他代码,因为有许多文件并且它们相对较大。如果需要,我也可以包括这些。

export const updatePlotDataInit = (datasetName, tableName, xFieldName, 
    yFieldName, chartId, chartType, plotId, newDomainStartDbIndex, newDomainEndDbIndex) => 
        console.log('[actions/plot.js.js] - [updatePlotDataInit] - [start of function]');
    return dispatch => 
        dispatch(updatePlotDataStart());
        console.log('[actions/plot.js.js] - [updatePlotDataInit] - [just before api request]');
        instance.get( // custom axios instance with extra auth header used here
            `/v1/datasets/$datasetName/tables/$tableName/fields/data?xField=$xFieldName&yField=$yFieldName&chartType=$chartType&domainStart=$newDomainStartDbIndex&domainEnd=$newDomainEndDbIndex`
            )
            .then(response => 
                console.log('[actions/plot.js.js] - [updatePlotDataInit] - [in .then before updatePlotDataSuccess]');
                // dispatch redux action for success case
                const currentLevel = response.data.metaData.current_level 
                const data = response.data.queryData.data //schema is available too
                //datasetId, tableId, xFieldId, xField, yFieldId, yField, chartId, plotIdVal, currentLevel, data
                dispatch( updatePlotDataSuccess( plotId, currentLevel, data ) );
                // console.log(response);
                console.log('[actions/plot.js.js] - [updatePlotDataInit] - [in .then after updatePlotDataSuccess]')
            )
            .catch(error => 
                console.log(error);

            // dispatch redux action for failure case
            dispatch(updatePlotDataFail(error));
            )
    
;

我不完全确定,但似乎 Axios 认为成功的飞行前响应适合解决 promsie,因此 .then 被执行。

看起来是这样吗?如果是这样,我将如何强制 Axios 在解决承诺之前等待 GET/POST/PUT/etc 成功?

感谢任何帮助。

【问题讨论】:

我想我也有同样的问题。你找到解决方案了吗? 我也遇到了这个补丁请求问题。 Promise 在预检响应上解决,但服务器仍在处理主请求。如何等待实际请求的结果? 【参考方案1】:

我知道这是很久以前的事了,但我认为它可能对那些发现这个问题与他们的问题相似但没有答案的其他人有用...

对我来说,这只是因为粗心的编码 :D, 这是我的响应接收器,我错过了 Promise.resolve(axios(originalRequest)); 之前的“return”。 我通过添加 return 解决了它:

AxiosInstance.interceptors.response.use(
    (response) => 
        return response;
    ,
    function (error) 
        const originalRequest = error.config;
        let refreshToken = localStorage.getItem("refreshToken");
        if (
            refreshToken &&
            error.response.status === 401 &&
            !originalRequest._retry
        ) 
            originalRequest._retry = true;
            return axios
                .post(apiUrl + `auth/refreshtoken`,  refreshToken: refreshToken )
                .then((res) =>             
                    if (res.status === 200) 
                        localStorage.setItem("accessToken", res.data.accessToken);
                        console.log("Access token refreshed!" + res.data.accessToken);       
                        originalRequest.headers.Authorization = 'Bearer ' + res.data.accessToken;
         //*************** I just return promise.resolve *****************//
                        return Promise.resolve(axios(originalRequest)); 
                    
                ).catch((error) => 
                    console.log(error);
                );

        
        return Promise.reject(error);
    

【讨论】:

以上是关于Axios 承诺解决飞行前请求响应,这使得关联的 GET 与应用程序的其余部分无序执行的主要内容,如果未能解决你的问题,请参考以下文章

不允许 Trustpilot API 飞行前

我们应该在发送响应时关闭飞行前 Cors 请求的连接吗?

返回嵌套承诺但未找到响应

axios post 请求挂在有效请求上

axios请求/响应拦截

axios请求/响应拦截