Nginx location规则与rewrite总结

发布于 2019-04-17  20 次阅读


前言

Nginx作为主流的的静态web服务器除了具有高并发,省资源等特点外功能也是特别强大,他可以实现反向代理、解决跨域问题、防盗链、负载均衡、访问限流限速等功能,实现这些功能的原理大致就是将符合你所定义的规则的请求进行匹配,然后调用Nginx内置模块或者第三方功能模块来实现的,而匹配的过程就是通过location来实现的,并且location匹配规则还有优先级,这个我们需要重点掌握,并且location匹配后有时也会和rewrite结合将请求进行重写,常见的就是强制http跳转https。不多说下面多这些重点知识进行总结。

location详解

配置文件如下:

  • 配置讲解

location = /        (精确匹配/,主机名不带任何字符串)

location ^~ 表示uri以某个字符串开头,不是正则匹配

location ~ 表示区分大小写的正则匹配

location ~* 表示不区分大小写的正则匹配

location /  通用匹配,如果没有其他匹配,则任何请求都会被匹配到

  • 优先级排序

第一优先级:等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。

第二优先级:^~类型表达式(非正则)。一旦匹配成功,则不再查找其他匹配项。

第三优先级:正则表达式类型(~ 或者 ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。

第四优先级:location/xxx/  ,匹配具体某个目录,如果没有被正则匹配到,则采取。

第五优先级: location / 因为所有地址都以/开头,所以这条规则将匹配所有请求,但是匹配了却不采用,只有当所有规则没匹配到后才会采用,又称为最低优先级。

location实战

备注:需要结合上面的配置文件,这里都是请求的域名后面的部分。

  • /

执行config A  (精确完全匹配,后面不带任何字符)

  • /downloads/download.html

执行config B (其他都没匹配到,采取优先级最低的 )

  • /images/1.gif

执行config D (虽然E可以匹配到1.git,F可以匹配到images。但是D优先级更高)

  • /images/abc/def

执行config D (可以匹配到F 和G ,同样D优先级高)

  • /documents/document.html

执行config C(可以匹配到B但是优先级C高)

  • /documents/1.jpg

执行config E(可以匹配到B C 但是E优先级高)

使用建议:

Rewrite总结

  • rewrite介绍

rewrite功能就是,使用nginx提供的全局变量自定义变量,结合正则表达式flag标志位实现url重写以及重定向。

rewrite只能放在server{}、location{}、if{}这三个字段中。并且只能对域名后除去传递的参数外的字符串起作用,

例如:

http://wangtingwei.info/a/we/index.php?id=1&u=str

 只对

/a/we/index.php

重写。语法

rewrite regex replacement [flag];

如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。

表明看rewrite和location功能有点像,都能实现跳转,主要区别在于rewrite是在同一域名内《更改获取资源的路径》,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。很多情况下rewrite也会写在location里。它们的执行顺序是:

  1. 执行server字段的rewrite指令
  2. 执行location匹配。
  3. 接这2顺序后,如果匹配到的location有rewrite操作就执行选定的location中的rewrite指令。

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

  • flag标志位

last : 相当于Apache的[L]标记,表示完成reqwrite

break:停止执行后续rewrite指令

redirect :返回302临时重定向,地址栏会显示跳转后的地址

permanent :返回301永久重定向,地址栏会显示跳转后的地址

因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:

  1. last一般写在server和if中,而break一般使用在location中。
  2. last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
  3. break和last都能组织继续执行后面的rewrite指令

if指令与全局变量

结构为:

if (判断条件) {...},对if条件进行判断,如果条件为真,则大括号内的rewrite将会被执行,if 条件可以是如下内容:

  • 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当作false
  • 直接比较变量内容,使用= 或 !=
  • ~ 区分大小写的正则表达式匹配。~*为不区分大小写的正则匹配,!~区分大小写的不匹配。

-f  和 ! -f 用来判断是否存在文件。(f代表file)

-d 和 ! -d 用来表示判断是否存在目录  (d 代表directorty)

-e  和 ! -e 用来表示判断是否存在文件或目录 (e表示exist)

-x 和 ! -x 用来判断文件是否可以执行

if条件判断实例

Nginx 常用内置变量

举个🌰:

https://wangtingwei.info:88/wp-admin/post.php?post=1375&action=edit&classic-editor

  • $host  : wangtingwei.info
  • $server_port : 88
  • $request_uri  : /wp-admin/post.php?post=1375&action=edit&classic-editor
  • $uri (等同于document_uri): /wp-admin/post.php
  • $document_root : /var/www/html/ (具体看web服务器配置文件中root的路径)
  • $request_filename :/var/www/html/wp-admin/post.php
  • $args : post=1375&action=edit&classic-editor

常用正则


一个幽默,喜欢动漫,音乐,爱小动物,逐渐成为二次元肥宅的LINUX运维工程师,我会用心写博客,刚开始写的不太好。但是我会不断进步的!。就像我的博客下面写的。我宁愿做错,也不愿什么都不做 ps:好像是伊泽瑞尔说的,看来你游戏没少玩啊 23333333333333