【问题标题】:Sails.js Serve Static Files not within project directorySails.js 提供不在项目目录中的静态文件
【发布时间】:2017-03-13 15:33:19
【问题描述】:

在我的网络上,有一个目录,我们存储了许多大图像。从我的风帆应用程序中,我希望能够展示它们。 Web 服务器与“图像存储”位置不同。所以我需要在资产文件夹之外显示图像。我怎样才能做到这一点? 我不在乎控制器操作是否会通过文件名手动获取图像,或者是否存在某种虚拟路由来在应用程序中创建指向其他地方的位置。只需要知道如何。我在网上找不到任何东西。

【问题讨论】:

    标签: javascript node.js express sails.js


    【解决方案1】:

    这里有我的一个例子。希望我理解正确:

    attachments: function(req, res) {
      if(req.method === 'GET') {
        var params = req.params.all();
        var filePath = [process.cwd(), '../yourpath/', params.filename].join('/');
    
        var stat = fs.statSync(filePath);
    
        var readStream = fs.createReadStream(filePath);
        readStream.pipe(res);
      }
    },
    

    基本上你可以从任何你想要的路径获取文件。一旦你点击/controller/attachments/file.jpg,这个函数就会返回图片。

    警告:正如@Liam 所说,“这有一些严重的安全风险 使用 ../ 在 params.filename 因为他们现在可以下载每个文件 您的服务器具有全局读取权限。”所以随便 为了避免这种情况,您需要采取预防措施。

    【讨论】:

    • 这对params.filename 中的../ 存在一些严重的安全风险,因为它们现在可以下载您服务器上具有全局读取权限的每个文件。
    • 这是一个好点。你可以清理文件名,不知道还能做什么来获取动态文件。
    • 'fs' 未定义。
    • var fs = require('fs').不过,请考虑一下利亚姆在上面的评论中所说的话。我只有封闭系统的登录用户才能访问此方法。如果您要向所有人发布此内容,则可能需要一些改进。
    • 做一个将静态文件与节点实例分离的反向代理是提供静态文件的标准方式。
    【解决方案2】:

    有两种标准方法可以做到这一点。首选/性能更高的方法是设置反向代理来为您的静态文件提供服务(您可以为不同的服务器配置不同的路由)。

    反向代理方法(首选)

    Apache/Nginx

    首选是配置您的 Apache 或 nginx 反向代理,以便某个 url(比如 /assets/images/<custom-folder> 将直接为目录提供服务,而不是通过 Nodejs 代理。这更有效,因为 Apache/nginx 守护进程要快得多比 Node 提供文件。

    [nginx 配置示例入站]

    IIS节点

    查看问题:Serving static files from iisnode with URL Rewrite

    我没有设置 IISNode 的经验,但从外观上看,您可以让它为静态文件提供服务,而不是让 Sails.js 为文件提供服务,这样您就可以为不同的文件夹配置不同的路由。下面是一个提供静态文件的 IISNode 配置示例,我想您可以为不同的文件夹设置多个静态和静态服务重写规则。

    <system.webServer>
      <handlers>
        <clear />
        <add name="iisnode" path="/index.js" verb="*" modules="iisnode" />
        <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
      </handlers>
      <rewrite>
        <rules>
          <rule name="static">
            <action type="Rewrite" url="www{REQUEST_URI}" />
          </rule>
          <rule name="serve-static" stopProcessing="true">
            <conditions logicalGrouping="MatchAny">
              <add input="{REQUEST_FILENAME}" matchType="IsFile" />
              <add input="{REQUEST_URI}" pattern="^/www/$" />
            </conditions>
          </rule>
          <rule name="node">
            <action type="Rewrite" url="index.js" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
    

    符号链接方法(更简单)

    另一种(更简单的)方法是符号链接 Sails.js 资产目录中的文件夹,然后通过通常的 Sails.js 路由提供它。设置符号链接:

    cd <assets-dir>
    ln -s <full-path-of-large-images-dir> <folder-name>
    

    例如:

    cd assets/images
    ln -s /var/images/large large
    

    然后您将拥有一个文件夹assets/images/large,它指向/var/images/large 目录。

    【讨论】:

    • 我没有指定,但我们使用 iisnode 在 windows iis 上托管它。我尝试过使用虚拟目录。但是sails 没有看到虚拟目录。
    • 编辑了答案,包括使用 IISNode 进行反向代理