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

Express响应动态文件名失效问题(部署于Google Cloud Run)

Express.js 动态文件名下载异常问题

问题现象

在Express.js(版本^4.17.1)中,使用静态文件名调用res.download时:

return res.download(filePath, 'test.pptx');

功能完全正常。但改用动态变量fileName调用时:

return res.download(filePath, fileName);

下载的文件名称会变成「download」,且响应中未返回Content-Disposition头。

完整处理代码

async function downloadPPT(req, res) {
    const readyFilesPath = path.resolve(pptProcessFolderPath, 'ready_files');
    const files = fs.readdirSync(readyFilesPath);

    if(files.length > 1){
        const zipFile = files.map(e => {
            return {
                path: path.resolve(readyFilesPath, e),
                name: e
            }
        });

        return res.zip(zipFile, 'PPTs.zip');
    }

    const filePath = path.resolve(readyFilesPath, files[0])
    const fileName = files[0]

    return res.download(filePath, fileName);
}

补充细节

  • 仅在部署到Google Cloud Run的Docker容器中出现该问题,本地Docker运行无异常;
  • 使用静态文件名部署在GCP时功能正常;
  • Dockerfile配置如下:
FROM node:14

# Create app directory
WORKDIR /home

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 3000
CMD [ "npm", "start" ]

可行解决方向

  1. 处理文件名编码:Google Cloud Run环境对文件名编码处理可能存在差异,尝试对fileName做URL编码后传入:
const encodedFileName = encodeURIComponent(fileName);
return res.download(filePath, encodedFileName);

或手动设置响应头:

res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(fileName)}"`);
return res.download(filePath);
  1. 校验文件名字符合法性:检查files[0]是否包含空格、非ASCII等特殊字符,这类字符在GCP环境下可能被截断过滤,可对文件名做清理处理。

  2. 显式设置响应头:GCP的负载均衡或Cloud Run可能修改响应头,尝试同时设置Content-Type和Content-Disposition:

const fileExt = path.extname(fileName);
const contentType = mime.getType(fileExt) || 'application/octet-stream';
res.setHeader('Content-Type', contentType);
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
return res.sendFile(filePath);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:05:43