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

基于Node.js使用Multer与Ajax实现多图片上传的技术问询

解决Node.js结合Multer与Ajax多图片上传问题

我来帮你搞定这个多图上传的需求,结合你现有的Ajax代码和Multer其实很清晰,核心是把cropper生成的Base64数据转成Multer能处理的文件格式,下面分前端和后端两部分逐步实现:

一、修改前端Ajax代码(Base64转FormData)

首先,你需要一个工具函数把Base64字符串转成Blob对象——因为Multer无法直接处理Base64,只能识别multipart/form-data格式的文件流:

// Base64转Blob工具函数
function base64ToBlob(base64Data, contentType = 'image/png') {
  const byteString = atob(base64Data.split(',')[1]);
  const arrayBuffer = new ArrayBuffer(byteString.length);
  const uint8Array = new Uint8Array(arrayBuffer);
  
  for (let i = 0; i < byteString.length; i++) {
    uint8Array[i] = byteString.charCodeAt(i);
  }
  
  return new Blob([uint8Array], { type: contentType });
}

然后修改你的点击事件处理代码,把Base64数组转成Blob后放入FormData,再通过Ajax发送:

$('.gogo').on('touchstart mousedown', function(e){
    e.preventDefault();
    e.stopPropagation();
    
    // 获取两个裁剪后的Base64数据
    const base64Imgs = [fetchCrop1(), fetchCrop2()];
    const formData = new FormData();
    
    // 把每个Base64转成Blob,添加到FormData中
    base64Imgs.forEach((base64, index) => {
      const blob = base64ToBlob(base64);
      // 用`images[]`作为字段名,方便后端接收数组
      formData.append('images[]', blob, `crop-image-${index + 1}.png`);
    });

    $.ajax({
        cache: false,
        type : 'POST',
        url : 'http://localhost:3001/img',
        data: formData, // 发送FormData而不是普通数组
        processData: false, // 必须设为false,避免jQuery处理FormData
        // 不需要手动设置contentType,FormData会自动生成正确的请求头
        success : function(data) {
            console.log('AJAX: '+data);
        },
        error: function(err) {
            console.error('上传失败:', err);
        }
    });
});

二、配置后端Multer实现多文件接收

接下来配置你的Node.js后端,用Multer处理多文件上传:

首先确保已经安装了Multer:

npm install multer --save

然后编写后端代码(比如app.js或者单独的路由文件):

const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const app = express();

// 配置Multer存储路径和文件名
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    // 确保uploads目录存在,不存在则自动创建
    const uploadDir = path.join(__dirname, 'uploads');
    fs.mkdirSync(uploadDir, { recursive: true });
    cb(null, uploadDir);
  },
  filename: function (req, file, cb) {
    // 自定义文件名,避免重名冲突
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, `${uniqueSuffix}-${file.originalname}`);
  }
});

// 创建Multer中间件,接收名为`images[]`的文件数组,最多允许2个文件
const upload = multer({ storage: storage }).array('images[]', 2);

// 处理上传的路由
app.post('/img', (req, res) => {
  upload(req, res, function (err) {
    if (err instanceof multer.MulterError) {
      // 上传参数错误(比如文件数量超过限制)
      return res.status(400).json({ error: err.message });
    } else if (err) {
      // 其他未知错误
      return res.status(500).json({ error: '上传失败,请重试' });
    }
    // 上传成功,返回文件信息
    res.json({
      message: '多图片上传成功',
      files: req.files.map(file => ({
        filename: file.filename,
        savePath: file.path
      }))
    });
  });
});

// 启动服务器
app.listen(3001, () => {
  console.log('服务器运行在http://localhost:3001');
});

关键注意点

  • 前端必须把Base64转成Blob/File对象并放入FormData,这是Multer能识别的唯一格式;
  • 后端用multer().array('字段名', 最大数量)接收多文件,字段名要和前端FormData的append字段严格一致;
  • 确保后端的上传目录存在,上面的代码用mkdirSync({ recursive: true })自动创建目录,避免报错;
  • Ajax中不要手动设置contentType: false,FormData会自动生成multipart/form-data; boundary=xxx的正确请求头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:27:03