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

Python Requests的files参数对应Axios如何实现?请求失败排查

问题描述

我有一个通过POST端点上传文件的API,使用Python的requests库可成功实现上传,代码如下:

files = {
    'payload': (None, json.dumps(payload), 'application/json'),
    'file': (file_name, open(full_path, 'rb'), 'application/octet-stream')
}

r = requests.post(f'{url}upload/', files=files)

我需要使用JS的Axios发起完全相同的请求,但尝试了以下库均未成功:

  • form-data包
  • formdata-node包
  • axios-form-data包

使用axios-form-data包时,我的请求代码如下:

async uploadFile(form_data, file_part) {
  axios.interceptors.request.use(axiosFormData);
      return await axios.request({
        method: 'POST',
        url: `${url}upload/`,
        data: {
          payload: 'Non-file value',
          file: fs.readFileSync("test/helpers/resources/test.csv", "utf-8");
        }
      });
}

每次尝试后,API端点都能收到请求,但Flask后端的request.form对象为空。此外,我的package.json中设置了type: module,无法使用CommonJS包。

编辑:我将axios-form-data的函数修改为以下形式,仍未成功:

async uploadFile(form_data, file_path) {
  axios.interceptors.request.use(axiosFormData);
      return await axios.request({
        method: 'POST',
        url: `${url}upload/`,
        data: {
          payload: 'Non-file value',
          file: fs.createReadStream(file_path);
        }
      });
}

请问我发起请求时哪里出错了?


问题分析与解决

你的核心问题是没有正确模拟Python requests中files参数生成的多部分表单请求结构,尤其是payload字段的格式处理和文件流的正确传递。以下是具体修正步骤:

1. 正确使用FormData构造请求体

放弃axios-form-data拦截器,直接用formdata-node(支持ES模块)手动构造符合要求的FormData:

import { FormData } from 'formdata-node';
import fs from 'fs';
import axios from 'axios';

async function uploadFile(payload, file_path, file_name) {
  // 创建FormData实例
  const form = new FormData();

  // 模拟Python中payload的格式:无文件名,JSON内容,指定Content-Type为application/json
  form.append('payload', JSON.stringify(payload), {
    filename: undefined,
    contentType: 'application/json'
  });

  // 添加文件:指定文件名、读取流、Content-Type
  form.append('file', fs.createReadStream(file_path), {
    filename: file_name,
    contentType: 'application/octet-stream'
  });

  // 发起请求,传递FormData自动生成的请求头(含boundary)
  const response = await axios.post(`${url}upload/`, form, {
    headers: form.getHeaders()
  });

  return response;
}

2. 原代码错误点拆解

  • 未正确构造FormData结构:axios-form-data拦截器无法自动识别payload字段需要的特殊格式(指定Content-Type为application/json),导致后端无法解析到request.form。
  • 文件读取方式错误:fs.readFileSync用utf-8读取会把二进制文件转成文本,破坏文件结构;即使改用createReadStream,也需要在FormData中明确指定文件名和Content-Type,才能和Python请求对齐。
  • 请求头缺失:手动构造FormData时,必须通过form.getHeaders()获取包含multipart/form-data和boundary的请求头,否则后端无法正确解析表单。

3. 验证要点

调用时确保:

  • payload是你要传递的JSON对象,而非字符串(代码中会自动转成JSON字符串)
  • file_name和Python请求中使用的文件名一致
  • 已安装formdata-node:执行npm install formdata-node

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:25:09