在 Nginx 中,前端反向代理至后端响应 504 Gateway Time-out 的解决

1、在 Postman 中直接请求后端接口,响应 401。符合预期。如图1

图1

2、在 Postman 中直接请求前端接口,响应 504 Gateway Time-out。不符合预期。如图2

图2

<html>

<head>
    <title>504 Gateway Time-out</title>
</head>

<body>
    <center>
        <h1>504 Gateway Time-out</h1>
    </center>
    <hr>
    <center>nginx</center>
</body>

</html>

3、在 Nginx 中的前端配置文件如下

server {
 listen 80;
    listen 443 ssl;
    server_name xxx-frontend.com;
    root E:/wwwroot/xxx-frontend/dist/apps/admin;

 access_log  logs/frontend.access.log;
    error_log   logs/frontend.error.log;

    # add_header X-Frame-Options "SAMEORIGIN";
    # add_header X-Content-Type-Options "nosniff";

 # client_max_body_size 1024M;

    ssl_certificate vhosts/xxx-frontend.com.pem;
    ssl_certificate_key vhosts/xxx-frontend.com-key.pem;

    index index.html;

    charset utf-8;

 location /api {
  proxy_pass https://xxx-backend.com/api;
 }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

4、查看后端接口的请求日志,确认在请求前端时,并没有新增加请求日志,说明请求没有到达后端。查看前端的请求错误日志,详情如下。如图3

图3

2024/01/03 11:45:21 [error] 21024#23748: *1121 upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond) while reading response header from upstream, client: 127.0.0.1, server: xxx-frontend.com, request: "POST /api/me HTTP/1.1", upstream: "https://120.79.70.168:443/api/me", host: "xxx-frontend.com"

5、直接 POST 请求 https://120.79.70.168:443/api/me ,确认无响应。点击 Disable SSL Verification 。如图4

图4

6、怀疑原因在于代理的网址本身是一个基于 FRP 实现的内网穿透的网址。决定直接代理至本地环境 127.0.0.1 的后端网址,不走 FRP。编辑 hosts 文件

127.0.0.1 xxx-frontend.com
127.0.0.1 xxx-backend.com

7、再次在 Postman 中直接请求前端接口,响应 401,与直接请求后端接口响应一致。符合预期。如图5

图5

8、但是,如此处理后,在 Chrome 浏览器中,提示网站不安全。最后不得不还原 hosts 文件的修改。

9、编辑前端的 Nginx 的配置。后端的 Nginx 配置需要监听 8000 端口。

 location /api {
  proxy_pass http://localhost:8000/api;
 }

10、再次在 Postman 中直接请求前端接口,响应 401,与直接请求后端接口响应一致。而且浏览器中也可以正常打开前端页面。如图6

图6

永夜