server 匹配server 匹配通过 listen 和server_name 进行具体如下listen定义格式IP address/portlone IP address ( default po
server 匹配
server 匹配通过 listen 和server_name 进行具体如下
listen
定义格式
- IP address/port
- lone IP address ( default port 80)
- lone port (every interface)
- path to a Unix socket
匹配
- translates
- A block with no listen directive uses the value 0.0.0.0:80.
- A block set to an IP address 111.111.111.111 with no port becomes 111.111.111.111:80
- A block set to port 8888 with no IP address becomes 0.0.0.0:8888
- match
- 有IP 高于无IP
- 端口必须匹配
- 处理
- 如果只有一个匹配则用它处理请求
- 否则继续看 server_name
server { listen 192.168.1.10; . . .}server { listen 80; server_name example.com; . . .}
server_name 会被忽略
server_name
- server_name 与 Host 头信息 精确匹配
- 如果有一个 则用它处理请求
- 如果有多个则用第一个处理请求
- 如果没有匹配继续下一个规则
- server_name 与 Host 头信息 头通配符匹配 如
*.example.com
- 如果有一个 则用它处理请求
- 如果有多个则用匹配度最长的那个
- 如果没有匹配继续下一个规则
- server_name 与 Host 头信息 尾通配符匹配 如
www.example.*
- 如果有一个 则用它处理请求
- 如果有多个则用匹配度最长的那个
- 如果没有匹配继续下一个规则
- server_name 与 Host 头信息 正则匹配 如
server_name ~[a-z].example.*
- 使用匹配到的第一个
- 如果没有匹配继续下一个规则
- server_name 与 Host 头信息 没有匹配
- 使用 server_name 与 Host 头信息
示例
server { listen 80; server_name *.example.com; . . .}server { listen 80; server_name host1.example.com; . . .}
头信息为host1.example.com
使用第二个 server块,依据精确匹配
server { listen 80; server_name www.example.*; . . .}server { listen 80; server_name *.example.org;}server { listen 80; server_name *.org; . . .}
头信息为www.example.org
使用第二个 server块,依据头通配符匹配,二和三都匹配但三匹配长些
server { listen 80; server_name host1.example.com; . . .}server { listen 80; server_name example.com; . . .}server { listen 80; server_name www.example.*; . . .}
头信息为www.example.com
使用第三个 server块,依据尾通配符匹配,
server { listen 80; server_name example.com; . . .}server { listen 80; server_name ~^(www|host1).*/.example/.com$; . . .}server { listen 80; server_name ~^(subdomain|set|www|host1).*/.example/.com$; . . .}
头信息为www.example.com
使用第二个 server块,依据正则匹配,每二个server块是匹配到的第一个
location 匹配
定义语法
location 可以在 server 内或其它 location内定义
location optional_modifier location_match { . . .}
location_match
与 请求URI 验证匹配, optional_modifier
可以有以下选择
- (none) 什么都没有则使用前缀匹配,匹配请求URI的前部分与
location_match
是否匹配 - = 等号匹配,请求URI 与
location_match
完全相同 - ~ 区分大小写正则匹配
- ~* 不区分大小写正则匹配
- ^~ 如果是非正则的最佳匹配则不再使用正则匹配
示例
location /site { . . .}
可以匹配 /site
, /site/page1/index.html
, /site/index.html
location = /page1 { . . .}
只匹配 /page1
,不 匹配/page1/index.html
location ~ /.(jpe?g|png|gif|ico)$ { . . .}
可匹配 /tortoise.jpg
不 匹配 /FLOWER.PNG
location ~* /.(jpe?g|png|gif|ico)$ { . . .}
可匹配 /tortoise.jpg
可 匹配 /FLOWER.PNG
location ^~ /costumes { . . .}
可匹配/costumes/ninja.html
如果是最佳的非正则匹配则不再进行正则匹配,(不太明白,待研究)
location 匹配规则
使用整个请求URI 与所有 前缀location 匹配
如果有
=
修饰的location
与 请求URI 完全匹配,则用它处理请求(end)如果没有
=
修饰的location
与 请求URI 完全匹配, 则查找最长匹配的 前缀location
- 如果这个最长匹配的 前缀
location
包含^~
, 则用它处理请求(end) - 如果这个最长匹配的 前缀
location
不 包含^~
,则保存此条,继续下一个规则
- 如果这个最长匹配的 前缀
开始匹配正则
location
(包括 区分大小写和不区分大小写), 如果上一规则保存的 前缀location
与任意一个正则location
匹配则将其放在最前, 然后使用第一个正则location
处理请求(end)如果没正则
location
匹配,则使用上一规则保存的 前缀location
处理请求(end)
因为正则匹配 使用第一个匹配结果,所有正则 location
是有重要意义的
- 如果都没匹配到是不是就 404了?
location 跳转
可能引起跳转的指令
- index
- try_files
- rewrite
- error_page
index
index index.html;location = /exact { . . .}location / { . . .}
请求/exact
, 但要处理这个请求,需要index
指令介入,从而导致跳转到第二个location 块(待验证)如果确实是访问 /exact
,可修改配置如下
location = /exact { index nothing_will_match; autoindex on;}location / { . . .}
(待验证)
try_files
root /var/www/main;location / { try_files $uri $uri.html $uri/ /fallback/index.html;}location /fallback { root /var/www/another;}
如果请求为/blahblah
, 则第一个location
处理此请求,尝试查找 /var/www/main
目录下有没有 blahblah
文件,如果没找到再尝试查找 目录下有没有blahblah.html
文件, 如果没有再尝试查找 目录下有没有 blahblah/
目录, 如果没有重定向到/fallback/index.html
第二个 location
处理这个请求,并访问 /var/www/another/fallback/index.html
文件
rewrite
root /var/www/main;location / { rewrite ^/rewriteme/(.*)$ /$1 last; try_files $uri $uri.html $uri/ /fallback/index.html;}location /fallback { root /var/www/another;}
如果请求为 /rewriteme/hello
, 则第一个location
处理此请求;rewrite
将请求重写为/hello
, 再次由 第一个location
处理此请求;此时由 try_files
如上一示例一样处理
而如果请求为 /rewriteme/fallback/hello
, 则先由第一个location
处理此请求;rewrite
将请求重写为/fallback/hello
, 再次由 第二个location
处理此请求;
redirect
向浏览器发送重定向指令return 301、302 new_urirewrite xxx redirect/permanent;这个批量的location都是明确的这样会发起一个新的请求
error_page
root /var/www/main;location / { error_page 404 /another/whoops.html;}location /another { root /var/www;}
如果请求 不 为 /another
,则会由第一个处理,如果请求的文件没有找到则使用第二个并最终访问 /var/www/another/whoops.html
文件
参考
翻译整理自 https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithmshttps://www.ruby-forum.com/topic/4422812#1136698