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

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

nginx配置中与请求匹配相关的就两个模块, location

rewrite

。也是我们做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的区别

rewrite

location

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

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 不会变,但是内容已经变化,也是永久性的重定向。

其他重写规则

通过上面一些栗子,我们会发现除了 location

rewrite

,还有一些与重写定位相关的关键字,比如 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
到底啦