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

Node.js中res.download()如何实现不区分大小写的文件名匹配下载?

Node.js 实现不区分文件名大小写下载的可行方案

你遇到的问题本质是因为 Linux 等大小写敏感的文件系统下,文件名匹配会严格校验大小写,只需在调用res.download前先匹配到目录下对应真实文件名即可。

方案1:原生 Node.js 遍历目录匹配(无第三方依赖)

适合存储文件数量较少的目录,无需引入额外依赖:

const fs = require('fs/promises');
const path = require('path');

// 第一步:路径安全校验,防止路径穿越漏洞
const safeInputName = path.basename(fileNameOnly);
const targetDir = path.resolve(filePath); // 你的文件存储根目录

try {
  // 读取目标目录下所有文件
  const dirFiles = await fs.readdir(targetDir);
  // 大小写不敏感匹配真实文件名
  const realFileName = dirFiles.find(file => 
    file.toLowerCase() === safeInputName.toLowerCase()
  );

  if (!realFileName) {
    return res.status(404).send({message: '请求的文件不存在'});
  }

  // 匹配到真实文件后执行下载逻辑
  const fullFilePath = path.join(targetDir, realFileName);
  res.set("Content-Disposition", "inline; filename=" + safeInputName);
  res.set("Content-Type", "application/pdf");
  res.download(fullFilePath, safeInputName, (err) => {
    if(err) {
      console.log('Impex Ctlr: There was an error in downloading document: ' + err);
      res.status(500).send({message: 'Download Error' + err})
    }
  });
} catch (readErr) {
  console.log('读取目录失败:', readErr);
  res.status(500).send({message: '服务器内部错误'});
}

方案2:使用 glob 库匹配(适合大文件目录)

如果目录下存储文件数量较多,用 glob 库的匹配能力性能更优:

  1. 先安装依赖:npm i glob
  2. 代码示例:
const glob = require('glob');
const path = require('path');

const safeInputName = path.basename(fileNameOnly);
const targetDir = path.resolve(filePath);

// nocase参数开启大小写不敏感匹配
glob(`${targetDir}/${safeInputName}`, { nocase: true }, (err, matchedFiles) => {
  if (err) {
    return res.status(500).send({message: '匹配文件失败'});
  }
  if (matchedFiles.length === 0) {
    return res.status(404).send({message: '请求的文件不存在'});
  }
  // 取第一个匹配到的文件,可根据业务调整优先级
  const fullFilePath = matchedFiles[0];
  res.set("Content-Disposition", "inline; filename=" + safeInputName);
  res.set("Content-Type", "application/pdf");
  res.download(fullFilePath, safeInputName, (err) => {
    if(err) {
      console.log('Impex Ctlr: There was an error in downloading document: ' + err);
      res.status(500).send({message: 'Download Error' + err})
    }
  });
});

注意事项

  • 必须做路径安全校验,用path.basename处理传入的文件名,防止攻击者传入../../xxx.js之类的路径穿越 payload 读取服务器敏感文件
  • 如果目录下存在多个仅大小写不同的同名文件(如Test.pdf和test.pdf同时存在),需根据业务需求决定返回优先级,可选择返回修改时间最新的文件,或直接返回400提示文件名存在歧义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:30:03