headers 的 Nginx sub_filter

Nginx sub_filter for headers

我想在 运行 在它们自己的端口上的不同应用程序之前使用 nginx proxy_pass。

所以我有

server {

    listen 443 ssl;
    ssl on;

    ssl_certificate /etc/ssl/certs/self-signed.crt;
    ssl_certificate_key /etc/ssl/private/self-signed.key;

    proxy_intercept_errors on;

    location /app1/ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_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;
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_pass http://localhost:1111;
    }

    location /app2/ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_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;
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_pass http://localhost:2222;
    }
}

但是问题是应用程序本身有重定向,导致 /app1/ 或 /app2/ 消失。

即302 get /page1 将变为 https://example.com/page1 instead of https://example.com/app1/page1

所以基本上只要有人在 /app1/* 页面总是前缀 /app1/。

如果这实际上是完整域名时不会发生,那就太好了,因此可以从 /app1/ 页面中的 /app2/ url 加载资源

有什么方法可以用 Nginx 配置修复,或者我只能在应用程序本身中修复这个问题吗?

编辑:

我发现Nginx有个函数叫做sub_filter。

这替换了响应 body 中的字符串。

所以: 应用程序 returns:200 "hello world!"

//nginx
sub_filter "world" "moon";

那么浏览器会显示"hello moon!"

但是我还需要为 302 重定向执行此操作。

headers有"sub_filter equivalent"吗?

编辑2:

正如 Ivan 所建议的那样,代理重定向可能应该可以解决问题,但它并没有改变任何东西。 我的 nginx 代码是:

location /app1/ {
    proxy_set_header Accept-Encoding ""; # no compression allowed or next won't work
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    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;

    proxy_http_version 1.1;
    proxy_redirect off;
    proxy_buffering off;
    proxy_read_timeout 3600;
    proxy_connect_timeout 3600;
    fastcgi_read_timeout 3600s;

    proxy_pass http://localhost:5000/;
    proxy_redirect http://localhost:5000/ /app1/; #also tried full domain
}

至于应用程序,我正在使用像这样的简单 Flask 应用程序对其进行测试:

@app.route('/')  
def hello_world(): 
    return redirect("http://localhost:5000/testing", code=302)

和浏览器响应 headers 是:

HTTP/1.1 302 FOUND
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 06 Nov 2019 15:56:24 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Location: http://localhost:5000/testing

针对您的情况使用 proxy_redirect 指令:

proxy_redirect / /app1/;

proxy_redirect / /app2/;

删除任何 proxy_redirect off; 指令,因为它取消了同一级别上所有 proxy_redirect 指令的效果。