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

Sails.js(v0.12)应用中如何将服务器文件下载至客户端?

在Sails.js v0.12中实现文件下载的两种可靠方案

嗨,我来帮你搞定Sails.js v0.12里的文件下载问题!你提到的两个思路其实都能落地,我给你详细拆解下靠谱的实现方式:

方案一:通过静态文件服务直接访问(对应你的第一个思路)

你想让用户通过URL下载文件的思路没问题,只是默认情况下Sails只会暴露assets目录下的静态文件,你的downloads目录不在这个范围内,所以需要手动配置静态路由:

  1. 配置静态中间件:
    打开config/http.js,找到customMiddleware选项,添加Express的静态文件服务中间件,把downloads目录映射到一个URL路径:

    var express = require('express');
    var path = require('path');
    
    module.exports.http = {
      middleware: {
        customMiddleware: function(app) {
          // 把myApp/downloads目录映射到 /public-downloads 路径下
          app.use('/public-downloads', express.static(path.join(__dirname, '../downloads')));
        }
      }
    };
    

    这里用/public-downloads而不是直接用/downloads是为了避免和业务路由冲突,你可以根据自己的需求调整。

  2. 用户下载方式:
    现在用户只要拿到完整的文件名(比如uuid-filename.ext),就可以通过http://你的域名/public-downloads/uuid-filename.ext直接下载文件了。

⚠️ 注意:如果这些文件需要权限验证(比如只有登录用户才能下载),就不能用这种直接暴露静态文件的方式,得用下面的控制器方案。

方案二:通过控制器流式传输文件(对应你的第二个思路)

你以为Sails没有类似Express的res.download()?其实Sails v0.12的res对象是继承自Express的,res.download()是可以直接用的!另外你提到的res.attachment()也能配合使用,下面是具体实现:

  1. 创建文件下载控制器:
    在api/controllers/下新建FileController.js,写一个download动作:

    module.exports = {
      download: function(req, res) {
        // 获取请求中的文件名参数
        var filename = req.param('filename');
        // 拼接完整的文件路径
        var filePath = require('path').join(sails.config.appPath, 'downloads', filename);
        var fs = require('fs');
    
        // 先检查文件是否存在
        fs.access(filePath, fs.constants.R_OK, function(err) {
          if (err) {
            return res.notFound('请求的文件不存在');
          }
    
          // 方式1:直接用res.download(),自动处理下载头和流式传输
          res.download(filePath, function(err) {
            if (err) {
              sails.log.error('文件下载失败:', err);
              return res.serverError('下载出错,请稍后重试');
            }
          });
    
          // 方式2:用res.attachment() + res.sendFile()(自定义下载文件名时用)
          // 如果想让用户下载时看到的文件名不是uuid开头的,比如改成"report.pdf"
          // res.attachment('report.pdf');
          // res.sendFile(filePath, function(err) {
          //   if (err) {
          //     sails.log.error('文件下载失败:', err);
          //     return res.serverError('下载出错,请稍后重试');
          //   }
          // });
        });
      }
    };
    
  2. 配置路由:
    打开config/routes.js,添加一条路由映射:

    'GET /download/:filename': 'FileController.download'
    
  3. 使用方式:
    用户访问http://你的域名/download/uuid-filename.ext就会触发文件下载,而且这个方式可以很方便地在控制器里添加权限验证逻辑(比如检查用户是否登录、是否有权限下载该文件)。

额外注意事项

  • 路径安全:一定要用path.join()拼接路径,避免用户通过构造恶意文件名进行路径遍历攻击;另外可以对filename参数做格式验证(比如检查是否符合uuid-*.ext的格式)。
  • 文件权限:确保运行Sails的进程有读取downloads目录的权限,不然会出现文件读取失败的错误。
  • 错误处理:记得处理文件不存在、读取失败等异常情况,给用户返回友好的提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:32:00