Weber博客

分享知识,记录思考

解决Nginx代理接口504超时问题:一次跨域配置的实战记录

2025年5月26日
Nginx

问题背景

最近我在部署一个项目时遇到了一个棘手的问题:在一台服务器上同时部署了博客网站(使用域名aimaji.top访问)和后台管理系统(直接使用服务器IP访问)。部署完成后,后台管理系统调用接口时一直报超时错误。

初步排查

首先我意识到问题可能出在跨域访问上:

  • 博客使用域名访问

  • 后台使用IP访问

  • 两者需要调用相同的API接口

Nginx代理配置

我尝试通过Nginx配置代理来解决这个问题:

location /api {
    proxy_pass http://aimaji.top/api;
    proxy_set_header Host $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;
}

这个配置的目的是将所有以/api开头的请求转发到http://aimaji.top/api。然而,配置后接口一直无响应,报504网关超时错误。

深入排查:查看Nginx错误日志

通过查看Nginx错误日志(/www/wwwlogs/***.error.log),发现了关键错误信息:

[error] 2943572#0: *13293 upstream timed out (110: Connection timed out) while reading response header from upstream, 
client: 120.79.69.***, 
server: 120.79.69.***, 
request: "GET /api/administrator HTTP/1.1", 
upstream: "http://120.79.69.***/api/administrator", 
host: "120.79.69.***"

发现问题所在

从错误日志可以看出:

  1. 我配置的proxy_pass http://aimaji.top/api本应转发到aimaji.top

  2. 但实际上请求被转发到了服务器自身的IP地址120.79.69.***

  3. 这导致了请求循环和超时

解决方案

问题出在Host头的设置上。我原本使用$host变量(即客户端请求的Host头),这导致Nginx将请求转发到自身。正确的做法是指定目标主机:

location /api {
    proxy_pass http://aimaji.top/api;
    proxy_set_header Host aimaji.top;  # 明确指定目标主机
    # 其他配置...
}

为什么这样能解决问题?

  1. Host头的重要性:很多Web服务器使用Host头来确定要服务的网站

  2. 原始配置的问题:使用$host会传递客户端的Host头(IP地址),导致Nginx尝试在本地解析

  3. 新配置的优点:明确指定aimaji.top确保请求被正确转发到目标域名

经验总结

  1. 日志是你的好朋友:遇到Nginx问题时,第一时间查看错误日志

  2. 理解Host头的作用:在代理配置中,Host头的设置至关重要

  3. 避免请求循环:确保代理不会将请求转发回自身

  4. 明确优于隐式:有时候明确指定值比使用变量更可靠

希望这篇记录能帮助遇到类似问题的开发者少走弯路!

文章评论

发表评论

全部评论 (0)

加载评论中...