6-nginx rewrite

nginx.jpg

Nginx Rewrite

  1. rewrite 指令的位置
    rewrite 指令确实可以放置在 server、location 或 if 块中。

  2. rewrite 匹配的范围
    rewrite 指令只对域名后的路径部分(即 URL 中的路径部分)起作用,不包括查询参数(query string)和片段标识符(fragment identifier)。具体来说:

路径部分:例如 http://192.168.27.11:9090/targets 中的 /targets。
查询参数:例如 http://192.168.27.11:9090/targets?search=pool-prometheus 中的 ?search=pool-prometheus。
片段标识符:例如 http://192.168.27.11:9090/targets#pool-prometheus 中的 #pool-prometheus。

  1. 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server {
    listen 80;
    server_name example.com;

    location /old {
    rewrite ^/old/(.*)$ /new/$1 permanent;
    }
    }

    # 访问 http://example.com/old/path?param=value#fragment
    # 会被重定向到 http://example.com/new/path?param=value#fragment

基本语法

1
rewrite regex replacement [flag];
  • regex: 正则表达式,用于匹配 URL。
  • replacement: 重写后的 URL,可以包含 Nginx 内置变量,如 $host 表示请求的主机名。
  • flag: 标记,控制重写行为。

常见标记

  • last: 终止当前 location 块中的处理,并将重写后的 URI 作为新的 URI 进行处理。通常用于内部重定向。
  • break: 将重写后的 URI 在当前 location 块中继续处理,不会将新的 URI 转移到其他 location 块。
  • redirect: 返回 302 临时重定向,浏览器地址栏会显示跳转后的 URL。下次访问同一个 URL 时,浏览器会重新发起请求,而不是直接跳转到上次重定向的 URL。
  • permanent: 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL。

示例

1. 临时重定向

1
2
3
4
5
server {
listen 80;
server_name old_web.com;
rewrite ^/ http://www.new_web.com/ redirect; # 使用 302 临时重定向,浏览器地址栏会显示跳转后的 URL
}

2. 永久重定向

1
2
3
4
5
server {
listen 80;
server_name old_web.com;
rewrite ^/ http://www.new_web.com/ permanent; # 使用 301 永久重定向,浏览器地址栏会显示跳转后的 URL
}

3. 内部重定向

1
2
3
4
5
6
7
8
9
10
server {
listen 80;
server_name example.com;
location /old {
rewrite ^/old/(.*)$ /new/$1 last; # 使用 last 标志,终止当前 location 块中的处理,并将重写后的 URI 作为新的 URI 进行处理
}
location /new {
# 处理新路径
}
}

4. 条件重定向

1
2
3
4
5
6
7
server {
listen 80;
server_name test1.com test2.com;
if ($host ~ test) { # 如果请求的主机名包含 "test"
rewrite ^(.*)$ http://www.test3.com/$1 permanent; # 使用 301 永久重定向到新的 URL
}
}

if 语句

if 语句用于在 serverlocation 块中进行条件判断。常见的条件包括:

  • 变量名: 变量的值为 0 或空字符串时,条件为 false
  • 变量与字符串相等: 使用 =!=,判断变量和字符串是否相等。
  • 变量与字符串匹配: 使用 ~(区分大小写)和 ~*(不区分大小写),判断变量值是否包含正则匹配内容。
  • 文件存在: 使用 -f!-f,判断文件是否存在。
  • 目录存在: 使用 -d!-d,判断目录是否存在。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 80;
server_name example.com;

if ($http_user_agent ~* "MSIE") { # 如果 User-Agent 包含 "MSIE"(不区分大小写)
rewrite ^(.*)$ /ie.html break; # 使用 break 标志,重定向到 /ie.html 并停止进一步处理
}

if (-f $request_filename) { # 如果请求的文件存在
break; # 停止进一步处理
}

if (-d $request_filename) { # 如果请求的目录存在
break; # 停止进一步处理
}

location / {
try_files $uri $uri/ /index.html; # 尝试匹配文件、目录或默认到 index.html
}
}

break 语句

break 语句用于中断当前作用域中的其他 Nginx 配置,使得 break 之前的指令生效,之后的指令不生效。可以在 serverlocationif 中使用。

示例

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name example.com;

location /test {
if ($arg_test = "yes") { # 如果请求参数 test 等于 "yes"
rewrite ^/test$ /test2 break; # 使用 break 标志,重定向到 /test2 并停止进一步处理
}
# 以下指令不会被执行
proxy_pass http://backend; # 这条指令不会被执行,因为前面的 break 已经停止了进一步处理
}
}

return 语句

return 语句用于直接向客户端返回响应状态码。可以在 serverlocationif 中使用。

示例

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name example.com;

location /maintenance {
return 503; # 直接返回 503 Service Unavailable 状态码
}

location /redirect {
return 301 http://www.newsite.com/; # 直接返回 301 永久重定向到新的 URL
}
}

set 语句

set 语句用于设置一个新的变量。

示例

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name example.com;

set $test_name "Hello, World!"; # 设置一个名为 $test_name 的变量,值为 "Hello, World!"
location / {
return 200 $test_name; # 返回 200 OK 状态码,并返回变量 $test_name 的值
}
}

rewrite_log 语句

rewrite_log 语句用于开启或关闭 rewrite 日志输出功能。

示例

1
2
3
4
5
6
7
8
9
10
server {
listen 80;
server_name example.com;

rewrite_log on; # 开启 rewrite 日志记录

location / {
rewrite ^/old/(.*)$ /new/$1 last; # 使用 last 标志,终止当前 location 块中的处理,并将重写后的 URI 作为新的 URI 进行处理
}
}

总结

通过上述配置和示例,你可以更好地理解和使用 Nginx 的 rewrite 模块。rewrite 模块在处理 URL 重写和重定向方面非常强大,可以帮助你优化网站的访问体验和 SEO 效果。希望这些内容对你有所帮助!