【发布时间】:2019-11-05 15:20:40
【问题描述】:
我想在运行在自己端口上的不同应用程序之前使用 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 而不是 https://example.com/app1/page1
所以基本上每当有人在 /app1/* 页面上时,总是添加前缀 /app1/。
如果这实际上是完整的域名时不会发生这种情况,那就太好了,因此可以从 /app1/ 页面中的 /app2/ url 加载资源
有什么方法可以通过 Nginx 配置修复,还是只能在应用程序本身中修复?
编辑:
我发现 Nginx 有一个叫做 sub_filter 的函数。
这替换了响应正文中的字符串。
所以: 应用返回:200 "hello world!"
//nginx
sub_filter "world" "moon";
然后浏览器将显示“你好月亮!”
但是我还需要为 302 重定向执行此操作。
标题是否有“sub_filter 等效项”?
EDIT2:
正如 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)
浏览器响应头是:
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_pass http://localhost:1111/app1/;和proxy_pass http://localhost:2222/app2/;会发生什么? -
@IvanShatsky 它返回 404,因为应用程序中没有 /app1/ 路径。
-
这些重定向是什么样的?它们是 3xx HTTP 代码还是
href的响应正文? -
@IvanShatsky 这些是 302 个 http 代码。 href 可以用 sub_filter 完成
标签: nginx nginx-location