
本文介绍在使用 Multer 处理文件上传时,因客户端与服务器编码不一致导致希腊字母等非 ASCII 字符文件名显示为乱码(如 Î Ïξ Îαξ)的根本原因及可靠解决方案,重点演示如何在 filename 函数中正确进行 Latin-1 到 UTF-8 的编码转换。
本文介绍在使用 multer 处理文件上传时,因客户端与服务器编码不一致导致希腊字母等非 ascii 字符文件名显示为乱码(如 `Î Ïξ Îαξ`)的根本原因及可靠解决方案,重点演示如何在 `filename` 函数中正确进行 latin-1 到 utf-8 的编码转换。
在基于 Express 的 Node.js 应用中,Multer 是最常用的文件上传中间件。但当用户上传包含希腊字符(如 αβγ.mp3)、中文、俄文等 Unicode 文件名时,常出现类似 ασκος.mp3 的乱码——这并非 Multer 本身的 Bug,而是 HTTP 协议对 Content-Disposition 中 filename 字段的编码限制所致:浏览器通常以 Latin-1(ISO-8859-1)编码发送原始文件名,而 Node.js 默认按 UTF-8 解析,造成字节错位解码。
关键修复点在于:必须在 filename 回调函数内部,对 file.originalname 进行 Latin-1 → UTF-8 的显式转码,而非在路由处理逻辑中事后修改(后者已错过文件写入时机,且 req.files 可能已被冻结)。
以下是修正后的完整 Multer 配置示例:
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 编码的 originalname 转为 UTF-8 字符串
const utf8Filename = Buffer.from(file.originalname, 'latin1').toString('utf-8');
callback(null, utf8Filename);
}
});
const limits = {
files: 100,
fileSize: 50000000 // 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');⚠️ 注意事项:
- 不可在 req.files[0].originalname = ... 中转码:此时文件已按错误名称写入磁盘,且 Multer 已完成核心流程,强行修改无效甚至引发 TypeError;
- Buffer.from(..., 'latin1') 是必需步骤:直接 file.originalname.toString('utf-8') 会失败,因为字符串已是错误解码后的 JS 字符串,需先还原为原始字节;
- 确保上传表单使用 enctype="multipart/form-data",且前端无额外 URL 编码干扰;
- 如需进一步兼容性(如旧版 IE),可添加容错逻辑:
filename: (req, file, callback) => { try { const utf8Filename = Buffer.from(file.originalname, 'latin1').toString('utf-8'); callback(null, utf8Filename); } catch (e) { // 若转码失败,回退到安全文件名(如时间戳+哈希) const safeName = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}${path.extname(file.originalname)}`; callback(null, safeName); } }
该方案已在 Express 4.x/5.x + Multer 1.4.x+ 环境中稳定验证,可彻底解决希腊语、阿拉伯语、中文等多语言文件名乱码问题,无需修改客户端或依赖额外中间件。

















