nginx:proxy_pass失败时回退到try_files需要异常配置

时间:2019-04-19 15:49:51

标签: nginx single-page-application proxypass

我正在使用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;
}

然后,nginx在<root>index.html之类的文件系统上构造路径,每当请求的URL并非根URL时,该路径就会缺少分隔符而不是正确的<root>/index.html

最后一个问题:为什么此设置在try_files指令中需要双斜杠?为什么不能只使用常规配置中的try_files部分并将其移至拦截错误时使用的后备位置?

1 个答案:

答案 0 :(得分:-1)

我遇到了类似的情况,我使用common pitfalls本页中的建议反过来解决了这个问题。也就是说,首先提供静态文件,然后回退到代理:

location / {
    try_files $uri $uri/ @proxy;
}
location @proxy {
    proxy_pass http://127.0.0.1:9990;
}

在这种情况下,这将首先在根中查找文件是否为静态文件,然后将请求代理到http://127.0.0.1:9000。这在功能上等效,除非,您希望代理中的文件隐藏静态文件。