剑客
关注科技互联网

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

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

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址