nginx配置中的location和rewrite规则介绍

nginx配置中与请求匹配相关的就两个模块, location和 rewrite。也是我们做nginx配置打交道最多也是最重要的两个模块。今天

nginx配置中与请求匹配相关的就两个模块, locationrewrite。也是我们做nginx配置打交道最多也是最重要的两个模块。今天我们就来学习一下这两个模块的用法。

location路径匹配

location =/ { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ]}location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 # 但是正则和最长字符串会优先匹配 [ configuration B ]}location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ]}location ^~ /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。 [ configuration D ] }

=开头表示精确匹配,请问地址后面不能带任何字符串,比如可以匹配 http://fanxing.com/,不能匹配http://fanxing.com/index/1。

/通用匹配, 如果没有其它匹配,任何请求都会匹配到; /documents/路径匹配, 只会匹配 http://fanxing.com/documents/xxx这样的请求。 ^~开头表示uri以某个常规字符串开头,匹配符合以后,停止往下搜索正则,采用这一条

location正则匹配

nginx通过 location ~开启正则匹配。比如:

location ~ /documents/abc { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration E ] }location ~* /.(gif|jpg|jpeg)$ { # 匹配所有以 gif,jpg或jpeg 结尾的请求 # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则 [ configuration F ] }location ~* /js/.*//.js { # 匹配所有js/目录下面的js文件 [ configuration F ] }

~开头表示开启区分大小写的正则匹配;

~*开头表示不区分大小写的正则匹配;

实际使用过程中与遇到同时匹配多个规则的URI,它们的顺序是这样的: (location =) > (location ^~ 路径) > (location ~,~* 正则) > (location 完整路径) > (location 部分路径) > (/)。 举个栗子吧:

#精确匹配location = /index/666 { [ config A ] return 401;}#字符匹配location ^~ /index/ { [ config B ] return 402;}#正则匹配location ~* /index//d+ { [ config C ] return 403;}#完整路径location /index/666 { [ config D ] return 404;}#部分路径, 注意,这个配置是不能与B共存的,这里只是为了做演示location /index/ { [ config E ] return 405;}#通用匹配location / { [ config F ] return 406;}

匹配优先级应该是: A > B > C > D > E >F。 第一种情况,路径深度一样的情况,优先级是: 精确匹配 > 正则匹配 > 路径匹配 > 通用匹配,比如请求是: http://myhost.com/index/666,处理优先级应该是 A > C > D > F;

因为A是精确匹配,因为D的存在,正则优先于路径匹配,所以C>D。

注意:如果没有规则D,会优先匹配B。

第二种情况,如果请求是: http://myhost.com/index/6,处理优先级应该是 B > C > F,因为模糊匹配的时候,处理优先级应该是: 字符匹配 > 正则匹配 > 路径匹配 > 通用匹配

第三种情况,如果请求是: http://myhost.com/index/,处理优先级应该是 B > F

第四种情况,如果请求是: http://myhost.com/F来处理。

rewrite规则

rewrite规则介绍

rewrite就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。

rewrite只能放在 server{}, location{}, if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,比如:

http://myhost.com/index/666?who=garygao请求,rewrite只对 /index/666进行处理。

rewrite与location的区别

rewritelocation都能实现跳转,它们有什么区别呢?

rewrite是在同一域名内更改获取资源的路径,而 location是对一类路径做控制访问或反向代理,可以 proxy_pass到其他机器。

rewrite的用法

rewrite可以直接写在 server{}中,也可以写在 if{},同时也可以写在 location{}中。

它们的执行顺序是:

1. 执行 server块的 rewrite指令

2. 执行 location匹配

3. 执行命中的 location中的 rewrite指令

如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误。我们先来看个栗子:

server { #server中的rewrite rewrite ^/index/(/d+)$ /index/666; #if中的rewrite if ($host = "myhost.com") { rewrite ^/(.*)$ http://localhost.com/$1 last; } #location中的rewrite location ^~ /index/ { rewrite ^/index//d+$ http://localhost.com/666 last; }}

执行顺序上面已经介绍过了,比较好理解吧。

rewrite的flag标识

上面的栗子中,我们看到有 last这样标识,这是用来干啥的呢?

flag可以是以下的值:

last- url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变。

break- url重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变。

redirect- 返回302临时重定向,url会跳转,爬虫不会更新url。

permanent- 返回301永久重定向。url会跳转。爬虫会更新url。

为空- URL 不会变,但是内容已经变化,也是永久性的重定向。

其他重写规则

通过上面一些栗子,我们会发现除了 locationrewrite,还有一些与重写定位相关的关键字,比如 if, break还有 return等等。

if规则

语法:if (condition) { … }

默认值:none

使用字段:server, location

if 判断一个条件,如果条件成立,则后面的大括号内的语句将执行,相关配置从上级继承。

可以在判断语句中指定下列值:

一个变量的名称;不成立的值为:空字符传”“或者一些用“0”开始的字符串。

一个使用=或者!=运算符的比较语句。

使用符号~

和~模式匹配的正则表达式:

~为区分大小写的匹配。

不区分大小写的匹配(firefox匹配FireFox)。

!~和!~*意为“不匹配的”。

使用-f和!-f检查一个文件是否存在。

使用-d和!-d检查一个目录是否存在。

使用-e和!-e检查一个文件,目录或者软链接是否存在。

使用-x和!-x检查一个文件是否为可执行文件。

break规则

break和程序语言中的用法一样,就是跳出某个逻辑。

语法:break

默认值:none

使用字段:server, location, if

if (!-f $request_filename) { break;}

上面这个例子就是在if里面使用break,意思是如果访问的文件名不存在,就跳出。

return规则

语法:return code

默认值:none

使用字段:server, location, if

这个指令结束执行配置语句并为客户端返回状态代码,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416与500-504。此外,非标准代码444将关闭连接并且不发送任何的头部。

常用变量

下面是可以用作if判断的全局变量:

$args: 这个变量等于请求行中的参数,同 $query_string

$content_length: 请求头中的Content-length字段。

$content_type: 请求头中的Content-Type字段。

$document_root: 当前请求在root指令中指定的值。

$host: 请求主机头字段,否则为服务器名称。

$http_user_agent: 客户端agent信息

$http_cookie: 客户端cookie信息

$limit_rate: 这个变量可以限制连接速率。

$request_method: 客户端请求的动作,通常为GET或POST。

$remote_addr: 客户端的IP地址。

$remote_port: 客户端的端口。

$remote_user: 已经经过Auth Basic Module验证的用户名。

$request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成。

$scheme: HTTP方法(如http,https)。

$server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

$server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。

$server_name: 服务器名称。

$server_port: 请求到达服务器的端口号。

$request_uri: 包含请求参数的原始URI,不包含主机名,如:"/foo/bar.php?arg=baz"。

$uri: 不带请求参数的当前URI, $uri不包含主机名,如"/foo/bar.html"。

$document_uri: 与$uri相同。

常用正则

正则表达无论是做location还是rewrite配置,都会经常用到,下面罗列一下常用的:

.: 匹配除换行符以外的任意字符

?: 重复0次或1次

+: 重复1次或更多次

*: 重复0次或更多次

/d:匹配数字

^: 匹配字符串的开始

$: 匹配字符串的介绍

{n}: 重复n次

{n,}: 重复n次或更多次

[c]: 匹配单个字符c

[a-z]: 匹配a-z小写字母的任意一个

小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。

结语

以上就是nginx中常用的定位规则了,梳理一遍之后发现自己对nginx基本配置都有了基本的认识,还能写一些基本的配置,在node服务部署中基本够用了,跟后端同学交流的过程中还能装装逼,哈哈~

参考资料: https://linux.cn/article-5714-1.html

未登录用户
全部评论0
到底啦