将动态文件服务从应用服务器转移到 nginx

将动态文件服务从应用服务器转移到 nginx

我在用着Nginx作为反向代理为了我的应用服务器

App Server通过以下路由接收文件下载请求:

/文件/:id

然后应用程序找到文件系统上的文件路径IE/路径/到/文件/带/id并以文件内容进行响应。

我不想向用户公开文件路径。

有没有办法通知 Nginx 文件的路径,以便 Nginx 可以为用户处理文件下载,反而我的应用服务器,我不想使用 Nginx 作为反向代理或缓存服务器,我需要更多来自 Nginx 的应用服务器。


概述:

想要从此架构切换:

[nodejs/express]> 文件内容[nginx]> 文件内容[浏览器]

到这个架构:

[nodejs/express]> 文件信息[nginx]> 文件内容[浏览器]

文件信息:

path
mimetype
originalname

Nginx 必须告诉浏览器文件的原始名称和 mimetype。文件名在路径中被散列,并且文件名中没有其 mimetype 的迹象,所以我必须使用从应用服务器返回的文件信息。

答案1

nginx 对于执行此类操作以找出要提供的文件名的支持形式逻辑非常有限。

您需要修改您的应用程序,以便它不向用户提供 URL /files/:id,而是提供实际静态文件的 URL。

另一个选择是简单地向 nginx 添加缓存。

答案2

您需要设置应用服务器来重定向(而不是重写!)URL,即如果我请求/files/:id,我应该获得 301 重定向到/path/to/file。

然后,您需要设置 nginx,如果找到则从本地文件系统提供文件,如果找不到则回退到反向代理。

接下来会发生什么:

  1. /files/:id 的请求由 nginx 代理到后端
  2. 后端向客户端发送 301 重定向到 /path/to/file
  3. 客户端请求 /path/to/file
  4. nginx 在本地文件系统上找到该文件并直接提供服务

像这样:

location / {
    try_files $uri $uri/ @backend;
}

location @backend {
    proxy_pass http://ip:80;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
}

编辑:如果您不想让用户知道文件的真实 URL,您唯一的选择是要求远程服务器转换 URL 或构建逻辑以在 nginx 内部进行映射。这可以通过从 nginx 切换到 openresty 并使用 lua-resty-http 来实现:https://github.com/pintsized/lua-resty-http

答案3

谢谢@MichaelHampton我使用了 x-accel

https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/

这是一个示例配置:

表达:

    if (file_info.mimetype.split('/')[0] === 'image') {
      res.header(
        'Content-Disposition',
        'inline');
    } else {
      res.header(
        'Content-Disposition',
        'attachment; filename=' + file_info.originalname);
    }

    res.header('Content-Type', file_info.mimetype);
    res.header('X-Accel-Redirect', file_info.path.split('/home')[1]);

nginx的:

    location ~ ^/ypj* {
        internal;
        root /home;
    }

    location ~ .* {
        if ($host ~ ^cdn\.(.+)$) {
            proxy_pass http://127.0.0.1:4000;
        }
    }

文件路径类似于:

/主页/ypj/x/y/z

相关内容