Nginx代理导致API 500错误的排查与修复指南

 更新时间:2026年07月02日 08:38:05   作者:SebastianLiam  
前端访问 http://localhost:9527/dev-api/Login/getStaticResource 返回 500 Internal Server Error,直接访问 http://anyu-portal.test/ 正常,所以本文给大家介绍了Nginx代理导致API 500错误的排查与修复指南,需要的朋友可以参考下

问题描述

前端访问 http://localhost:9527/dev-api/Login/getStaticResource 返回 500 Internal Server Error,直接访问 http://anyu-portal.test/ 正常。

技术栈

  • 前端:Vue.js + Vue CLI (devServer proxy)
  • 后端:ThinkPHP 5.x + PHP 7.4
  • 容器:Docker Compose (nginx, php-fpm)
  • 代理:Nginx 反向代理

请求链路分析

浏览器 localhost:9527/dev-api/Login/getStaticResource
    ↓ Vue devServer proxy (vue.config.js)
Nginx anyu-portal-frontend.test/api/Login/getStaticResource
    ↓ Nginx location /api/ proxy_pass (anyu-front.conf)
Nginx anyu-portal.test/Login/getStaticResource
    ↓ Nginx location ~ .php$ fastcgi_pass (anyu-portal.conf)
PHP-FPM anyu-portal/Public/index.php

配置文件检查

1. Vue devServer 代理配置

vue.config.js

proxy: {
  [process.env.VUE_APP_BASE_API]: {
    target: 'http://anyu-portal-frontend.test/api',
    changeOrigin: true,
    pathRewrite: {
      ['^' + process.env.VUE_APP_BASE_API]: ''
    }
  }
}

VUE_APP_BASE_API = /dev-api,所以:

  • 请求 /dev-api/Login/getStaticResource
  • 被转发到 http://anyu-portal-frontend.test/api/Login/getStaticResource

2. Nginx 前端站点配置

anyu-front.conf

server {
    listen 80;
    server_name anyu-frontend.test *.anyu-frontend.test;
    root "/www/anyu-portal-frontend";
    location / {
        try_files $uri $uri/ /index.html;
    }
    location /api/ {
        proxy_set_header Host $http_x_forwarded_host;
        proxy_pass http://anyu-portal.test/;
    }
}

3. Nginx 后端站点配置

anyu-portal.conf

server {
    listen 80;
    server_name anyu-portal.test;
    root /www/anyu-portal/Public;
    if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php?s=$1 last;
    }
    location ~ \.php$ {
        fastcgi_pass php:9000;
        include fastcgi-php.conf;
        include fastcgi_params;
    }
}

4. Docker Compose 网络配置

docker-compose.yml

services:
  nginx:
    extra_hosts:
      - "openapi:127.0.0.1"
      - "lvs:127.0.0.1"
      - "admin:127.0.0.1"
      - "portal:127.0.0.1"
    # 缺少: anyu-portal.test:127.0.0.1

排查过程

步骤 1:直接测试后端 API

从 nginx 容器内部直接访问后端:

docker exec nginx curl -v http://anyu-portal.test/Login/getStaticResource

结果:返回 200 OK,后端 API 本身正常。

步骤 2:测试代理链路

从 nginx 容器内部通过前端域名访问:

docker exec nginx curl -v http://anyu-portal-frontend.test/api/Login/getStaticResource

结果:返回 500 Internal Server Error。

步骤 3:检查 Host 头问题

直接访问时 curl 会发送 Host: anyu-portal.test,但通过 /api/ 代理时:

proxy_set_header Host $http_x_forwarded_host;

$http_x_forwarded_host 是客户端请求的 X-Forwarded-Host 头,通常为空。当 Host 头为空时,后端 ThinkPHP 的 getStaticResource 方法无法正确识别 SERVER_NAME,导致找不到合作伙伴配置。

步骤 4:检查域名解析

nginx 容器的 extra_hosts 中没有配置 anyu-portal.test,虽然之前已经添加了,但需要确认是否生效。

根因分析

问题有两个层面:

  1. Host 头为空proxy_set_header Host $http_x_forwarded_host; 设置了一个通常为空的变量,导致转发到后端时没有正确的 Host 头。
  2. 域名解析:nginx 容器内部无法解析 anyu-portal.test(虽然之前已添加到 extra_hosts)。

后端 ThinkPHP 的 getStaticResource 方法依赖 SERVER_NAME 获取合作伙伴配置:

public function getStaticResource() {
    $server_name = SERVER_NAME;  // 依赖 $_SERVER['SERVER_NAME']
    $redis = new Redis();
    $redis->connect(C("REDIS_HOST"), C("REDIS_PORT"));
    // ...
    if(!C('PARTNER')) {
        $this->setPartner($redis, $server_name);  // 根据 server_name 获取合作伙伴
    }
    // ...
}

当 Host 头为空或不正确时,SERVER_NAME 无法正确识别,导致 C('PARTNER') 为空,后续操作失败。

修复方案

