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

Express框架下异步上传图片至服务器的简易实现方案咨询

用XMLHttpRequest + FormData 高效上传Blob到Express服务器

嘿,我完全懂你之前用base64的痛点——编码解码慢还麻烦,其实直接用FormData配合XMLHttpRequest发送二进制文件才是更高效的方案,不用折腾编码,服务器端处理也简单。咱们分前端和后端两部分来实现:

前端代码(XHR发送Blob)

假设你已经拿到了要上传的uploadBlob对象,还有对应的文件名(比如从<input type="file">的File对象里获取,或者你自己定义),可以这么写:

// 假设你已经有了要上传的Blob和文件名
const uploadBlob = /* 你的Blob对象 */;
const fileName = "example.jpg"; // 替换成实际的文件名,包括扩展名

// 创建FormData对象,用来包装文件数据
const formData = new FormData();
// 把Blob添加到FormData,第二个参数是文件名,服务器端能直接拿到这个名字
formData.append("file", uploadBlob, fileName);

// 创建XMLHttpRequest对象
const xhr = new XMLHttpRequest();

// 设置请求方法和服务器地址
xhr.open("POST", "/api/upload", true);

// 监听上传进度(可选,用来做进度条)
xhr.upload.addEventListener("progress", (e) => {
  if (e.lengthComputable) {
    const percent = (e.loaded / e.total) * 100;
    console.log(`上传进度:${percent.toFixed(2)}%`);
  }
});

// 监听请求完成
xhr.addEventListener("load", () => {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log("上传成功!", xhr.responseText);
  } else {
    console.error("上传失败", xhr.statusText);
  }
});

// 监听错误
xhr.addEventListener("error", () => {
  console.error("网络错误,上传失败");
});

// 发送请求
xhr.send(formData);

这个方式直接传递二进制数据,没有base64的额外体积开销(base64会让文件体积膨胀约30%),速度快很多,而且文件名直接跟着FormData一起发送,服务器端能直接获取。

后端代码(Express处理上传)

Express这边推荐用multer中间件来处理文件上传,它能帮你自动解析FormData里的文件,直接保存到指定目录,不用自己处理二进制数据。

步骤1:安装multer

首先在你的Express项目里安装multer:

npm install multer --save

步骤2:配置multer并写路由

const express = require("express");
const multer = require("multer");
const app = express();

// 配置multer的存储路径和文件名规则
const storage = multer.diskStorage({
  // 设置文件保存的目录,注意这个目录要提前创建好
  destination: (req, file, cb) => {
    cb(null, "./uploads"); // 比如项目根目录下的uploads文件夹
  },
  // 设置保存的文件名,这里用原文件名,你也可以自定义(比如加时间戳避免重名)
  filename: (req, file, cb) => {
    cb(null, file.originalname); // file.originalname就是前端传过来的文件名
  }
});

// 创建multer实例
const upload = multer({ storage: storage });

// 处理上传的路由,upload.single("file")对应前端FormData里的"file"字段
app.post("/api/upload", upload.single("file"), (req, res) => {
  // req.file就是上传的文件信息
  if (!req.file) {
    return res.status(400).json({ message: "没有上传文件" });
  }
  // 这里可以做一些额外的处理,比如记录数据库等
  res.status(200).json({
    message: "文件上传成功",
    filePath: `/uploads/${req.file.filename}`
  });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在端口${PORT}`);
});

额外配置(可选)

如果需要限制文件大小、类型,可以在multer配置里加limits和fileFilter参数,比如:

const upload = multer({
  storage: storage,
  limits: { fileSize: 5 * 1024 * 1024 }, // 限制5MB
  fileFilter: (req, file, cb) => {
    // 只允许图片类型
    const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
    if (allowedTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error("只允许上传图片文件"));
    }
  }
});

这个方案比base64高效太多,前端不用编码,后端不用解码,直接处理原生二进制文件,完美解决你之前的痛点!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:27:31