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

React客户端向Python Flask服务器上传CSV文件:实现文件存储与读取的技术问询

需求完全可行,以下是具体实现方案

问题根源分析

你当前遇到的问题是因为前端直接把File数组传给FormData.append(),此时浏览器会自动调用数组的toString()方法,把每个File对象转换成[object File]字符串,导致后端拿到的只是一串文本而非实际文件对象。我们需要调整前后端的文件传递和接收逻辑。


前端代码修改(React)

需要循环遍历File数组,逐个将文件添加到FormData中,保持同一个键名(比如arrFile),这样后端可以批量获取所有文件:

export const sendFiles = async (files) => {
  let form = new FormData();
  // 循环添加每个文件到FormData
  files.forEach(file => {
    form.append("arrFile", file);
  });
  
  try {
    const res = await axios.post(local + "/read-files", form, {
      // 这里可以不用手动设置Content-Type,axios会自动根据FormData生成正确的头部
      // headers: { "Content-Type": "multipart/form-data" },
    });
    return res.data;
  } catch (err) {
    console.error("文件上传失败:", err);
    return err;
  }
};

注意:不需要手动设置Content-Type,axios会自动为FormData类型的请求添加正确的multipart/form-data头部,还会自动生成边界符(boundary),手动设置反而可能导致请求格式错误。


后端代码修改(Flask)

Flask中上传的文件会被存放在request.files对象中,而非request.form。我们需要通过getlist()方法获取所有同名的文件,然后将它们保存到服务器指定目录:

import os
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/read-files", methods=['POST'])
def read_files():
    if request.method == 'POST':
        # 获取所有上传的文件列表
        uploaded_files = request.files.getlist("arrFile")
        
        # 定义服务器上的文件保存目录(比如项目根目录下的uploads文件夹)
        upload_dir = os.path.join(os.getcwd(), "uploads")
        # 如果目录不存在,自动创建
        if not os.path.exists(upload_dir):
            os.makedirs(upload_dir)
        
        saved_files_info = []
        for file in uploaded_files:
            # 验证文件是否为CSV格式(可选,但建议做校验)
            if file and file.filename.endswith('.csv'):
                # 构建文件保存路径
                save_path = os.path.join(upload_dir, file.filename)
                # 保存文件到服务器
                file.save(save_path)
                # 记录保存成功的文件信息
                saved_files_info.append({
                    "filename": file.filename,
                    "save_path": save_path,
                    "size": file.content_length
                })
        
        # 返回保存结果给前端
        return jsonify({
            "status": "success",
            "message": f"成功保存{len(saved_files_info)}个CSV文件",
            "saved_files": saved_files_info
        })
    return jsonify({"status": "error", "message": "仅支持POST请求"})

后续读取文件的实现思路

保存文件后,你可以通过以下方式实现后续读取:

  • 接口读取:新增一个Flask接口,接收文件名参数,从uploads目录读取对应CSV文件的内容,解析后返回给前端(比如转成JSON格式)。
  • 静态文件访问:将uploads目录配置为Flask的静态目录,前端可以直接通过URL访问文件(比如http://your-server/uploads/filename.csv)。

示例接口(读取CSV内容):

import csv
from flask import send_file

@app.route("/get-csv/<filename>", methods=['GET'])
def get_csv(filename):
    file_path = os.path.join(os.getcwd(), "uploads", filename)
    if os.path.exists(file_path) and filename.endswith('.csv'):
        # 方式1:返回原始CSV文件
        # return send_file(file_path, mimetype='text/csv')
        
        # 方式2:解析CSV为JSON返回
        csv_data = []
        with open(file_path, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                csv_data.append(row)
        return jsonify({"status": "success", "data": csv_data})
    return jsonify({"status": "error", "message": "文件不存在或格式错误"})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:02:28