修复 1:修改 Nginx 代理配置

文件services/nginx/conf.d/anyu-front.conf

# 修改前
location /api/ {
    proxy_set_header Host $http_x_forwarded_host;
    proxy_pass http://anyu-portal.test/;
}
# 修改后
location /api/ {
    proxy_set_header Host anyu-portal.test;
    proxy_pass http://anyu-portal.test/;
}

修复 2:添加域名解析

文件docker-compose.yml

services:
  nginx:
    extra_hosts:
      - "openapi:127.0.0.1"
      - "lvs:127.0.0.1"
      - "admin:127.0.0.1"
      - "portal:127.0.0.1"
      - "anyu-portal.test:127.0.0.1"  # 新增

修复 3:重载 Nginx 配置

docker exec nginx nginx -s reload

验证

docker exec nginx curl -v http://anyu-portal-frontend.test/api/Login/getStaticResource

结果:返回 200 OK,JSON 数据正常。

总结

经验教训

  1. Host 头很重要:反向代理时,proxy_set_header Host 必须设置正确的值,后端框架(如 ThinkPHP)依赖它来识别当前站点。
  2. 容器内部域名解析:Docker Compose 的 extra_hosts 只对容器内部生效,宿主机的 hosts 文件不会自动同步到容器。
  3. 排查顺序:先测试直接访问后端,再测试完整代理链路,定位问题出在哪一层。
  4. 变量陷阱$http_x_forwarded_host 是客户端请求头,不是 Nginx 内置变量,不要误以为它会自动填充。

最佳实践

location /api/ {
    proxy_set_header Host $proxy_host;  # 使用 proxy_pass 中指定的主机名
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://backend/;
}

使用 $proxy_host 可以自动获取 proxy_pass 中指定的主机名,比硬编码更灵活。

以上就是Nginx代理导致API 500错误的排查与修复指南的详细内容,更多关于Nginx代理导致API 500错误的资料请关注脚本之家其它相关文章!

相关文章

  • nginx中proxy_pass各种用法详解

    nginx中proxy_pass各种用法详解

    nginx中配置location代理转发规则的时候不同写法对应不同转发规则。本文就介绍几种常见的匹配情况,感兴趣的可以了解一下
    2021-11-11
  • shell脚本定时统计Nginx下access.log的PV并发送给API保存到数据库

    shell脚本定时统计Nginx下access.log的PV并发送给API保存到数据库

    这篇文章主要介绍了shell脚本定时统计Nginx下access.log的PV并发送给API保存到数据库的实现方法 ,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • Nginx添加内置模块过程

    Nginx添加内置模块过程

    文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验证功能
    2025-08-08
  • 国内一些常用PHP的CMS的Nginx服务器的伪静态规则整理

    国内一些常用PHP的CMS的Nginx服务器的伪静态规则整理

    当我们从apache服务器转向Nginx服务器的时候,它们的伪静态规则就不一样了,所以你熟悉Nginx服务器的伪静态规则,自己写当然也好
    2011-03-03
  • Nginx实现精准IP访问控制的方法全攻略

    Nginx实现精准IP访问控制的方法全攻略

    在日常服务器运维、前后端联调、测试环境部署中,精准控制访问权限是高频且核心的需求,Nginx 作为当下最流行的 Web 服务器和反向代理工具,本文将从基础用法入手,结合实际测试场景,拆解 Nginx IP 访问控制的核心指令、实用技巧、常见坑点,需要的朋友可以参考下
    2026-03-03
  • Nginx手动编译、安装超详细教程

    Nginx手动编译、安装超详细教程

    Nginx安装除了编译以外,我们还可以直接用操作系统上自带的工具比如说yum、apt-get直接安装,这篇文章主要介绍了Nginx手动编译、安装超超详解,需要的朋友可以参考下
    2023-09-09
  • Nginx+SSL+Node.js运行环境配置教程

    Nginx+SSL+Node.js运行环境配置教程

    这篇文章主要介绍了Nginx+SSL+Node.js运行环境配置教程,本文用反向代理的方式代理基于Node.js的Web应用,需要的朋友可以参考下
    2014-09-09
  • 强大的 Web 应⽤服务器OpenResty安装(Nginx仓库)

    强大的 Web 应⽤服务器OpenResty安装(Nginx仓库)

    OpenResty 是⼀个强大的 Web 应⽤服务器,Web 开发⼈员可以使用 Lua 脚本语⾔调动 Nginx ⽀持的各种 C 以及 Lua 模块,更主要的是在性能方面,OpenResty可以快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统
    2023-06-06
  • nginx.conf配置两个前端路径

    nginx.conf配置两个前端路径

    本文主要介绍了nginx.conf配置两个前端路径,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • 详解Nginx HTTP负载均衡和反向代理配置

    详解Nginx HTTP负载均衡和反向代理配置

    这篇文章主要介绍了详解Nginx HTTP负载均衡和反向代理配置,有需要的同学可以了解一下。
    2016-11-11

最新评论