Nginx提供了rewrite指令,用于对地址进行重写,语法规则:

rewrite "用来匹配路径的正则" 重写后的路径 [指令];

我们的案例:

	server {
        listen       80;
        server_name  api.alianga.com;

        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    	# 上传路径的映射
		location /api/upload {	
			proxy_pass http://127.0.0.1:8082;
			proxy_connect_timeout 600;
			proxy_read_timeout 600;
			
			rewrite "^/api/(.*)$" /$1 break; 
        }
		
        location / {
			proxy_pass http://127.0.0.1:10010;
			proxy_connect_timeout 600;
			proxy_read_timeout 600;
        }
    }
  • 首先,我们映射路径是/api/upload,而下面一个映射路径是 / ,根据最长路径匹配原则,/api/upload优先级更高。也就是说,凡是以/api/upload开头的路径,都会被第一个配置处理
  • proxy_pass:反向代理,这次我们代理到8082端口,也就是upload-service服务
  • rewrite “^/api/(.*)$” /$1 break,路径重写:
    • “^/api/(.*)$”:匹配路径的正则表达式,用了分组语法,把/api/以后的所有部分当做1组
    • /$1:重写的目标路径,这里用$1引用前面正则表达式匹配到的分组(组编号从1开始),即/api/后面的所有。这样新的路径就是除去/api/以外的所有,就达到了去除/api前缀的目的
    • break:指令,常用的有2个,分别是:last、break
      • last:重写路径结束后,将得到的路径重新进行一次路径匹配
      • break:重写路径结束后,不再重新匹配路径。 我们这里不能选择last,否则以新的路径/upload/image来匹配,就不会被正确的匹配到8082端口了

二、Nginx rewrite 介绍

  • 主要功能是实现 URL 地址重写,需要 PCER 的支持。

  • 应用位置:serverlocationif 中都可以。

  • 语法:

    rewrite 是实现 URL 重写的关键指令,根据匹配 URL 部分的内容,重定向到目标 URL 上,结尾是 flag 标记。

    rewrite 匹配URL(正则表达式) 目标URL [flag];
    复制代码
    
  • flag 标记符号

    Flag 标记符号说明
    last本条规则匹配完成后,继续向下匹配新的 location URL 规则
    break本条规则匹配完成即终止,不再匹配后面的任何规则
    redirect返回 302 临时重定问,浏览器地址栏会显示跳转后的 URL 地址
    permanent返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址
    • lastbreak 用来实现 URL 重写,浏览器地址栏的 URL 地址不变,单在服务器端访问的程序及路径发生了变化。
    • redirectpermanent 用来实现 URL 跳转,浏览器地址栏会显示跳转后的 URL 地址。
    • redirectpermanent 的区别
      • 301 永久重定向,浏览器会记住,比如 a.com 网站 301b.com 网站,浏览器输入 a.com 时,就不请求 a.com 了,而是直接请求 b.com 了。
      • 302 临时重定向,浏览器不记住,比如 a.com 网站 302b.com 网站,浏览器输入 a.com 时,还是请求 a.com,根据 a.com 网站响应的 location 内容,再去请求 b.com 网址。

案例:

需求:nginx 配置 manager.alianga.com 的所有域名请求,转发到 http://manager.net.alianga.com 的域名上

实现方式:以下是两种常见的配置方式:

配置方式特点用户浏览器地址栏变化
return 重定向告知浏览器重新请求新地址。配置简单,效率高。会变化,显示新的目标 URL
proxy_pass 反向代理Nginx 代为请求后端服务并返回内容。后端服务器对用户隐藏。不会变化,仍显示原始请求的域名

方案一:使用 return 重定向(推荐用于直接跳转)

这种方法使用 return 指令,效率较高[citation:1]。

server {
    listen 80;
    # 监听 443 端口(如果你有 SSL 证书)
    # listen 443 ssl; 
    server_name manager.alianga.com;

    # SSL证书配置(如果需要HTTPS)
    # ssl_certificate /path/to/your/certificate.crt;
    # ssl_certificate_key /path/to/your/private.key;

    # 将所有 HTTP 请求 301 重定向到目标域名
    return 301 http://manager.net.alianga.com$request_uri;
}

