请忍耐一下,这是一个很长的故事。
一开始,我创建了一个 Nginx 服务器来为我的公司提供静态文件服务,并且使用以下配置片段来提供文件服务,它运行良好:
server {
# bunch of ssl stuff
root /path/to/files;
location / {
include cors_support;
sendfile on;
sendfile_max_chunk 1m;
try_files $uri =404;
}
简单、干净且功能齐全。直到我想到要为该服务器添加另一个功能:存储我们的应用程序构建并将它们提供给我们的 QA 团队。由于应用程序文件可能非常大,我添加了另一个仅用于构建的存储卷,并认为只需对 Nginx 配置进行简单的更改即可实现这一点,如下所示(仅显示相关部分):
server {
# mostly the same
root /new/path/to/builds;
location / {
#same as before
try_files $uri @cdn_files;
}
location @cdn_files {
#some cors and send_file settings
root /path/to/files;
try_files $uri =404;
}
}
根据文档我预计会发生以下情况:
- 文件请求进来
- 检查文件的第一个块
- 找到文件了吗?是=发送文件否=重定向到指定位置
- 命名位置 -> 找到文件?是=发送文件否=404 页面
实际情况:
- 文件请求进来
- 检查文件的第一个块
- 找到文件了吗?是=发送文件否=404 页面
我尝试过很多不同的方法来解决这个问题,包括一些疯狂的“万福玛利亚”尝试。
这会产生相同的结果(404页面):
# ... irrelevant code
root /;
location / {
# ... more irrelevant code
try_files /new/path/to/builds/$uri /path/to/files/$uri =404;
}
这会产生相同的结果(404页面):
# ...
root /new/path/to/builds;
location / {
# ...
try_files $uri @cdn_files;
}
location @cdn_files {
# ...
root /path/to/files;
try_files $uri =403; #note that the page delivered is 404 and NOT 403
}
这也会产生 404 错误:
# I removed the "root" directive from the server block for this test
location / {
# ...
root /new/path/to/builds;
try_files $uri ../realitve/path/to/files/$uri =404;
}
还有几点需要注意:
- 错误日志仅显示在指令的第一个参数处定位文件的1次尝试
try_files
。 - 如果文件存在于
try_files
指令的第一个参数中,则文件将被传送 - 我不认为它是相关的,但以防万一:操作系统是 Ubuntu 16.04
编辑:
- Nginx 版本 1.21.0
答案1
因此,我最终设法通过新的 URL 路由我对构建的传入请求并将其路由到它们自己的服务器块,从而使其正常工作,同时保留修改之前的原始文件访问权限,并且两个 URL 现在都可以从其特定位置检索文件。
我查看、谷歌搜索并摆弄了几个小时,但我仍然无法修复在单个服务器块中从多个目录访问文件的问题,尽管从查看文档来看这应该是可能的。