我正在使用Nginx来提供单页面应用。基本上,我们只需要在找不到匹配文件时提供index.html
页面。该位置如下所示,并且一直正常工作:
location / {
try_files $uri $uri/ /index.html
}
现在我想查询一个上游服务器,只有在它失败时才使用上述
try_files
指令。如果
try_files
被移动到备用位置,例如:location @fallback {
try_files $uri $uri/ /index.html;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_intercept_errors on;
error_page 400 403 502 503 504 @fallback;
}
如果上游服务器不可用,客户端将看到Nginx 502错误页面,而不是从文件系统提供的文件。
最后我找到了一个解决方案,通过在/index.html备用中使用双斜杠来实现。这是整个配置文件,可以与官方的nginx docker镜像一起使用进行测试。
events {
}
http {
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
server {
listen 80;
root /usr/share/nginx/html/;
location / {
proxy_pass http://127.0.0.1:9990;
proxy_intercept_errors on;
error_page 400 403 502 503 504 = @fallback;
}
location @fallback {
try_files $uri?$args /index.html //index.html;
}
}
}
可以通过类似命令的方式运行
docker run -v /path/to/www/folder:/usr/share/nginx/html:ro -v /path/to/config/nginx.conf:/etc/nginx/nginx.conf -d -p 8080:80 nginx
如果在最后一个
index.html
回退之前没有出现双斜杠,就会发生如下情况。location @fallback {
try_files $uri?$args /index.html;
}
当请求一个非根URL时,nginx会在文件系统上构造一个路径,如<root>index.html
,其中缺少正确的分隔符<root>/index.html
。
最后一个问题:为什么这个设置要求在try_files指令中使用双斜杠?为什么不能直接使用常规配置中的try_files部分并将其移动到拦截错误时使用的回退位置?