avatar
童琦杰
向死而生
githubmusic
2022-05-07编辑

Nginx Location语法

URI匹配方式

1.前缀匹配

  • 无修饰符: 前缀匹配

  • =: 精确匹配

  • ^~: 前缀匹配,与无修饰符的区别是不再匹配正则表达式

2.正则表达式匹配

  • ~*: 大小写不敏感

  • ~: 大小写敏感

匹配优先级(顺序)

1.首先按照最长匹配原则校验前缀匹配方式的location。

  • 如果匹配到的location带有修饰符^~=,则不再进行第二步匹配,直接应用该location。

  • 如果匹配到location暂时先记下来,继续进行第二步。

2.然后按配置文件里的顺序依次校验正则表达式匹配方式的location。

  • 如果匹配到location就停止继续校验并且应用该location。

  • 如果未匹配到location就应用第一步前缀匹配方式匹配到的location。

Location示例

nginx
location = / {
        root /directory/of/web/static/files;
        try_files $uri $uri/ /index.html;
        index index.html;
}
location /api/ {
        proxy_pass your_api_address;
}
location / {
        root /directory/of/web/static/files;
        try_files $uri $uri/ /index.html;
        index index.html;
}

参考:官方文档

nginx
Syntax:    location [ = | ~ | ~* | ^~ ] uri { ... }
           location @name { ... }
Default:   —
Context:   server, location

Sets configuration depending on a request 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.

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 blocks can be nested, with some exceptions mentioned below.

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.

Regular expressions can contain captures (0.7.40) that can later be used in other directives.

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

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.

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. Let’s illustrate the above by an example:

nginx
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.

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.

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:

nginx
location /user/ {
    proxy_pass http://user.example.com;
}
location = /user {
    proxy_pass http://login.example.com;
}