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
的支持。 -
应用位置:
server
、location
、if
中都可以。 -
语法:
rewrite
是实现URL
重写的关键指令,根据匹配URL
部分的内容,重定向到目标URL
上,结尾是flag
标记。rewrite 匹配URL(正则表达式) 目标URL [flag]; 复制代码
-
flag
标记符号Flag 标记符号 说明 last 本条规则匹配完成后,继续向下匹配新的 location URL 规则 break 本条规则匹配完成即终止,不再匹配后面的任何规则 redirect 返回 302 临时重定问,浏览器地址栏会显示跳转后的 URL 地址 permanent 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址 last
和break
用来实现URL
重写,浏览器地址栏的URL
地址不变,单在服务器端访问的程序及路径发生了变化。redirect
和permanent
用来实现URL
跳转,浏览器地址栏会显示跳转后的URL
地址。redirect
与permanent
的区别301
永久重定向,浏览器会记住,比如a.com
网站301
到b.com
网站,浏览器输入a.com
时,就不请求a.com
了,而是直接请求b.com
了。302
临时重定向,浏览器不记住,比如a.com
网站302
到b.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
✅ 关键注意事项
- DNS 解析:你必须确保域名
manager.alianga.com
的 DNS 解析记录(通常是一个 A 记录或 CNAME 记录)已经指向了你正在配置的这台 Nginx 服务器的 IP 地址。否则,请求根本无法到达 Nginx。 - 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
。
- 方案一中,
- 配置位置:可以将此配置直接放在主配置文件
nginx.conf
的http {}
块内,或者为了更好的可维护性,放在/etc/nginx/conf.d/
或/etc/nginx/sites-available/
目录下的一个独立配置文件(如manager_alianga.conf``)中,然后在主文件中用
include` 指令引入。 - 重定向类型:
return 301 ...;
是永久重定向。搜索引擎会将权重和排名转移到新的 URL。请谨慎使用,确认跳转是永久性的。- 如果只是临时跳转,可以使用
return 302 ...;
。
- 通配符域名:如果你的
server_name
需要匹配子域(如*.alianga.com
),可以使用通配符*.alianga.com
。但根据你的问题,精确匹配manager.alianga.com
即可。
Q.E.D.