Nginx proxy_pass 缺少错误正文
Nginx proxy_pass missing error body
下面是一个非常标准的 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;
}
}
我正在代理 return 的 API 响应正文包含 400、404 和 500 错误代码的错误信息。例如,在 404 上,我的响应正文可能如下所示:
{
"errorCode": "TOKEN_NOT_FOUND",
"errorMessages": [
"Could not find a matching authorization token."
]
}
如果我在没有代理的情况下执行请求,我会得到错误的响应主体。
如果我使用 nginx 代理,由于某种原因响应主体被 nginx 吞没,我什至在我的网络浏览器网络选项卡中根本看不到响应。
有没有办法告诉 Nginx return 响应主体以获取 proxy_pass 中的错误代码?
今天我将 Laravel 5.2 从 IIS 8.5 移动到 Ubuntu 16.04 (Nginx 1.10.0 - PHP-FPM 7.0.10),我遇到了同样的问题。当来自 Angular2 的请求时,来自服务器的 body 响应总是空的。但是邮递员仍然得到 body 的回应。
所以这一定是请求 headers.
的问题
这个配置帮我解决了上面的问题:
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 版本中可用。
见How to add a response header on nginx when using proxy_pass?
- 根据 Alexey 的评论 - "browsers need headers to allow access to response body. I guess, you need always flag for
add_header
"
- 从 nginx 1.7.5 开始,您可以使用关键字
always
来包含 headers,即使在错误响应中也是如此 - 因此您可以按如下方式设置 nginx.conf:
-
server {
server_name .myserver.com
location / {
proxy_pass http://mybackend;
add_header X-Upstream $upstream_addr always;
}
}
我最近 运行 遇到了同样的问题。
最后一个答案是:添加代理header升级
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 错误 body
详情:http://nginx.org/en/docs/http/websocket.html
希望能给你一些帮助。
下面是一个非常标准的 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;
}
}
我正在代理 return 的 API 响应正文包含 400、404 和 500 错误代码的错误信息。例如,在 404 上,我的响应正文可能如下所示:
{
"errorCode": "TOKEN_NOT_FOUND",
"errorMessages": [
"Could not find a matching authorization token."
]
}
如果我在没有代理的情况下执行请求,我会得到错误的响应主体。
如果我使用 nginx 代理,由于某种原因响应主体被 nginx 吞没,我什至在我的网络浏览器网络选项卡中根本看不到响应。
有没有办法告诉 Nginx return 响应主体以获取 proxy_pass 中的错误代码?
今天我将 Laravel 5.2 从 IIS 8.5 移动到 Ubuntu 16.04 (Nginx 1.10.0 - PHP-FPM 7.0.10),我遇到了同样的问题。当来自 Angular2 的请求时,来自服务器的 body 响应总是空的。但是邮递员仍然得到 body 的回应。 所以这一定是请求 headers.
的问题这个配置帮我解决了上面的问题:
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 版本中可用。
见How to add a response header on nginx when using proxy_pass?
- 根据 Alexey 的评论 - "browsers need headers to allow access to response body. I guess, you need always flag for
add_header
" - 从 nginx 1.7.5 开始,您可以使用关键字
always
来包含 headers,即使在错误响应中也是如此 - 因此您可以按如下方式设置 nginx.conf:
-
server {
server_name .myserver.com
location / {
proxy_pass http://mybackend;
add_header X-Upstream $upstream_addr always;
}
}
我最近 运行 遇到了同样的问题。
最后一个答案是:添加代理header升级
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 错误 body
详情:http://nginx.org/en/docs/http/websocket.html
希望能给你一些帮助。