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

Axios自定义请求函数返回数据异常:projects字段为空问题排查

问题排查:自定义Axios封装函数返回projects为空数组,直接调用Axios正常

问题背景

基于Axios封装的makeApiRequest函数在多数场景下运行正常,但调用某接口时,返回的projects字段为空数组;而直接调用Axios发起相同请求,却能获取到非空的projects数据。

相关代码上下文如下:

自定义API函数代码

import axios, { AxiosRequestConfig } from 'axios';

const baseUrl = import.meta.env.VITE_BASE_URL;
export type METHODS = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';

export async function makeApiRequest(
  url: string,
  method: METHODS,
  body?: object,
  token?: string
) {
  const headers: HeadersInit = {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  };

  if (token) {
    headers.Authorization = `Bearer ${token}`;
  }

  const options: AxiosRequestConfig = {
    method,
    headers,
    baseURL: baseUrl,
    url,
    data: body,
  };

  return axios(options)
    .then((res) => res.data)
    .catch((error) => {
      throw error.response;
    });
}

请求调用示例

if (auth.token) {
  // 直接使用axios
  axios 
    .get('http://localhost:8080/api/v1/admin', {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${auth.token}`,
      },
    })
    .then((res) => console.log('axios-res', res))
    .catch(console.log);

  // 使用自定义函数
  makeApiRequest('/v1/admin', 'GET', {}, auth.token)
    .then((res) => {
      if (res) console.log('custom-res', res);
    })
    .catch((error) => throw error);
}

后端控制器代码

import * as express from 'express'
import models from '@/v1/models/';

const { Admin, Project, RetrievedMedia: media } = models;

const adminDetailsController = async (req: express.Request, res: express.Response, next: express.NextFunction) => {
  try {
    const { jwt: { id } } = req.body;
    
    const admin = await Admin.findOne({
      where: { id },
      include: [
        { model: Project, as: 'projects' },
        { model: media, as: 'avatar' },
        { model: media, as: 'resume' },
      ],
    });
    if (!admin) {
      return res.status(404).send({ success: false, message: 'No user found' });
    }
    
    res.status(200).send({
      success: true,
      message: 'Admin details retrived',
      data: {
        admin,
        projects: admin.projects,
      },
    });
  } catch (error) {
    next(error);
  }
};

export default adminDetailsController 

排查步骤及解决方案

1. 验证请求URL是否匹配

对比两种调用方式的最终请求URL:

  • 直接Axios调用的完整URL:http://localhost:8080/api/v1/admin
  • 自定义函数的完整URL:baseUrl + '/v1/admin'

检查import.meta.env.VITE_BASE_URL的值是否为http://localhost:8080/api。如果baseUrl仅为http://localhost:8080,则自定义函数的请求URL会变成http://localhost:8080/v1/admin,与目标接口/api/v1/admin不符,导致请求到错误端点,返回空数据。

验证方式:在浏览器开发者工具的Network面板中,查看两种请求的完整URL是否一致。

2. 修复GET请求的body参数问题

自定义函数在GET请求时传递了空对象{}作为body,并赋值给Axios配置的data字段。根据HTTP规范,GET请求不应携带请求体,且部分后端框架(如Express)在接收到带body的GET请求时,会解析并覆盖req.body的原有数据。

后端控制器从req.body.jwt.id获取管理员ID,若JWT认证中间件原本会将用户信息写入req.body.jwt,但自定义函数发送的空body会被express.json()中间件解析为{},覆盖原有req.body数据,导致req.body.jwt不存在,查询到的管理员ID异常,最终返回空的projects。

修复方式:修改自定义函数,仅在非GET请求时设置data字段:

const options: AxiosRequestConfig = {
  method,
  headers,
  baseURL: baseUrl,
  url,
  // 仅非GET请求携带data
  ...(method !== 'GET' && { data: body }),
};

或在调用自定义函数时,GET请求不传body参数:

makeApiRequest('/v1/admin', 'GET', undefined, auth.token)

3. 确认请求头完全一致

在Network面板中对比两种请求的请求头,确保Authorization(token格式是否正确,如Bearer后是否有空格)、Content-Type等字段完全一致,避免因请求头差异导致后端处理逻辑不同。

4. 调试后端查询逻辑

临时在后端控制器中添加日志,打印两种请求下的req.body和查询到的admin.id:

console.log('req.body:', req.body);
console.log('查询到的管理员ID:', admin?.id);

通过日志确认自定义函数请求时的管理员ID是否与直接Axios请求时一致,进一步定位数据查询问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:29:55