前言

要想学会nginx的路径配置,请认真弄懂下述的locationproxy_passrootalias指令,尤其是location的匹配处理过程,要不然每次配置路径,又得四处搜博客,而且搜出来的不一定有用。

location

Syntax: location [ = | ~ | ~* | ^~ ] uri { … }
location @name { … }
Context: server, location

location匹配规则流程

location只包括prefix stringregular expression两种,regular expression就是以~*(忽略大小写)或者~(区分大小写)修饰的字符串。

  1. 对于给定的request,nginx首先check prefix string,找出最长的匹配的路径,选择并记住;
  2. 按照regular expression定义的顺序继续匹配,如果找到第一个正则匹配的,则结束check;如果没有正则匹配,则使用上一步匹配的最长路径

上述匹配流程,有以下几种例外情况。

  • 对于大小写不敏感的操作系统,比如macOS和Cygwin,用prefix string匹配时会忽略大小写。
  • 如果最长的匹配的路径^~修饰符,那么终止,不再匹配regular expression。
  • 当然,使用=修饰符可以定义URI和location的完全匹配。如果找到一个完全匹配,那么终止匹配;比如,经常请求/a ,定义location = /a会加速请求处理,因为在第一个比较后就会终止匹配。这样的location很明显不能包含内嵌的location。

location block可以嵌套,regular expression可以包含capture,capture到的内容在后边的directive中可以使用。
我们举例说明,

location = / { 
    [ configuration A ] 
} 
 
location / { 
    [ configuration B ] 
} 
 
location /documents/ { 
    [ configuration C ] 
} 
 
location ^~ /images/ { 
    [ configuration D ] 
} 
 
location ~* \.(gif|jpg|jpeg)$ { 
    [ configuration E ] 
} 
  • / 匹配configuration A
  • /index.html匹配configuration B
  • /documents/document.html匹配configuration C
  • /images/1.gif匹配configuration D
  • /documents/1.jpg匹配configuration E

named location

@前缀定义一个named location。named location不用来处理常规请求,它是用来请求重定向的。named locaton不能嵌套,它内部也不能包含嵌套location。

特殊处理以/结尾的location

prefix string如果以/结尾,并且被 proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, grpc_pass其中之一处理,那么会执行特殊处理。如果request等于location,并且request不以/结尾,那么会返回一个重定向(permanent redirect,http状态码301)并且URI追加/。如果这不是你想要的,你想要的确切的URI和location匹配,可以像这样定义。

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

proxy_pass

Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except

设置代理服务器的protocol、address、URI(可选项)。可以指定httphttps协议。address可以是domain name或者ip address,和可选的port:

proxy_pass http://localhost:8000/uri/; 

request URI发送到server时,按如下方式处理:

  • 如果proxy_pass指定的是uri,那么当一个请求发送到server,则用proxy_pass指定的uri替换请求匹配部分
location /name/ { 
    proxy_pass http://127.0.0.1/remote/; 
} 
  • proxy_pass没有指定URI,请求的URI就像跟客户端发过来一样发送给server;
location /some/path/ { 
    proxy_pass http://127.0.0.1; 
} 

root

Syntax: root path;
Default:
root html;
Context: http, server, location, if in location

设置请求的root directory。比如,如下配置

location /i/ { 
    root /data/w3; 
} 

/i/top.gif请求会返回`/data/w3/i/top.gif```
path可以包含variable,除了$document_root 和$realpath_root
文件的路径就是root指定的值追加上URI。如果你想改变URI,那么就得使用alias。

root指定的路径拼接上请求路径就是请求的路径;如果想改变请求路径,则使用alias

alias

Syntax: alias path;
Default: —
Context: location

对指定的locaton,定义替换。比如如下配置

location /i/ { 
    alias /data/w3/images/; 
} 

/i/top.gif请求,返回/data/w3/images/top.gif

如果alias在regular expression的location中使用,那么regular expression应该包含capture,alias指向这些captures,比如

location ~ ^/users/(.+\.(?:gif|jpe?g|png))$ { 
    alias /data/w3/images/$1; 
} 

当location匹配指令的最后一部分值

location /images/ { 
    alias /data/w3/images/; 
} 

那么最好使用root指令替换

location /images/ { 
    root /data/w3; 
} 

发布评论
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

nginx 代理情况下 jsp request.getservername 得不到代理服务器ip详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。