Nginx-路由
Nginx localhost路由匹配规则
URI 即统一标识资源符,通用的 URI 语法格式如下:
scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
格式说明如下:
- 在 Nginx 的应用场景中,URL 与 URI 并无明确区别。URI 标准(RFC3986)中约定,URL 是 URI 的一个子集;
- scheme 是 URI 请求时遵守的协议,常见的有 HTTP、HTTPS、FTP;
- host[:port] 是主机名与端口号,HTTP 协议的默认端口是 80,HTTPS 协议的默认端口是 443;
- [/path] 是访问路径与访问文件名;
- [?query] 是访问参数,访问参数以“?”开始作标识,由多个以“&”连接的 key=value 形式的字符串组成。
语法 | location [= | ~ | ~* | ^~ | @] URI |
---|---|
位置 | server,location |
其中,[=||*|^~|@]部分称为 location 修饰语(Modifier),修饰语定义了与 URI 的匹配方式。URI 为匹配项,可以是字符串或正则表达式。
URI 匹配规则
uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式,那么nginx服务器在搜索匹配location的时候,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。
无修饰语
修饰符 | |
---|---|
解释 | location 后没有参数直接跟着 标准 URI,表示前缀匹配,代表跟请求中的 URI 从头开始匹配。 |
server { location /abc { ... } }
以下访问:只要以前缀abc开始就可以匹配,?后的都是访问参数
http://192.168.204.131/abc/def http://192.168.204.131/abc?p1=TOM http://192.168.204.131/abc/ http://192.168.204.131/abcdef...
修饰语 "="
修饰符 | = |
---|---|
解释 | 用于标准 URI 前,要求请求字符串与其精准匹配,成功则立即处理,nginx停止搜索其他匹配,Linux 系统下会区分大小写,Windows 系统下则不会 |
server { location =/abc { ... } }
以下访问:只能完全匹配 abc; ?后的都是访问参数
#可以匹配 http://192.168.204.131/abc http://192.168.204.131/abc?p1=TOM #匹配不到 http://192.168.204.131/abc/ http://192.168.204.131/abcdef http://192.168.204.131/abc/def
修饰语 "~ | ~*"
修饰符 | ~ | ~* |
---|---|
解释 | 用于正则 URI 前,表示 URI 包含正则表达式,~ 区分大小写,~* 不区分大小写 |
server { location ~ ^/ABCD$ { ... } } server { location ~* ^/abcd$ { ... } }
以下访问:
# ~ 匹配 http://192.168.204.131/ABCD http://192.168.204.131/ABCD?name=tom # ~ 不匹配 http://192.168.204.131/ABCD/ # ~* 匹配 http://192.168.204.131/aBcD http://192.168.204.131/abcd?p1=TOM # ~* 不匹配 http://192.168.204.131/abcd/
修饰语 "^~"
修饰符 | ^~ |
---|---|
解释 | 用于标准 URI 前,并要求一旦匹配到就会立即处理,不再去匹配其他的那些个正则 URI,一般用来匹配目录;注意,这不是一个正则表达式匹配,它的目的是优先于正则表达式的匹配 |
server { location ^~ /abc { ... } }
修饰语 "@"
修饰符 | @ |
---|---|
解释 | @ 定义一个命名的 location,@ 定义的locaiton名字一般用在内部定向,例如error_page, try_files命令中。它的功能类似于编程中的goto。 |
server { location @jump_to_error_page { default_type text/plain; return 200 "not found "; } error_page 404 =200 @jump_to_error_page; }
表示没找页面或资源,但是我正确返回了200,并通知没找到。
匹配顺序
优先级 | 修饰符 | 解释 |
---|---|---|
1 | location = | # 精准匹配 |
2 | location ^~ | # 带参前缀匹配 |
3 | location ~ | # 正则匹配(区分大小写) |
4 | location ~* | # 正则匹配(不区分大小写) |
5 | location /a | # 普通前缀匹配,优先级低于带参数前缀匹配 |
6 | location / | # 任何没有匹配成功的,都会匹配这里处理 |
案例分析
案例1
location /doc { return 701; } location ~* ^/document$ { return 702; }
curl -i localhost/document 702
按照上述的规则,显然第二个正则匹配会有更高的优先级
案例2
location /document { return 701; } location ~* ^/document$ { return 702; }
curl -i localhost/doucument 702
第二个匹配了正则表达式,优先级高于第一个普通前缀匹配
案例3
location ^~ /doc { return 701; } location ~* /document { return 702; }
curl -i localhost/document 701
第一个前缀匹配 ^~ 命中以后不会再搜寻正则匹配,所以会第一个命中
案例4
location /docu { return 701; } location /doc { return 702; } location /my { return 701; } location /myweb { return 702; }
curl -i localhost/document 701
curl -i localhost/doc 702
curl -i localhost/myweb 702
curl -i localhost /mywebm 702
前缀匹配下,返回最长匹配的 ,与 location 所在位置顺序无关
curl -i localhost/myw 701
前缀匹配下,字符串没达到最长匹配,返回短的 location;
案例 5
location ~* ^/doc[a-z]+ { return 701; } location ~* ^/docu[a-z]+ { return 702; } location ~* ^/myw[a-z]+ { return 701; } location ~* ^/my[a-z]+ { return 702; }
curl -i localhost/document 701
curl -i localhost/myweb 701
可见正则匹配是使用文件中的顺序,先匹配成功的返回。
curl -i localhost/myw 702
当完全匹配,就使用完全匹配 location;
location 实际使用建议
直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理
这里是直接转发给后端应用服务器
location = / { proxy_pass http://192.168.204.131:19901/index }
第二个必选规则是处理静态文件请求,这是 nginx 作为 http 服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用:
location ^~ /static/ { root /html/static/; } location ~* \.(gif|jpg|jpeg|png|css|js)$ { root /html/res/; }
第三个规则就是通用规则,用来转发动态请求到后端应用服务器,非静态文件请求就默认是动态请求;
location / { proxy_pass http://192.168.204.131:19901/ }