nginx的location匹配规则
匹配规则与实际路径问题
如果在server块中定义了下面内容:
1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name 10.1.1.50;
location /app {
root /usr/share/myweb;
index index.html;
}
}
此时我们去访问会发现是404,虽然路径匹配上了,但是nginx去根目录找的并不是index.html,而是/app下的index.html:
因此我们把index.html移动进app文件夹下再进行测试:
很遗憾,还是出现了错误,这里是为什么呢?
原来nginx是将app当成了一个普通的文件,而不是我们想要的文件夹📂,注意文件不一定都是有后缀的哦。
这样我们再来测试,现在知道请求什么路径了吧!
果不其然,我们总算访问到了hello world,这里如果加上/index.html也是可以访问的,大家可以自己试一试。
再然后我们把文件夹app改名为apple,再去访问:
可以发现居然访问成功了,要知道我们的nginx配置文件配置的可是/app,为什么也会访问成功呢?
1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name 10.1.1.50;
location /app {
root /usr/share/myweb;
index index.html;
}
}
这里是因为location默认匹配的是前缀,因为apple的前缀匹配上了app,所以也就能访问了,聪明的你已经想到了,这样可能会让一些我们不想要别人访问到的文件被访问,那么怎么解决这个问题呢,我们只需要在nginx的配置文件中加上一个=
号,这样就会严格的匹配路径了,再试一下发现已经无法访问了。
我们还可以使用参数~
来启用正则表达式来解锁更灵活的用法:
1
2
3
4
5
6
7
8
server {
listen 80;
server_name 10.1.1.50;
location ~ /index[1-3].html {
root /usr/share/myweb;
}
}
先在app文件夹下面生成几个文件for i in {1..9}; do echo "我是index$i 文件" > "index$i.html"; done
可以发现只有我们配置的正则表达式index1-3可以访问,另外~
是区分大小写的,而在后面加一个星号变成~*
就不会区分大小写了,注意这里是nginx不区分大小写进行路由到指定规则,到指定规则下还是要按正确的文件路径和文件名匹配的,否则也是无法访问。
这里我们看到虽然我们配置的是/app的路由规则,但是我们访问/App也访问到了内容,相反/app如果没有这个文件夹就无法访问,这里大家多理解理解。一定要确保你访问的url和实际的路径是一样的,这个大小写要严格一致,所谓的不区分大小写只是针对路由规则。
总结
- 精确匹配 (
=
)1 2 3
location = /uri { ... }
这种规则会精确匹配请求的 URI。只有当请求的 URI 完全匹配
/uri
时,才会使用该location
块中的配置。 - 前缀匹配 (
^~
)1 2 3
location ^~ /uri { ... }
这种规则会匹配以
/uri
开头的请求 URI。一旦匹配成功,Nginx 不会再检查其他location
规则。 - 正则匹配 (
~
或~*
)1 2 3 4 5 6
location ~ \.html$ { ... } location ~* \.html$ { ... }
~
表示区分大小写的正则匹配,~*
表示不区分大小写的正则匹配。例如,~ \.html$
会匹配以.html
结尾的 URI。 - 普通前缀匹配
1 2 3
location /uri { ... }
这种规则会匹配以
/uri
开头的请求 URI,但与^~
不同的是,如果存在更精确的匹配(如正则匹配),Nginx 会优先使用更精确的匹配。
匹配优先级
- 精确匹配 (
=
) - 前缀匹配 (
^~
) - 正则匹配 (
~
或~*
) - 普通前缀匹配