如何使用 nginx 为 root 和代理其他所有内容提供静态 html 服务?

How to use nginx to serve static html for root and proxy everything else?

此配置的目标是:

  1. 为主页提供普通 html 以启动 SPA,例如。 www.website.comwww.website.com/?foo=bar
  2. Python REST API 的代理,用于 1 未捕获的所有内容,例如。 www.website.com/foowww.website.com/foo?bar=123

html 文件位于 /var/www/website.com/index.html

server {
    listen 80;
    server_name website.com;
    return 301 $scheme://www.website.com$request_uri;
}

server {
    listen 80;
    server_name www.website.com;
    access_log off;

    location = / {
        root /var/www/website.com;
    }
    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

我在 Python 端看到对 /index.html 的请求,但在那里失败了。如果我删除 location /,然后我会看到 "Welcome to nginx" 页面,很明显 location = / 不工作。我做错了什么?

NGINX - Serving Static Content

If a request ends with a slash, NGINX treats it as a request for a directory and tries to find an index file in the directory. The index directive defines the index file’s name (the default value is index.html).

检查您是否在当前或任何封闭范围内定义了 index。如果是这样,它会在 nginx 中创建一个内部重定向,它将匹配 Python 位置 (location /).

对于你的情况,我认为至少有两个解决方案:

  1. 添加另一个明确匹配索引文件的位置块:

    location = /index.html {
        ...
    }
    
  2. 在根位置使用try_files

    location = / {
        try_files $uri $uri/index.html =404;
    }
    

您可以使用 error_page 404 重定向流量。 "If there is no need to change URI and method during internal redirection it is possible to pass error processing into a named location."

此外,您有语法错误,这就是显示 "Welcome" 页面的原因。

此处记录了此解决方案:http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page

server {
    listen 80;
    server_name www.website.com;
    index index.html;
    root /var/www/www.website.com;

    error_page 404 = @fallback;

    location @fallback {
            proxy_pass http://127.0.0.1:8000;
    }

}