为什么我可以用 NGINX 编写一组 URL,但不能编写其他 URL?

为什么我可以用 NGINX 编写一组 URL,但不能编写其他 URL?

我已将 NGINX 版本 1.18.0 设置为 Apache Superset 1.4.0 安装的反向代理。

我正在尝试捕获一些 URL 模式,并且改写standalone=1在末尾添加。

以下 NGINX 配置按预期工作:

location /superset/explore/ {
        if ($args ~* "(.*?)slice_id%22%3A133(.*)$") {
            rewrite ^/superset/explore/(.*)$ /superset/explore/$1?standalone=1 break;
        }

        proxy_pass http://127.0.0.1:8087;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

因为当我访问(使用 Chrome)诸如 的 URL 时,当我检查 Chrome 地址栏时,我可以看到它已被添加到 URL 中的http://192.168.239.40:8088/superset/explore/?form_data=%7B%22viz_type%22%3A%22echarts_timeseries_line%22%2C%22datasource%22%3A%2233__table%22%2C%22slice_id%22%3A133%2C ...原始加号替换。&standalone=1

但是,当我尝试对 Apache Superset 的另一个 URL 模式执行类似操作时,例如:

   location /dashboard/list/ {
        rewrite ^/dashboard/list/(.*)$ /dashboard/list/$1?standalone=1 break;

        proxy_pass http://127.0.0.1:8087;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

当我http://192.168.239.40:8088/dashboard/list/使用 Chrome 发出请求时,我看到地址栏被替换了,http://192.168.239.40:8088/dashboard/list/?pageIndex=0&sortColumn=changed_on_delta_humanized&sortOrder=desc&viewMode=table但没有看到任何&standalone=1附加内容。

我还检查了 Superset 日志以查看它在我请求后提供什么服务http://192.168.239.40:8088/dashboard/list/并且我发现它?standalone=1实际上是附加的!

Feb 10 14:09:19 dashboard-server python[34169]: 2022-02-10 14:09:19,482:INFO:werkzeug:127.0.0.1 - - [10/Feb/2022 14:09:19] "GET /dashboard/list/?standalone=1 HTTP/1.0" 200 -
Feb 10 14:09:20 dashboard-server python[34169]: 2022-02-10 14:09:20,729:INFO:werkzeug:127.0.0.1 - - [10/Feb/2022 14:09:20] "GET /api/v1/dashboard/_info?q=(keys:!(permissions)) HTTP/1.0" 200 -
Feb 10 14:09:20 dashboard-server python[34169]: 2022-02-10 14:09:20,771:INFO:werkzeug:127.0.0.1 - - [10/Feb/2022 14:09:20] "GET /api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25) HTTP/1.0" 200 -

知道为什么会发生这种情况吗?

完整/etc/nginx/conf.d/superset.conf如下:

server {
    listen 8088;
    server_name 192.168.239.40;

    location / {
        proxy_pass http://127.0.0.1:8087;
    }

    location /superset/explore/ {
        if ($args ~* "(.*?)slice_id%22%3A133(.*)$") {
            rewrite ^/superset/explore/(.*)$ /superset/explore/$1?standalone=1 break;
        }

        proxy_pass http://127.0.0.1:8087;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

   location /dashboard/list/ {
        rewrite ^/dashboard/list/(.*)$ /dashboard/list/$1?standalone=1 break;

        proxy_pass http://127.0.0.1:8087;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }


    # required as superset has hardcoded base path urls
    location /static/ {
        proxy_pass http://127.0.0.1:8087/static/;
    }

    # to expose a specific dashboard using a custom url
    # the below example will make dashboard 2 available in standalone mode
    # on $host/dashboards/my-dashboard
    location /dashboards/my-dashboard {
        proxy_pass http://127.0.0.1:8087/superset/dashboard/2/?standalone=true;
    }
}

答案1

如果不知道上游应用程序实际如何处理 URL,像这样修改 URL 是非常危险的。这可能会导致许多难以诊断的错误。

你应该重新审视你最初的目标并思考是否可以通过其他方法实现它。

当前问题变成了:rewrite ... break内部重写 URL。这意味着,nginx 仅修改发送到上游服务器的 URL。

在这种情况下,您的上游服务器只会返回修改后的 URL 指定的页面。

在客户端的浏览器中,URL 没有发生变化,因为服务器只是返回所请求 URL 的内容。

当浏览器 URL 使用此配置发生变化时,会发生什么情况:在这种情况下,您的上游应用程序似乎正在使用 302 重定向进行响应,这会使浏览器访问另一个 URL。

如果您想告诉客户端转到该 URL,那么您需要发送 HTTP 重定向:

rewrite ^/dashboard/list/(.*)$ /dashboard/list/$1?standalone=1;

但是,这很可能会自行创建一个重定向循环,因为同一个location块会一次又一次地捕获请求。创建非循环 HTTP 重定向可能是一项相当复杂的工作。

因此,我会寻找解决当前实际问题的其他方法。

相关内容