天天看点

Nginx:location匹配规则

语法规则

location [ = | ~ | ~* | ^~ | @ ] uri { ... }
location @name { ... }
location uri { ... }  // 没有修饰符
           
  • =

    :精确匹配。只有请求的url路径与配置的字符串完全相等时,才会命中
  • ^~

    :前缀匹配,在正则匹配前执行,且如果该项匹配上,则不再进行匹配
  • ~

    :正则匹配,但是区分大小写
  • ~*

    :正则匹配,不区分大小写
  • 没有修饰符

    :普通匹配,当上面都匹配不上时,再进行该匹配
  • @

    :"@" 定义一个命名的 location,使用在内部定向时,例如 error_page

注意:在前缀匹配和普通匹配中,按最大匹配原则进行匹配。比如在前缀匹配:

location /dir01

location /dir01/dir02

,如有请求

http://localhost/dir01/dir02/file

将最终匹配到

location /dir01/dir02

,但请求

http://localhost/dir01/dir

会匹配到

location /dir01

匹配规则

  1. 先进行(

    =

    )精确匹配,命中后不再匹配
  2. 再进行(

    ^~

    )前缀匹配,全部匹配一次,命中最大匹配的规则,命中后不再匹配
  3. ~

    |

    ~*

    )正则匹配,命中第一个匹配成功的,命中后不再匹配
  4. 进行(

    没有修饰符

    )普通匹配,全部匹配一次,命中最大匹配的规则
  5. 以上规则都没有命中,则报错404

例子

可以自行修改下面的例子去验证,这里就不一一说明(注意:网络上一些文章描述的规则是错误的,建议自行验证)。

server {
    listen 1999;
    listen [::]:1999;
    server_name your_host;
    location /api/refresh {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultH redirect;
    }
    location ~* \.(jpg)$ {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultI redirect;
    }
    location ~ \.(gif|jpg|png|js|css)$ {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultG redirect;
    }
    location ~* \.(gif2|jpG|png|js|css)$ {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultJ redirect;
    }
    location ^~ /api {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultF redirect;
    }
    location = /api {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultA redirect;
    }
    location = /login {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultB redirect;
    }
    location ^~ /api/login {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultD redirect;
    }
    location / {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultE redirect;
    }
    location /demo {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultK redirect;
    }
    location /demo/run {
        rewrite ^(.*) https://www.baidu.com/s?wd=ResultL redirect;
    }
}
           

location @name的用法

@用来定义一个命名location。主要用于内部重定向,不能用来处理正常的请求。其用法如下:

location / {
    try_files $uri $uri/ @reset
}
location @reset {
    # ...do something
}
           

继续阅读