一般来说,子目录反向代理只需要以下配置就足够了:
nginx
location ^~ /test/ {
proxy_pass https://example.com;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
add_header X-Cache $upstream_cache_status;
add_header Cache-Control no-cache;
proxy_ssl_server_name off;
proxy_ssl_name $proxy_host;
}每条配置解释:
location ^~ /test/: 匹配以/test/开头的 URL 请求。^~表示优先匹配。proxy_pass https://example.com;: 将请求转发到https://example.com。proxy_set_header: 设置请求头,将一些客户端信息传递给后端服务器。Host example.com;: 将请求头中的 Host 字段设置为example.com,这是必须的,否则后端服务器可能无法正确处理请求。X-Real-IP $remote_addr;: 传递客户端的真实 IP 地址。X-Forwarded-For $proxy_add_x_forwarded_for;: 追加客户端的 IP 地址到 X-Forwarded-For 头部,用于记录完整的请求链路。REMOTE-HOST $remote_addr;: 传递客户端的主机名(通常是 IP 地址)。Upgrade $http_upgrade;和Connection $http_connection;: 用于支持 WebSocket 代理。X-Forwarded-Proto $scheme;: 传递请求的协议 (http 或 https)。
proxy_http_version 1.1;: 设置 HTTP 协议版本为 1.1。add_header X-Cache $upstream_cache_status;: 添加一个响应头,显示缓存状态 (HIT, MISS, EXPIRED 等)。add_header Cache-Control no-cache;: 设置响应头,指示客户端不要缓存响应。proxy_ssl_server_name off;: 关闭 SNI (Server Name Indication)。proxy_ssl_name $proxy_host;: 设置用于验证后端服务器证书的域名。
但实际使用会发现,如果反向代理的是一些有绝对路径的网站,就会出现 404 错误。
举个例子:
假设我们使用上述配置将 /test/ 映射到 https://example.com。当访问 http://your_server/test/ 时,Nginx 会将其代理到 https://example.com/。这通常没有问题。
但是,如果 https://example.com 的网页中有一个资源的链接是绝对路径,例如:
html
<img src="/images/logo.png">当浏览器解析到这个标签时,它会尝试请求 http://server/images/logo.png,而不是 http://server/test/images/logo.png。由于服务器上 /images/logo.png 路径并不存在,就会导致 404 错误。
问题的原因在于,当网站使用绝对路径时,浏览器会根据当前的域名来拼接完整的 URL,而忽略了反向代理的子目录 /test/。
使用rewrite重写url
nginx
location ^~ /test/ {
rewrite ^/test/(.*)$ /$1 break; # 重写 URL
proxy_pass https://example.com;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache off;
proxy_ssl_server_name on;
proxy_ssl_name example.com;
add_header Strict-Transport-Security "max-age=31536000";
proxy_set_header X-Accel-Buffering no;
add_header X-Proxy-Cache $upstream_cache_status;
tcp_nodelay on;
location ~* /test/.*\.(css|js)$ {
rewrite ^/test/(.*)$ /$1 break;
proxy_pass https://example.com;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_key "$scheme$proxy_host$uri";
proxy_ssl_server_name on;
proxy_ssl_name example.com;
expires 7d;
add_header Cache-Control "public";
}
}我这里反代的是某个视频网站,所以我开了缓存+视频流优化,如果不需要请自行删减
反代前:

反代后:

虽然不知道为什么反代之后资源只会一个个加载了,但起码视频流是正常的,速度比反代前高得多