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
相关产品推荐
相关产品推荐

