参考nginx中文站文档
nginx配置中location解析
- 类型
- 普通location:location using literal strings
- 正则location:location using regular expressions
- 语法格式: location[=||*|^~] /uri/ {}
- 普通location
=
路径完全匹配^~
^ 表示“非”,~ 表示“正则”,字符意思是:不要继续匹配正则@
- 无任何前缀
- 正则location:
~*
大小写不敏感~
大小写敏感
- 普通location
- 作用域: server
注意
-
uri不包含查询字符串(querystring)
-
uri前缀可选,不同的前缀具有不同的含义
-
对于一个待定的http请求,当有多个location时,匹配规则:先匹配普通location,再匹配正则location
-
多个普通location之间按照最大前缀匹配
-
#请求 http://localhost/prefix/mid/file.html #多个普通location location /prefix/{#这能匹配到} location /prefix/mid/ {#这能匹配到,且符合前缀最大,所以走此规则}
-
-
普通location的最大前缀匹配
只是一个**“临时结果”**,还需要找正则location,正则location按server中编辑的顺序执行查找,查到就停止且普通location获得的临时结果被覆盖,没找到则匹配到 “临时结果”-
#请求 http://localhost/prefix/mid/file.html #普通location location /prefix/mid/{#这能匹配到,取得临时结果} #正则location,多条就按顺序匹配,找到就停止,否则继续查找 ## 能匹配到 location ~ /prefix/mid/*\.html {#这能匹配到,覆盖临时结果} ## 不能匹配到 location ~ /prefix/mid/*\.htm {#这不能匹配到,走临时结果}
-
-
=
与^~
的比较-
相同点: 都可以阻止继续搜索正则location
-
不同点:
^~
依然遵守最大前缀匹配;=
表示严格匹配 -
location / {} #遵守普通location 的最大前缀匹配,由于任何URI 都必然以“/ ”根开头,有点默认配置的味道,其他更specific的配置能覆盖overwrite 这个默认配置(这也是为什么我们总能看到 这个配置的一个很重要的原因) location = / {} #遵守的是“严格精确匹配exact match ”,也就是只能匹配 http://host:port/ 请求,同时会禁止继续搜索正则location 。因此如果我们只想对“GET / ”请求配置作用指令,那么我们可以选“location = / {} ”这样能减少正则location 的搜索,因此效率比“location / {}” 高(注:前提是我们的目的仅仅只想对“GET / ”起作用)
-
-
@
- 用来定义“Named Location ”的(你可以理解为独立于“普通location (location using literal strings )”和“正则location (location using regular expressions )”之外的第三种类型
- 这种“Named Location ”不是用来处理普通的HTTP 请求的,它是专门用来处理“内部重定向(internally redirected )”请求的
- 注意:这里说的“内部重定向(internally redirected )”或许说成“forward ”会好点,以为内internally redirected 是不需要跟浏览器交互的,纯粹是服务端的一个转发行为
例子
server {
listen 8090;
server_name localhost;
location / {
root html;
index index.html index.htm;
deny all;
}
location ~ \.html$ {
alllow all;
}
}
#上述配置的意思是: location / {… deny all;} 普通 location 以“ / ”开始的 URI 请求(注意任何 HTTP 请求都必然以“/ ”开始,所以“ / ”的意思是所有的请求都能被匹配上),都拒绝访问; location ~\.html$ {allow all;} 正则 location以 .html 结尾的 URI 请求,都允许访问。
URI请求 | 结果 |
---|---|
curl http://localhost:8090/ | 403 |
curl http://localhost:8090/index.html | hello world |
curl http://localhost:8090/index_notfound.html | 404 |
# @ 的用法
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
allow all;
}
#error_page 404 http://www.baidu.com # 直接这样是不允许的
error_page 404 = @fallback;
location @fallback {
proxy_pass http://www.baidu.com;
}
}
#如果请求的 URI 存在,则本 nginx 返回对应的页面;如果不存在,则把请求代理到baidu.com 上去做个弥补(注: nginx 当发现 URI 对应的页面不存在, HTTP_StatusCode 会是 404 ,此时error_page 404 指令能捕获它)。
总结
正则 location 匹配让步普通location 的严格精确匹配结果;但覆盖普通 location 的最大前缀匹配结果