首页 > 解决方案 > 为什么 Nginx proxy_pass 在与变量一起使用时会忽略 add_headers?

问题描述

我正在尝试使用 Nginx 制作动态 CORS 代理,因此我可以使用前端代码中的多个 API 而不会出现任何 CORS 错误。我目前的方法是使用多个location块,每个域一个块,这是可行的,但我宁愿有一个动态的解决方案。我的想法是使用x-proxy-target指定上游主机名,并传递路径名。Nginx 在 Kubernetes 上的 Docker 容器中运行,因此10.245.0.10是解析器。

这完美地工作,并使用在底部设置的 CORS 标头发送add_header

location / {
      default_type application/json;
      if ($http_x_proxy_target = "") {
        return 400 '{"message": "No x-proxy-target header", "code": "PROXY_TARGET_NOT_SET"}';
      }

      resolver 10.245.0.10 [::1];
      set $cors '*';
      if ($http_origin != "") {
         set $cors $http_origin;
      }

      if ($request_method = "OPTIONS") {
        add_header Access-Control-Allow-Origin $cors always;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
        add_header Access-Control-Allow-Headers * always;
        return 204;
      }

      proxy_hide_header Access-Control-Allow-Headers;
      proxy_hide_header Access-Control-Expose-Headers;
      proxy_hide_header Access-Control-Allow-Credentials;
      proxy_hide_header Access-Control-Allow-Origin;
      
      proxy_set_header x-proxy-target '';
      proxy_set_header User-Agent $http_user_agent;
      proxy_set_header Connection $http_connection;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Origin https://$http_x_proxy_target;
      proxy_set_header Host $http_x_proxy_target;
      proxy_set_header Referer https://$http_x_proxy_target/;

      proxy_pass https://google.com/;

      add_header Access-Control-Allow-Headers * always;
      add_header Access-Control-Expose-Headers * always;
      add_header Access-Control-Allow-Credentials true always;
      add_header Access-Control-Allow-Origin $cors always;
}

但是当我更改proxy_pass为使用提供的上游时:

location / {
      default_type application/json;
      if ($http_x_proxy_target = "") {
        return 400 '{"message": "No x-proxy-target header", "code": "PROXY_TARGET_NOT_SET"}';
      }

      resolver 10.245.0.10 [::1];
      set $cors '*';
      if ($http_origin != "") {
         set $cors $http_origin;
      }

      if ($request_method = "OPTIONS") {
        add_header Access-Control-Allow-Origin $cors always;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
        add_header Access-Control-Allow-Headers * always;
        return 204;
      }

      proxy_hide_header Access-Control-Allow-Headers;
      proxy_hide_header Access-Control-Expose-Headers;
      proxy_hide_header Access-Control-Allow-Credentials;
      proxy_hide_header Access-Control-Allow-Origin;
      
      proxy_set_header x-proxy-target '';
      proxy_set_header User-Agent $http_user_agent;
      proxy_set_header Connection $http_connection;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Origin https://$http_x_proxy_target;
      proxy_set_header Host $http_x_proxy_target;
      proxy_set_header Referer https://$http_x_proxy_target/;

      proxy_pass $scheme://$http_x_proxy_target$uri$is_args$args;

      add_header Access-Control-Allow-Headers * always;
      add_header Access-Control-Expose-Headers * always;
      add_header Access-Control-Allow-Credentials true always;
      add_header Access-Control-Allow-Origin $cors always;
}

我使用 Postman 得到了正确的响应,但未设置 CORS 标头。我曾尝试将add_header线条移到 上方proxy_pass,但无济于事。对我来说,这似乎是 Nginx 中的一个可能的错误,尽管我可能只是犯了一个明显的错误。尽管这是一个非常具体的用例,但我在任何地方都找不到任何提及此问题的内容。

标签: nginxnginx-reverse-proxynginx-location

解决方案


推荐阅读