我在用着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,如果找到则从本地文件系统提供文件,如果找不到则回退到反向代理。
接下来会发生什么:
- /files/:id 的请求由 nginx 代理到后端
- 后端向客户端发送 301 重定向到 /path/to/file
- 客户端请求 /path/to/file
- 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