
multer 默认对非 ascii 文件名(如希腊字母)解析错误,导致乱码;本文提供在 diskstorage.filename 中通过 buffer 转换 latin1 → utf-8 的标准解决方案,并附完整可运行代码与关键注意事项。
multer 默认对非 ascii 文件名(如希腊字母)解析错误,导致乱码;本文提供在 diskstorage.filename 中通过 buffer 转换 latin1 → utf-8 的标准解决方案,并附完整可运行代码与关键注意事项。
在使用 Multer 处理文件上传时,若客户端(尤其是某些浏览器或旧版系统)以 ISO-8859-7(Greek)或 Windows-1253 编码发送含希腊字符的文件名(如 Αθήνα.mp3),而服务器默认按 Latin-1(ISO-8859-1)解码 file.originalname,就会出现类似 Î Ïξ Îαξ 的乱码。根本原因在于:HTTP 表单未声明字符集,Node.js 将原始字节流误判为 Latin-1,而非 UTF-8。
正确解法是在 filename 回调中主动进行编码转换,而非在路由逻辑里后置修正(易出错且不可靠)。核心思路是:将 file.originalname 视为 Latin-1 编码的字节序列,用 Buffer.from(..., 'latin1') 还原原始字节,再以 UTF-8 解码为正确字符串:
const multer = require('multer');
const path = require('path');
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, './uploads');
},
filename: (req, file, callback) => {
// ✅ 关键修复:将 Latin-1 字节流转为 UTF-8 字符串
const utf8Filename = Buffer.from(file.originalname, 'latin1').toString('utf-8');
callback(null, utf8Filename);
}
});
const limits = {
files: 100,
fileSize: 50_000_000 // 50MB
};
const upload = multer({
storage: storage,
fileFilter: (req, file, callback) => {
const ext = path.extname(file.originalname).toLowerCase();
const allowedTypes = ['.mp3', '.wav', '.m4a', '.flac', '.aac'];
if (!allowedTypes.includes(ext)) {
return callback(new Error('Only audio files (.mp3, .wav, .m4a, .flac, .aac) are allowed.'));
}
callback(null, true);
},
limits: limits
}).any('file');
⚠️ 重要注意事项:
- 此方案假设客户端实际发送的是 Latin-1 兼容编码(如 Windows-1253 或 ISO-8859-7),这是多数传统环境的默认行为。若明确支持现代 UTF-8 表单(需
- 不要在 req.files[0].originalname = ... 中修改——originalname 是只读属性,强行赋值无效且可能破坏 Multer 内部状态。
- 确保上传目录 ./uploads 存在且有写入权限,否则 destination 回调会失败。
- 生产环境建议添加文件名安全处理(如移除路径遍历字符、限制长度),例如结合 sanitize-filename 库。
该方法轻量、可靠,无需引入额外依赖,已在 Express + Multer v1.x/v2.x 中验证有效。只要确保 filename 回调内完成编码转换,希腊语、俄语、阿拉伯语等其他非 ASCII 文件名均可同理解决。











