nginx rewrite

一、location 匹配

直接上例子

location ~ /app/(.*)\.mp3 {

    return 200 "$uri";

}

# 应该要加上 ~

# 因为这里没加上 ~,所以 curl 127.0.0.1/app2/a.mp3 会匹配到 location /

location /app2/(.*)\.mp3 {

    return 200 "$uri";

}

location / {

    return 200 "root";

}

 测试

# curl 127.0.0.1/app/a.mp3
/app/a.mp3
# curl 127.0.0.1/app2/a.mp3
root

结论:

  • 加上 ~ 表示要进行正则匹配,locaiton 右边表达式中的正则符号才会生效
  • 如果不需要正则匹配,则不要加上 ~

 二、break 和 last

直接上例子

location /download/ {

    rewrite  ^(/download/.*)/media/(.*)\..*$   $1/mp3/$2.mp3 break;

    return 403;

}

location ~ /download/a/mp3/(.*)\.mp3 {

    return 200 "$uri";

}

 2.1 break 测试

# curl http://127.0.0.1/download/a/media/a.mp3

<html>

<head><title>404 Not Found</title></head>

<body>

<center><h1>404 Not Found</h1></center>

<hr><center>nginx/1.23.1</center>

</body>

</html>

 == nginx log ==

2022/11/20 21:54:54 [notice] 7233#0: *100 "^(/download/.*)/media/(.*)\..*$" matches "/download/a/media/a.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/a/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

2022/11/20 21:54:54 [notice] 7233#0: *100 rewritten data: "/download/a/mp3/a.mp3", args: "", client: 127.0.0.1, server: localhost, request: "GET /download/a/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

2022/11/20 21:54:54 [error] 7233#0: *100 open() "/usr/local/nginx/html/download/a/mp3/a.mp3" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /download/a/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

结论:rewrite 后的 uri /download/a/mp3/a.mp3 虽然能匹配「 location ~ /download/a/mp3/(.*)\.mp3 」,但 break 的表现是直接打开 /usr/local/nginx/html/download/a/mp3/a.mp3,这里 usr/local/nginx/html/ 是 root 的路径。

2.2 last 测试

直接上例子,只是将 2.1 中的 break 改为 last

location /download/ {

    rewrite  ^(/download/.*)/media/(.*)\..*$   $1/mp3/$2.mp3 last;

    return 403;

}

location ~ /download/a/mp3/(.*)\.mp3 {

    return 200 "$uri";

}

测试 1

# curl 127.0.0.1/download/a/media/a.mp3

/download/a/mp3/a.mp3

== nginx log ==

2022/11/20 23:40:37 [notice] 13584#0: *123 "^(/download/.*)/media/(.*)\..*$" matches "/download/a/media/a.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/a/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

2022/11/20 23:40:37 [notice] 13584#0: *123 rewritten data: "/download/a/mp3/a.mp3", args: "", client: 127.0.0.1, server: localhost, request: "GET /download/a/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

结论:重写后的 uri 会再次进行 locaiton 匹配,该测试中,重写后被 「 location ~ /download/a/mp3/(.*)\.mp3 」匹配了。

 测试 2

# curl http://127.0.0.1/download/b/media/a.mp3

<html>

<head><title>403 Forbidden</title></head>

<body>

<center><h1>403 Forbidden</h1></center>

<hr><center>nginx/1.23.1</center>

</body>

</html>

== nginx log ==

2022/11/20 19:07:13 [notice] 5502#0: *80 "^(/download/.*)/media/(.*)\..*$" matches "/download/b/media/a.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/b/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

2022/11/20 19:07:13 [notice] 5502#0: *80 rewritten data: "/download/b/mp3/a.mp3", args: "", client: 127.0.0.1, server: localhost, request: "GET /download/b/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

2022/11/20 19:07:13 [notice] 5502#0: *80 "^(/download/.*)/media/(.*)\..*$" does not match "/download/b/mp3/a.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/b/media/a.mp3 HTTP/1.1", host: "127.0.0.1"

结论:重写后的 uri 再次被「 location /download/ 」匹配了,只是本次 rewrite 的处理中,uri 跟正则表达式匹配不上,所以 rewrite 后面的 return 403 起效果了。 

总结:

  • break,直接打开重写后的 uri(会默认加上 root  路径前缀)
  • last(继续),重写后的 uri 会再次进行 location 匹配,匹配到的 location 处理中可能也会配置 rewrite 指令,所以如果一个请求经历的 rewrite 处理超过 10 次的话,就会直接返回 500。

三、redirect 和 permanent(重定向)

3.1 rewrite 时加上 http(s)

直接上例子

location = /uniframe/uniframe.js {

   rewrite  ^/(.*)    http://www.baidu.com  redirect;

}

 测试 1

# curl  http://127.0.0.1/uniframe/uniframe.js  -i

HTTP/1.1 302 Moved Temporarily

Server: nginx/1.23.1

Date: Sun, 20 Nov 2022 06:30:05 GMT

Content-Type: text/html

Content-Length: 145

Connection: keep-alive

Location: http://www.baidu.com

 == nginx log ==

2022/11/20 14:29:05 [notice] 22480#0: *28 "^/(.*)" matches "/uniframe/uniframe.js", client: 127.0.0.1, server: localhost, request: "GET /uniframe/uniframe.js HTTP/1.1", host: "127.0.0.1"

2022/11/20 14:29:05 [notice] 22480#0: *28 rewritten redirect: "http://www.baidu.com", client: 127.0.0.1, server: localhost, request: "GET /uniframe/uniframe.js HTTP/1.1", host: "127.0.0.1"

3.2 rewrite 时不加上 http(s)

重定向时会自动加上 http(s)://127.0.0.1

location = /uniframe/uniframe.js {

    rewrite  ^/(.*)   /uniframe-micro/uniframe.js  permanent;

}

location ~ /uniframe-micro/uniframe.js {

    return 200 "call $uri";

}

测试 1

# curl http://127.0.0.1/uniframe/uniframe.js -i

HTTP/1.1 301 Moved Permanently

Server: nginx/1.23.1

Date: Sun, 20 Nov 2022 08:06:01 GMT

Content-Type: text/html

Content-Length: 169

Location: http://127.0.0.1/uniframe-micro/uniframe.js

Connection: keep-alive

 == nginx log ==

2022/11/20 16:06:01 [notice] 31665#0: *42 "^/(.*)" matches "/uniframe/uniframe.js", client: 127.0.0.1, server: localhost, request: "GET /uniframe/uniframe.js HTTP/1.1", host: "127.0.0.1"

2022/11/20 16:06:01 [notice] 31665#0: *42 rewritten redirect: "/uniframe-micro/uniframe.js", client: 127.0.0.1, server: localhost, request: "GET /uniframe/uniframe.js HTTP/1.1", host: "127.0.0.1"

总结:

  • permanent 和 redirect 的区别,只是 301 和 302 的区别,其他地方一致。
  • 重定向会触发客户端再次发起请求,用 postman 测试的话,在 nginx 的 access.log 中可以看到客户端先后发起了两次请求。但用 curl 测试时,不会对 301/302 返回的 Location 头部中的重定向链接自动发起请求。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值