NginxLocation详细总结

编程

上一篇文章我们用echo模块做了试验,这次我们来看看官方文档,这是地址: http://nginx.org/en/docs/http/ngx_http_core_module.html#location , 我尝试着翻译如下。

正文

Syntax:

语法

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

Default:

默认

Context:

使用场景/语境

serverlocation

Sets configuration depending on a request URI. 基于请求uri的配置规则

The matching is performed against a normalized URI, after decoding the text encoded in the “%XX” form, resolving references to relative path components “.” and “..”, and possible compression of two or more adjacent slashes into a single slash. 匹配针对从"%xx"格式的文本解码之后的正常的uri生效,解析相对路径引用 "." 和 "..",以及将两个或更多的相邻的斜杠压缩成单斜杠。

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

Location 可以用前缀字符串定义,或者正则表达式。正则表达式前面带有 ~* 修饰 (大小写不敏感匹配) ,或者 ~ 修饰 (大小写敏感匹配). 为了找到和一个给定的请求相匹配的location,nginx 首先检查 带了前缀字符串的location(也叫前缀location). 在它们当中,拥有最长的匹配前缀的location将被选中并被记录下来。然后按照在配置文件中的先后顺序,依次检查正则表达式。正则表达式的搜索会在第一个匹配的时候终止,然后相应的配置将被使用。如果没有命中正则表达式,则会使用之前被记录下来的前缀location。

location blocks can be nested, with some exceptions mentioned below.

location 模块可以被嵌套,以下是一些例外情况:

For case-insensitive operating systems such as macOS and Cygwin, matching with prefix strings ignores a case (0.7.7). However, comparison is limited to one-byte locales. 对于大小写不敏感的操作系统,例如macOS和Cygwin,匹配前缀字符串会忽略一个大写(0.7.7版本). 然而,比较被限制在单字节的地方。

Regular expressions can contain captures (0.7.40) that can later be used in other directives. 正则表达式可以包含匹配,这些匹配可以在后续其他指令中被用到的。(0.7.40版本)

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked. 如果最长的匹配到的前缀location带有 ^~ 修饰符,那么正则表达式将不会被检查。

Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.

同时,使用 "=" 修饰符可能定义一个精准匹配的uri和location. 如果找到了一个精准匹配,那么查询就会终止。例如,如果一个 "/" 请求经常出现,那么定义 "location = /" 将加快处理这些请求的速度,因为搜索会在第一次比较之后就结束。这种location很显然不能包含嵌套的location.

In versions from 0.7.1 to 0.8.41, if a request matched the prefix location without the “

=” and “

^~” modifiers, the search also terminated and regular expressions were not checked.

在 0.7.1 到 0.8.41 的版本中,如果一个请求命中了 不含有 "=" 或 "^~" 修饰符的前缀location,搜索也会终止,且正则表达式不会被检查到。

Let’s illustrate the above by an example: 让我们用一个例子来展示以上的内容:

location = / {

[ configuration A ]

}

location / {

[ configuration B ]

}

location /documents/ {

[ configuration C ]

}

location ^~ /images/ {

[ configuration D ]

}

location ~* .(gif|jpg|jpeg)$ {

[ configuration E ]

}

The “/” request will match configuration A, the “/index.html” request will match configuration B, the “/documents/document.html” request will match configuration C, the “/images/1.gif” request will match configuration D, and the “/documents/1.jpg” request will match configuration E.

"/" 请求将会匹配到 配置A (精准匹配)

"/index.html" 请求将匹配到 配置B (没有命中精准匹配,没有命中前缀匹配,也没有命中正则匹配,最后命中默认匹配)

"/documents/document.html" 请求将命中 配置C (没有命中精准匹配,命中了前缀匹配 /documents/,继续查找正则匹配,没有命中,使用前缀匹配)

"/images/1.gif" 请求将命中 配置D (没有命中精准匹配,命中了前缀匹配 ^~ /images/,这个匹配带了 ^~修饰符,不查找正则匹配,直接使用该前缀匹配)

"/documents/1.jpg" 请求将命中 配置E  (没有命中精准匹配,同时命中了 /documents 和 ~* .(gif|jpg|jpeg)$,后面这个最长,被记录下来,继续查找正则匹配,没有命中,使用之前记录下的最长的前缀匹配,配置E。

The “@” prefix defines a named location. Such a location is not used for a regular request processing, but instead used for request redirection. They cannot be nested, and cannot contain nested locations.

"@" 前缀相当于给一个location命了名. 这种location不会用来处理常规的请求,但是会用来请求重定向。它们不可以被嵌套,也不可以包含嵌套location.

If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, or grpc_pass, then the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended. If this is not desired, an exact match of the URI and location could be defined like this:

如果一个location用一个前缀字符串,并以一个斜杠结束,且这些请求被 proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass 或者 grpc_pass中的一个处理,那么特殊的处理将被执行。在响应 带有和这个字符串相等,但没有最后的斜杠 的uri的请求时,会返回一个带有301状态码的永久重定向 给请求的uri,并带上最后的斜杠。如果不希望这样,可以对uri的精准匹配以及location定义如下: (这样就不会跳转301了)

location /user/ {

proxy_pass http://user.example.com;

}

location = /user {

proxy_pass http://login.example.com;

}

总结

1, 语法

                修饰符(modifier)         
location  [ = | ~ | ~* | ^~ ]    uri    { ... } 

2, 分类

根据不同的修饰符可以分为两大类
2.1 前缀location (prefix location)
2.1.1 无修饰符的普通location,例如 location /abc, location /abc/
2.1.2 带=的精准匹配location,例如 location =/abc
2.1.3 带^~表示以某个常规字符串开头的,非正则表达式location,例如 location ^~ /abc

2.2 正则表达式location (regular expressions location)
2.2.1 ~   区分大小写的正则location
2.2.2 ~*  不区分大小写的正则location

3, 匹配规则

3.1 nginx会首先检查 前缀location

3.1.1 如果命中,拥有最长的匹配字符串的location将被选中并被记录下来。

3.1.1.1 如果最长前缀匹配location的修饰符是^~时,就不会检查正则location了,直接选择该location为最终location。如果不是,则进入下一步正则匹配。

3.1.2 如果没有命中,则进入下一步正则匹配

3.2 如果存在正则location时,按照配置的先后顺序(重要!)依次匹配URI。

3.2.1 如果找到匹配的正则location就不再继续往下,并选择该location作为最终的结果。

3.2.2 如果没有找到匹配的正则location,则会使用之前被记录下来的前缀location (如果有的话)。

3.3 如果存在精准匹配location,且请求的uri跟其完全匹配,选择该精准匹配location作为最终的location。

4, 优先级

精准匹配 > ^~修饰符最长前缀匹配 > 正则匹配 > 无修饰符普通最长前缀匹配 > 通用匹配 /

5, 其他

注意,在同一个Server中,不能同时存在带有相同字符串的 ^~ 修饰符前缀location 和 无修饰符普通前缀location,如下

server {

listen 80;

server_name www.test1.com;

root /opt/wwwroot/test;

location /fullpath {

echo "prefix fullpath with no modifier";

}

location ^~ /fullpath {

echo "prefix fullpath with ^~ modifier";

}

}

如果这两个同时打开,在 nginx -t 命令检查nginx 配置时,会报 emerg 级别错误

2019/11/05 14:01:52 [emerg] 22355#22355: duplicate location "/fullpath" in /etc/nginx/sites-enabled/default:165

但是,将第二个location 改为 ^~ /fullpath/ 就OK了。

以上是 NginxLocation详细总结 的全部内容, 来源链接: utcz.com/z/510437.html

回到顶部