【问题标题】:Nginx proxy_pass missing error bodyNginx proxy_pass 缺少错误主体
【发布时间】:2016-05-05 11:25:19
【问题描述】:

下面是一个非常标准的 nginx proxy_pass 设置:

server {
  listen 80;
  server_name ireport.jungdigital.com;
  access_log /var/log/nginx/ireport.access.log;
  root /var/www/ireport.jungdigital.com/dist;
  index index.html index.htm;
  location / {       
  }
  location /api/ {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
     }
     if ($request_method = 'PUT') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
     }
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header X-NginX-proxy true;
     proxy_set_header Host ireport.somehost.org;
     proxy_pass http://ireport_dyndns/api/;
     proxy_ssl_session_reuse off;
     proxy_redirect off;
  }
}

我正在代理的 API 返回包含 400、404 和 500 错误代码的错误信息的响应正文。例如,在 404 上,我的响应正文可能如下所示:

{
  "errorCode": "TOKEN_NOT_FOUND",
  "errorMessages": [
    "Could not find a matching authorization token."
  ]
}

如果我在没有代理的情况下执行请求,我会得到错误的响应正文。

如果我使用 nginx 代理,由于某种原因,响应正文被 nginx 吞没了,我什至在我的网络浏览器“网络”选项卡中都看不到响应。

有没有办法告诉 Nginx 在 proxy_pass 中返回错误代码的响应正文?

【问题讨论】:

  • @AlexeyTen 这不是我需要的标头,而是响应正文本身。我做了更多的挖掘,看起来身体实际上是返回的,但被浏览器本身吞噬了。
  • 那是因为浏览器需要标头来允许访问响应正文。我猜,add_header 需要 always 标志
  • @AlexeyTen 所以我实际上比较了来自直接请求和代理请求的响应标头,它们是相同的。唯一不同的是,来自浏览器的代理请求包含 localhost 的 Origin 和 Referrer 标头,而非代理请求包含 X-Requested-With 标头。
  • 显示完整的服务器配置\

标签: nginx error-handling http-status-code-404 httpresponse


【解决方案1】:

我最近遇到了同样的问题。

最后一个答案是:添加代理标头升级

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';

我的完整配置如下:

upstream cloud-api {
        server 127.0.0.1:8089;
}

client_max_body_size 20M;
client_header_buffer_size 8k;
large_client_header_buffers 4 16k;

server {
        listen 8001;
        access_log  /data/senseid-cloud-log/senseid-cloud-api-access.log;
        error_log  /data/senseid-cloud-log/senseid-cloud-api-error.log warn;

        location / {
                proxy_http_version 1.1;
                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_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';

                proxy_read_timeout 300s;
                proxy_pass http://cloud-api;
        }
}

您可以捕获 500/401 .etc 错误正文

详情:http://nginx.org/en/docs/http/websocket.html

希望能给你一些帮助。

【讨论】:

    【解决方案2】:

    今天我将 Laravel 5.2 从 IIS 8.5 迁移到 Ubuntu 16.04(Nginx 1.10.0 - PHP-FPM 7.0.10),我遇到了同样的问题。当来自 Angular2 的请求时,来自服务器的正文响应始终为空。但是邮递员仍然得到了回应。 所以这一定是请求头的问题。

    这个配置帮我解决了上面的问题:

        add_header 'Access-Control-Allow-Origin' '*' 'always';
        add_header 'Access-Control-Allow-Credentials' 'true' 'always';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, HEAD' 'always';
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' 'always';
    

    add_header 的第三个参数仅在最近的 nginx 版本中可用。

    【讨论】:

      【解决方案3】:

      How to add a response header on nginx when using proxy_pass?

      1. 根据 Alexey 的评论 - “浏览器需要标头才能访问响应正文。我猜,您需要始终标记 add_header
      2. 从 nginx 1.7.5 开始,您可以使用关键字 always 在错误响应中包含标头 - 因此您可以按如下方式设置您的 nginx.conf:

      -

      server {
          server_name  .myserver.com
          location / {
              proxy_pass  http://mybackend;
              add_header X-Upstream $upstream_addr always;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-03
        • 2016-10-14
        • 2013-09-12
        • 1970-01-01
        • 2016-01-19
        • 1970-01-01
        • 1970-01-01
        • 2017-01-04
        相关资源
        最近更新 更多