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

React中用mic-recorder-to-mp3录音后,无法通过Express+Multer保存至服务器目录

问题分析与解决方案

核心问题

前端传递给后端的是本地生成的Blob URL字符串而非实际音频文件,导致multer无法识别并存储。此外还有几处细节问题需要修正。

具体修复步骤

1. 前端(RecordAudio.js)修改

  • 保存原始Blob对象到状态:停止录制时,同时保存Blob URL和原始Blob对象。
  • 提交Blob文件而非URL:将Blob对象添加到FormData中传递给后端,而非Blob URL。
  • 添加错误处理逻辑:捕获请求失败场景,避免误提示上传成功。

修改后的关键代码片段:

// 构造函数中新增blob状态
constructor(props) {
  super(props);
  this.state = {
    isRecording: false,
    blobURL: "",
    isBlocked: false,
    blob: null // 存储原始音频Blob
  };
}

// 停止录制时保存Blob对象
stop = () => {
  Mp3Recorder.stop()
    .getMp3()
    .then(([buffer, blob]) => {
      const blobURL = URL.createObjectURL(blob);
      this.setState({ blobURL, isRecording: false, blob }); // 保存Blob到状态
    })
    .catch((e) => console.log(e));
};

// 修正保存方法
Save = (e) => {
  e.preventDefault();
  if (!this.state.blob) {
    alert("没有可保存的音频");
    return;
  }
  const url = "http://localhost:8000/record";
  const data = new FormData();
  // 传递Blob对象并指定文件名
  data.append("audio", this.state.blob, "recording.mp3");

  axios.post(url, data)
    .then((res) => {
      console.log("上传成功", res.data);
      alert("音频上传成功");
    })
    .catch((err) => {
      console.error("上传失败", err);
      alert("音频上传失败");
    });
};

2. 后端(server.js)修改

  • 自动创建uploads目录:避免因目录不存在导致multer存储失败。
  • 优化文件名处理:兼容文件原始名称无扩展名的情况,默认使用mp3格式。
  • 添加文件接收校验:确认multer成功接收文件后再返回成功响应。

修改后的关键代码片段:

const path = require("path");
const fs = require("fs");
const express = require("express");
const multer = require("multer");
const cors = require("cors");
const app = express();

app.use(cors());
app.use(express.static("uploads"));

// 确保uploads目录存在,不存在则创建
const uploadsDir = path.join(__dirname, "uploads");
if (!fs.existsSync(uploadsDir)) {
  fs.mkdirSync(uploadsDir, { recursive: true });
}

const storage = multer.diskStorage({
  destination(req, file, cb) {
    cb(null, uploadsDir); // 使用绝对路径更可靠
  },
  filename(req, file, cb) {
    // 处理扩展名,默认使用mp3
    let extension = "mp3";
    if (file.originalname && file.originalname.includes(".")) {
      extension = file.originalname.split(".").pop();
    }
    cb(null, `recording.${extension}`);
  },
});

const upload = multer({ storage });

app.post("/record", upload.single("audio"), (req, res) => {
  if (!req.file) {
    return res.status(400).json({ 
      success: false, 
      message: "未接收到音频文件" 
    });
  }
  res.json({ 
    success: true, 
    filePath: req.file.path,
    fileName: req.file.filename 
  });
});

app.listen(8000, () => {
  console.log("服务器运行在8000端口");
});

验证步骤

  1. 重启后端服务
  2. 录制音频后点击保存,检查uploads目录下是否生成音频文件
  3. 查看浏览器控制台和后端日志,确认无错误信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 06:31:05