说明

  • listen 80;: 监听 HTTP 的 80 端口。
  • server_name manager.alianga.com;: 指定该服务器块处理的域名。
  • return 301 ...;: 使用 301 (永久重定向) 状态码将请求重定向到目标 URL。$request_uri 变量会保留原始请求的 URI(路径和参数)并拼接到新域名后。
  • 如果你的域名已配置 SSL 证书,需要取消注释 listen 443 ssl; 和 SSL 证书相关配置,并确保 return 指令中的目标地址也使用 https://

方案二:使用 proxy_pass 反向代理(推荐用于隐藏后端或处理 API)

如果你希望用户浏览器地址栏不变,且由 Nginx 代理转发请求到目标域名并获取内容返回给用户,可以使用 proxy_pass[citation:3][citation:5]。

server {
    listen 80;
    server_name manager.alianga.com;

   location / {
             proxy_pass http://manager.net.alianga.com;
             #proxy_set_header Host $host;
            proxy_set_header Host $proxy_host;  # 传递目标域名作为Host头
            #proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链IP
            proxy_set_header X-Forwarded-Proto $scheme; # 传递原始协议(http/https)
            proxy_read_timeout 60; # 连接成功后,后端服务器响应时间
            proxy_connect_timeout 60; # ngnix 和后端连接超时时间
            proxy_buffer_size 4k;
            client_max_body_size 50m;
            proxy_buffers 6 32k;   # proxy_buffers 缓冲区
            proxy_busy_buffers_size 64k; #高负荷下缓冲器大小
            client_body_buffer_size 128k; #缓缓区代理缓冲用户端请求的最大字节数

        }
}

说明

  • proxy_pass http://manager.net.alianga.com;: 指定要代理到的上游服务器地址。
  • proxy_set_header 指令至关重要:
    • Host $host;: 将代理请求的 Host 头设置为原始请求的域名 (manager.alianga.com)。如果后端服务需要通过 Host 头来识别流量,这很有用。有时可能需要设置为 $proxy_host(即 manager.net.alianga.com)或直接写死,这取决于后端服务的配置。
    • X-Real-IP $remote_addr;: 将客户端的真实 IP 传递给后端服务器。
    • X-Forwarded-For $proxy_add_x_forwarded_for;: 追加客户端 IP 到 X-Forwarded-For 头,用于记录请求链。
    • X-Forwarded-Proto $scheme;: 告知后端服务器原始的请求协议(http 或 https)。

检查并重载 Nginx 配置

配置完成后,务必执行以下命令:

# 测试配置文件语法是否正确
nginx -t

# 如果测试成功,重新加载 Nginx 配置使其生效
nginx -s reload

✅ 关键注意事项

  1. DNS 解析:你必须确保域名 manager.alianga.comDNS 解析记录(通常是一个 A 记录或 CNAME 记录)已经指向了你正在配置的这台 Nginx 服务器的 IP 地址。否则,请求根本无法到达 Nginx。
  2. SSL/TLS 证书 (HTTPS):如果 manager.alianga.com 需要通过 HTTPS 访问,你不仅需要在 Nginx 的 server 块中配置 listen 443 ssl 并指定正确的证书和私钥路径,还需要注意:
    • 方案一中return 指令的目标URL最好也改为 https://manager.net.alianga.com$request_uri,以避免二次重定向。
    • 方案二中,如果 manager.net.alianga.com 也使用 HTTPS,那么 proxy_pass 的目标也应改为 https://manager.net.alianga.com
  3. 配置位置:可以将此配置直接放在主配置文件 nginx.confhttp {} 块内,或者为了更好的可维护性,放在 /etc/nginx/conf.d//etc/nginx/sites-available/ 目录下的一个独立配置文件(如 manager_alianga.conf``)中,然后在主文件中用include` 指令引入。
  4. 重定向类型
    • return 301 ...;永久重定向。搜索引擎会将权重和排名转移到新的 URL。请谨慎使用,确认跳转是永久性的。
    • 如果只是临时跳转,可以使用 return 302 ...;
  5. 通配符域名:如果你的 server_name 需要匹配子域(如 *.alianga.com),可以使用通配符 *.alianga.com。但根据你的问题,精确匹配 manager.alianga.com 即可。

Q.E.D.


寻门而入,破门而出