OpenResty(nginx)子目录反向代理

25 年 1 月 19 日 星期日 (已编辑)
677 字
4 分钟

一般来说,子目录反向代理只需要以下配置就足够了:

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";
    }
}

我这里反代的是某个视频网站,所以我开了缓存+视频流优化,如果不需要请自行删减

反代前:

反代后:

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

文章标题:OpenResty(nginx)子目录反向代理

文章作者:butlanys

文章链接:https://blog.butlanys.de/posts/30145[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。