使用Express构建对接SeaweedFS的API时出现异常文件传输问题
问题根因
- 二进制文件处理错误导致体积变大:你在
seaweedfs.js中直接将二进制响应数据作为字符串拼接,初始data变量未赋值默认是undefined,拼接时会将undefined转为字符串混入内容,同时二进制Buffer转UTF-8字符串会出现不可逆的编码损坏,最终导致文件体积变大、内容损坏。 - MIME类型异常:Express返回响应时未显式设置
Content-Type响应头,浏览器无法识别文件类型,默认使用通用二进制类型application/octet-stream。 - Hoppscotch无法请求:如果是使用网页版Hoppscotch请求本地服务,会触发跨域限制,同时需要确认你的Express服务已正常启动、端口对外开放、防火墙未拦截对应端口。
修复代码
1. 修复 /drivers/seaweedfs.js
// /drivers/seaweedfs.js Defines how API interacts with SeaweedFS const http = require("http"); module.exports = class Weed { constructor(mserver) { this.mserver = new URL(mserver); } get(fileId) { return new Promise((resolve, reject) => { let options = { hostname: this.mserver.hostname, port: this.mserver.port, method: "GET", path: `/${fileId}`, timeout: 6000, }; // 用数组存储二进制块,避免字符串拼接导致的编码损坏 const chunks = []; const fileReq = http.request(options, (res) => { console.log(`Statuscode ${res.statusCode}`); res.on("data", (chunk) => { chunks.push(chunk); }); res.on("end", () => { // 合并二进制块,同时返回SeaweedFS返回的响应头供上层使用 resolve({ data: Buffer.concat(chunks), headers: res.headers }); }); }); fileReq.on("error", (error) => { console.error(error); reject(error); }); fileReq.end(); }); } };
2. 修复 /routes/file.js
// /routes/file.js An Express router const express = require("express"); const router = express.Router(); const Weed = require("../drivers/seaweedfs"); let weedClient = new Weed("http://localhost:60002"); router.get("/:fileId", (req, res) => { weedClient.get(req.params.fileId) .then(result=>{ // 透传SeaweedFS返回的内容类型、内容长度头 if (result.headers['content-type']) { res.set('Content-Type', result.headers['content-type']); } if (result.headers['content-length']) { res.set('Content-Length', result.headers['content-length']); } res.send(result.data); }) .catch(err => { res.status(500).send('文件读取失败'); }) } ) module.exports = router;
额外排查项
如果Hoppscotch仍然无法请求,可先在本地执行curl http://<你的服务地址>:<端口>/<测试文件ID>验证服务是否正常,如需支持网页端跨域请求可在Express中引入cors中间件处理跨域。
内容的提问来源于stack exchange,提问作者PolarBear1310
相关产品推荐
相关产品推荐

