Skip to content

Nginx 重定向

Nginx Rewite

和Apache等Web服务软件一样,Nginx rewrite的主要功能也是实现URL地址重写。Nginx的rewrite规则需要PCRE软件的支持,即通过Perl兼容正则表达式语法进行规则匹配。默认参数编时,Nginx就会安装支持rewrite的模块,但是,也必须要有PCRE软件的支持

语法结构

nginx
rewrite 正则表达式 替换目标 [flag];

常用标记(flag)

  • last - 停止当前重写规则,用新URL重新匹配location
  • break - 停止当前重写规则,不再匹配其他规则
  • 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";
}

注意事项

  1. 性能考虑returnrewrite 更高效,优先使用
  2. 避免循环:确保重定向不会形成无限循环
  3. 测试验证:使用 curl -I 检查响应头
  4. 保留参数:使用 $request_uri 保留原始请求参数
  5. 协议处理:注意 $scheme (http/https) 变量使用