Nginx 重定向
Nginx Rewite
和Apache等Web服务软件一样,Nginx rewrite的主要功能也是实现URL地址重写。Nginx的rewrite规则需要PCRE软件的支持,即通过Perl兼容正则表达式语法进行规则匹配。默认参数编时,Nginx就会安装支持rewrite的模块,但是,也必须要有PCRE软件的支持
语法结构
nginx
rewrite 正则表达式 替换目标 [flag];常用标记(flag)
last- 停止当前重写规则,用新URL重新匹配locationbreak- 停止当前重写规则,不再匹配其他规则redirect- 返回302临时重定向permanent- 返回301永久重定向
egex常用正则表达式
| 字符 | 描述 |
|---|---|
| \ | 将后面接着的字符标记为特殊字符或原义字符。如"\n"匹配换行符,""匹配"" |
| ^ | 匹配输入字符串起始位置。设置Multiline属性后也匹配"\n"或"\r"后的位置 |
| $ | 匹配输入字符串结束位置。设置Multiline属性后也匹配"\n"或"\r"前的位置 |
| * | 匹配前面字符零次或多次,如"ol*"匹配"o"及"olll"(等价{0,}) |
| + | 匹配前面字符一次或多次,如"ol+"匹配"ol"及"oll"(等价{1,}) |
| ? | 匹配前面字符零次或一次,如"do(es)?"匹配"do"或"does"(等价{0,1}) |
| ? | 跟在限制符(*,+,?,{n})后表示非贪婪模式,尽可能少匹配 |
| . | 匹配除"\n"外的任何单个字符,匹配包括"\n"可用"[\s\S]" |
| (pattern) | 匹配括号内pattern,可通过0...9获取匹配内容,匹配括号需用"$$" |
常见应用场景
nginx
# 简单重定向
rewrite ^/旧地址$ /新地址 permanent;
# 带参数的重定向
rewrite ^/users/(.*)$ /profile/$1 last;
# 强制HTTPS
if ($scheme != "https") {
rewrite ^ https://$host$request_uri permanent;
}
# 去掉www前缀
rewrite ^(.*) http://example.com$1 permanent;
# 添加www前缀
rewrite ^(.*) http://www.example.com$1 permanent;
# 伪静态(前端控制器模式)
rewrite ^/(.*)$ /index.php?url=$1 last;
# 配置location使用
location /blog {
rewrite ^/blog/(.*)$ /news/$1 permanent;
}
location /downloads {
rewrite ^/downloads/(.*)/file$ /files/$1 last;
}经典案例
80跳转443
nginx
server {
listen 80;
server_name example.com www.example.com;
# 永久重定向到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com www.example.com;
# SSL 证书配置
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
# 其他 HTTPS 配置...
location / {
# 你的网站内容配置
}
}旧域名跳转新域名
nginx
server {
listen 80;
server_name old.com;
rewrite ^(.*) http://new.com$1 permanent;
}移动端跳转
nginx
if ($http_user_agent ~* "(mobile|android|iphone)") {
rewrite ^(.*)$ http://m.example.com$1 redirect;
}目录访问控制
nginx
location /private/ {
rewrite ^/private/(.*)$ /error/403.html last;
}根据host请求头
nginx
server {
listen 80;
server_name mail.yun.com.zh mail.yun.com.en;
if ( $http_host ~* "zh" ){
set $language zh;
}
if ( $http_host ~* "en" ){
set $language en;
}
rewrite ^/$ http://www.yunjisuan.com/$language permanent;
}last 案例
last停止当前location匹配,下面结果最终请求的是4.html。
nginx
server{
listen 80;
server_name mail.yun.com;
location / {
rewrite /1.html /2.html last;
# 不会执行下面
rewrite /2.html /3.html;
}
# 继续执行
location /2.html{
rewrite /2.html /4.html;
}
# 继续执行
location /3.html{
rewrite /3.html /5.html;
}
}break案例
break相当于exit,最终请求的是2.html
nginx
server{
listen 80;
server_name mail.yun.com;
location / {
rewrite /1.html /2.html break;
# 不会执行下面
rewrite /2.html /3.html;
}
# 不会执行
location /2.html{
rewrite /2.html /4.html;
}
# 不会执行
location /3.html{
rewrite /3.html /5.html;
}
}使用 return 指令
常见应用场景
nginx
# 301 永久重定向
return 301 https://example.com$request_uri;
# 302 临时重定向
return 302 http://example.com/new-location;
# 307 临时重定向(保持请求方法)
return 307 /maintenance.html;经典案例
强制 HTTPS
nginx
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}www 与非 www 统一
nginx
# 非www跳转到www
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
# 或者www跳转到非www
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}旧域名跳转新域名
nginx
server {
listen 80;
server_name old.com www.old.com;
return 301 https://new.com$request_uri;
}目录重定向
nginx
location /old-dir/ {
return 301 /new-dir/;
}基于用户代理
nginx
if ($http_user_agent ~* "(mobile|android|iphone)") {
return 302 https://m.example.com$request_uri;
}基于请求参数
nginx
if ($args ~* "param=old-value") {
return 301 $scheme://$host$uri?param=new-value;
}维护页面重定向
nginx
location / {
return 503 /maintenance.html;
}
error_page 503 @maintenance;
location @maintenance {
root /var/www/html;
try_files /maintenance.html =503;
}多语言重定向
nginx
if ($http_accept_language ~* "^zh") {
return 301 /zh$request_uri;
}返回固定值
nginx
location / {
return 200 "OK";
}注意事项
- 性能考虑:
return比rewrite更高效,优先使用 - 避免循环:确保重定向不会形成无限循环
- 测试验证:使用
curl -I检查响应头 - 保留参数:使用
$request_uri保留原始请求参数 - 协议处理:注意
$scheme(http/https) 变量使用
