【问题标题】:Why is my Nginx reverse proxy doing a 301 redirect instead of proxying?为什么我的 Nginx 反向代理执行 301 重定向而不是代理?
【发布时间】:2018-12-14 21:29:22
【问题描述】:

我在 docker 容器中有一个 Nginx 反向代理,它监听 3000 端口并暴露于 3002:docker run -p "3002:3000" ...

这个想法是这个反向代理将/my-app代理到在我的笔记本电脑上运行的8080端口的实例;和/my-app/api 到云实例,在https://my-domain

这是配置:

upstream my-laptop {
  server host.docker.internal:8080; # this is a magic hostname for the laptop's IP address.
  keepalive 64;
}

upstream cloud {
  server my-domain.com:443;
  keepalive 64;
}

server {
    listen       3000;

    include ssl/ssl-certs.conf;
    include ssl/ssl-params.conf;

    location /my-app {
        proxy_pass http://my-laptop;
        proxy_set_header Host            $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /my-app/api {
        proxy_pass https://cloud;
        proxy_set_header Host            $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    ...
}

问题是:

  1. 当我点击https://localhost:3002/my-app 时,我收到了对/my-app/ 的301 响应(斜杠)。我不知道为什么会这样。本地应用实例显示在浏览器中,所以我想我可以让它暂时滑动一下?
  2. 当我点击https://localhost:3002/my-app/api/students 时,我收到了对https://cloud/my-app/api/students 的301 响应。当然,这会导致 CORS 问题,并且端点不会返回数据。

现在,我已经配置了几次反向代理,所以我完全震惊于我没有看到问题所在,这不是我第一次。

与我为不同应用程序使用的另一个反向代理相比,我尝试调整上游代理集标题;我没有想法。

我做错了什么?

【问题讨论】:

  • 你试过proxy_set_header Host $proxy_host
  • 使用哪个“斜杠组合”?
  • 类似的东西 location /my-app/api { proxy_pass cloud; proxy_set_header 主机 $proxy_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } 位置 /my-app/? { proxy_pass my-laptop; proxy_set_header 主机 $proxy_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
  • 我不确定这是否重要,但我想知道proxy_set_headerproxy_pass 的顺序是否重要,所以我可能会尝试将通行证移到底部。

标签: docker nginx reverse-proxy


【解决方案1】:

虽然提问者的配置没有这个特殊问题,但尾斜杠问题也可能导致重定向而不是代理,如the docs 中所述:

如果位置由以斜杠字符结尾的前缀字符串定义,并且请求由 proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pa​​ss 或 grpc_pass 之一处理,则执行特殊处理。为了响应 URI 等于此字符串但没有尾部斜杠的请求,将返回带有代码 301 的永久重定向到附加斜杠的请求 URI。如果不希望这样,可以像这样定义 URI 和位置的完全匹配:

location /user/ {
   proxy_pass http://user.example.com;
}

location = /user {
    proxy_pass http://login.example.com;
}

【讨论】:

  • 很高兴在此处注意此信息,因为我有这个确切的问题,并且此答案直接适用于我的问题(以及我确定的其他问题)。 (y) 另见serverfault.com/questions/801897/…
【解决方案2】:

问题是我在云上游的Host 标头,我有

proxy_set_header Host $http_host;

但它必须是

proxy_set_header Host my-domain.com;

【讨论】:

  • 我的 Nginx 代理在 cloudflare 代理后面。我已删除 server_name。在那种情况下,我的主机的价值应该是多少?因为我面临着和你一样的问题。如果我的端点中没有斜杠,我会收到 405 Method Not Allowed CORS 问题。
【解决方案3】:

这是 nginx 作为反向代理的示例配置,适用于我, 我对其进行了简化并删除了不必要的部分。 希望对你有帮助。

upstream OAUTH {
    server remote_oauth;
}



server {
    listen  80;
    server_name example.com;

    client_header_timeout       300;


    location = /servies/oauth {
      return 301 /services/oauth/;
    }


    location /services/oauth/ {
        proxy_pass_request_headers on;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://OAUTH/;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-ROOT-URI /services/oauth;
        proxy_set_header Accept-Encoding "gzip";
        proxy_buffering off;
        proxy_request_buffering off;
        proxy_http_version 1.1;
        proxy_intercept_errors on;
        proxy_redirect default;
        client_max_body_size 4M;
    }


}

我认为你错过了这部分: proxy_pass_request_headers 开启

【讨论】:

    猜你喜欢
    • 2019-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 2015-11-29
    相关资源
    最近更新 更多