nginx location

等号项目(=)的优先级最高,要求规范匹配。1旦匹配成功,则不再查找其余匹配项。
^~类型表明式。一旦匹配成功,则不再查找其余匹配项。

正则表明式类型(~
~*)的事先级次之。假设有三个location的正则能匹配的话,则选拔正则表达式最长的不行。

(location =) > (location 完整路径) > (location ^~ 路径) >
(location ~,~* 正则相继) > (location 部分开场路径) > (/)

location正则写法


###### 一个示例:
location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ] 
}

location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ] 
}

location /documents/ {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration C ] 
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration CC ] 
}

location ^~  {
  # 匹配任何以  开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
  [ configuration D ] 
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
  # 然而,所有请求  下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
  [ configuration E ] 
}

location  {
  # 字符匹配到 ,继续往下,会发现 ^~ 存在
  [ configuration F ] 
}

location  {
  # 最长字符匹配到 ,继续往下,会发现 ^~ 存在
  # F与G的放置顺序是没有关系的
  [ configuration G ] 
}

location ~ / {
  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
    [ configuration H ] 
}

location ~* /js/.*/\.js
  • 匹配规则小总计,匹配规则。已=开首表示精确匹配
    如 A 中只匹配根目录结尾的呼吁,前边不可能带任何字符串。
  • ^~ 开始表示uri以某些常规字符串开首,不是正则匹配
  • ~ 起初表示区分轻重缓急写的正则匹配;
  • ~* 初始表示不区分轻重缓急写的正则匹配
  • / 通用匹配, 如若未有任何包容,任何请求都会合营到

顺序 no优先级:
(location =) > (location 完整路径) > (location ^~ 路径) >
(location ,* 正则相继) > (location 部分起初路径) > (/)

Nginx
内核源码解析

一、Nginx 正则及 location 匹配

一.Nginxlocation
规则匹配

^~      
标识符匹配前边跟三个字符串。匹配字符串后将告一段落对持续的正则表明式进行匹配,
如 location ^~
,在同盟了这几个字符串后就止住对一而再的正则匹配

=         精准匹配,如 location = /,只会匹配 url 为/的央浼

~         区分轻重缓急写的协作

~*       不区分轻重缓急写的匹配

!~        对界别轻重缓急写的匹配取非

!~*      对不区分轻重缓急写的相当取非

/          通用匹配, 借使未有其余包容,任何请求都会被匹配到

贰、正则表明式

*              重复前面包车型大巴字符 0 次或频仍

?              重复前边的字符 0 次或 壹 次

+              重复前边的字符 一 次或频仍

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

(a|b)         匹配 a 或 b

^              以…开头

$              以…结尾

{n}          重复前边的字符 n 次

{n,}         重复前边的字符 n 次或更频仍

{n,m}       重复前边的字符 n 到 m 次

*?            重复前边的字符 0 次或频繁,但尽也许少重复

+?            重复后边的字符 一 次或更频仍,但尽可能少重复

??             重复前边的字符 0 次或 一 次,但尽可能少重复

{n,m}?      重复后面包车型地铁字符 n 到 m 次,但尽恐怕少重复

{n,}?        重复前边的字符 n 次以上,但尽恐怕少重复

三、正则表达式补充:

\W         匹配任意不是字母,数字,下划线,汉字的字符

\S          匹配任意不是空白符的字符

\D          匹配任意非数字的字符

\B          匹配不是单词起始或收尾的岗位

[a]         匹配单个字符a

[a-z]      匹配 a-z 小写字母的随机一个

[^a]       匹配除了 a 以外的四意字符

[^abc]    匹配除了 abc 那多少个假名以外的自由字符

4、Nginx location 应用规则

location [=|~|~*|^~|!~|!~*] /url/{…}

默认值:no

选择字段:server

location 参数依照 ULANDL
的例外要求来举办安顿,可以动用字符串与正则表达式匹配,

location = / {

# 精确匹配 / ,主机名后边无法带任何字符串

[ configuration A ]

}

location / {

# 因为兼具的地方都是 / 初叶,所以那条规则将合营到全数请求

# 然则正则和最长字符串会优先匹配

[ configuration B ]

location /documents/ {

# 匹配任何以 /documents/
发轫的地方,匹配符合现在,还要持续往下搜寻

#
唯有后边的正则说明式没有匹配到时,这一条才会利用这一条

[ configuration C ]

}

location ~ /documents/Abc {

# 匹配任何以 /documents/
初阶的地址,匹配符合以后,还要一而再往下寻找

#
唯有后边的正则表达式未有匹配到时,这一条才会采用这一条

[ configuration CC ]

}

location ^~ {

# 匹配任何以
开头的地点,匹配符合以往,截至往下寻找正则,选拔这一条。

[ configuration D ]

}

location ~* \.(gif|jpg|jpeg)$ {

# 匹配全部以 gif,jpg 或 jpeg 结尾的央求

# 但是,全体请求 下的图纸会被
config D 处理,因为 ^~ 到达不了这一条正则

[ configuration E ]

}

location {

# 字符匹配到 ,继续往下,会意识
^~ 存在

[ configuration F ]

}

location {

# 最长字符匹配到 ,继续往下,会意识 ^~ 存在

# F 与 G 的放置顺序是未曾提到的

[澳门金沙国际, configuration G ]

}

location ~ / {

# 唯有去掉 config D 才有效:先最长匹配 config G
开端的地方,继续往下寻找,匹配到这 一条正则,选拔

[ configuration H ]

}

极度顺序优先级:

(location =) > (location 完整路径) > (location ^~ 路径) >
(location ~,~* 正则顺 序) > (location 部分开场路径) > (/)

安份守己位置的 location 匹配,分析以下案例:

/ ->config A

精确完全匹配,固然/index.html 也极度不了

/downloads/download.html ->config B

匹配 B 现在,往下并未有其余匹配,选用 B

 

.gif -> configuration D

同盟到 B,往下匹配到 D,甘休往下

/def ->config D

最长匹配到 G,往下匹配 D,截至往下

你能够观望 任何以开头的都会合营到 D 并终止,FG
写在这里是不曾其余意义的, H 是永恒轮不到的,那里只是为了求证匹配顺序

/documents/document.html ->config C

合作到 C,往下未有其余匹配,接纳 C

/documents/1.jpg -> configuration E

同盟到 C,往下正则匹配到 E

/documents/Abc.jpg ->config CC

最长匹配到 C,往下正则顺序匹配到 CC,不会往下到 E

 

实质上采纳提议

因而其实使用中,个人认为至少有多个门户差不多规则定义,如下:

#一直匹配网址根,通过域名访问网址首页比较频仍,使用那个会加速处理。那里是直接转载给后端应用服务器了,也得以是一个静态首页。

# 第三个必选规则

location = / {

      proxy_pass

}

# 第3个必选规则是拍卖静态文件请求,这是 nginx 作为 http 服务器的刚强

# 有三种配备情势,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {

              root /usr/local/nginx/html/static/;

}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {

              root /webroot/res/;

}

#其两个规则正是通用规则,用来转载动态请求到后端应用服务器,非静态文件请求就默认是动态请求,自个儿依照实际把握。

#毕竟近日的有些框架的盛行,带.php,.jsp 后缀的意况很少了

location / {

             proxy_pass

}

 

二、Nginx Rewrite 规则

        rewrite 成效正是,使用 nginx
提供的全局变量或本人设置的变量,结合正则表明式和 标志位达成 url
重写以及重定向。rewrite 只可以放在 server{},location{},if{}中,并且只好对域名前面的除此之外传递的参数外的字符串起效果           Nginx 的 Rewrite
规则采取 PCRE(Perl compatible Regular Expressions)Perl 包容正则表达式的语法进行平整匹配,假如急需Ningx的Rewrite功效,在编写翻译安装Nginx在此以前,
必须设置 PCRE 库。

例如: 只对 UCR-VL
中的 /a/we/index.php 等字符串起效果。

U兰德冠道L 是 Uniform Resource Location 的缩写,译为“统一能源一定符”。
如:

语法:

rewrite 正则表达式 更换目的 [标志位];

        rewrite 和 location 功能有点像,都能落到实处跳转。首要不相同在于
rewrite 是在同一域名内 更改获取财富的不2诀窍,而 location
是对路线做决定访问或反向代理,能够应用 proxy_pass 到
别的机器。很多情状下 rewrite 也会写在 location 里,它们的推行顺序是:

  1. 执行 server 块的 rewrite 指令

  2. 执行 location 匹配

  3. 执行选定的 location 中的 rewrite 指令

小心:倘使内部某步 U奥迪Q3I 被重写,则再次循环执行
一-三,直到找到真正存在的文书;循环超 过 十 次,则赶回 500 Internal Server
Error 错误。

 

flag 标志位

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

※ break : 本条规则匹配成功后,终止匹配,不再匹配后面包车型大巴平整

※ redirect : 重回 30贰 权且重定向,浏览器地址栏会呈现跳转后的 USportageL 地址

※ permanent : 再次回到 30一 永久重定向,浏览器地址栏会突显跳转后的 U大切诺基L 地址

last 一般写在 server 和 if 中,而 break 一般选用在 location 中

last 不鸣金收兵重写后的 url 匹配,即新的 url 会再从 server
走1次匹配流程,而 break 终止重写 后的合营

break 和 last 都能组织继续执行前面包车型大巴 rewrite 指令

last 和 break 用来落到实处 U奥迪Q5I 重写,浏览器地址栏 UHummerH二L 地址不变 redirect 和
permanent 用来促成 U途达L 跳转,浏览器地址栏会展现跳转后的 UEnclaveL 地址

 

if 指令与全局变量

if 判断指令

语法为 if(condition){…},对给定的尺度 condition
举行判定。假使为真,大括号内的 rewrite 指令将被执行,if
条件(conditon)能够是之类任何内容:

当表明式只是三个变量时,假使其值为空或任何以 0
初叶的字符串时都会作为条件为 false

直白相比变量和剧情时,使用=或!=

-f 和!-f 用来判定是不是存在文件

-d 和!-d 用来判定是还是不是存在目录

-e 和!-e 用来判断是不是存在文件或目录

-x 和!-x 用来判断文件是不是可实施

例如: if ($http_user_agent ~ MSIE) {

            rewrite ^(.*)$ /msie/$1 break;

          } //如果 UA 包含”MSIE”,rewrite 请求到/msid/目录下

         if ($request_method = POST) {

             return 405;

          } //假如提交方法为 POST,则赶回状态 40伍(Method not
allowed)。 return 无法再次回到 30一,302

专注:因为再次来到 301 和 302 不可能只回去状态码,还必须有重定向的 U大切诺基L,所以
return 指令 不可能回来 301,30贰。 

 

if ($slow) {

limit_rate 10k;

} //限制速度,$slow 能够由此 set 指令设置 

if (!-f $request_filename){

break;

proxy_pass ;

} //假使请求的公文名不设有,则反向代理到 localhost 。那里的 break
也是停止 rewrite 检 查

if ($args ~ post=140){

rewrite ^ permanent;

} //假使 query string 中蕴藏”post=140″,永久重定向到 example.com

location ~* \.(gif|jpg|png|swf|flv)$ {

valid_referers none blocked www.jefflei.com www.leizhenfang.com;

if ($invalid_referer) {

return 404;

}//防盗链

}

Nginx 变量

下边是可以用作 if 判断的变量

$args:                              
 记录请求行中的参数,同$query_string

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

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

$document_root:                 记录当前伏乞在 root 指令中钦定的值。

$host :                              
记录请求主机头字段,不然为服务器名称。

$http_user_agent:               记录用于记录客户端浏览器的相关音信

$http_cookie:                      记录客户端 cookie 新闻$limit_rate: 记录能够界定连接速率。

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

$request_filename:              记录当前呼吁的文本路径,由 root 或
alias 指令与 U汉兰达I 请求生成。

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

$server_protocol:                记录请求使用的磋商,平时是 HTTP/壹.0
或 HTTP/一.一。

$server_addr:                    
记录服务器地址,在成功贰次系统调用后能够规定那么些值。

$server_name:                    记录服务器名称。

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

$request_uri:                       记录包蕴呼吁参数的原始
USportageI,不含有主机名,如:” /foo/bar.php?arg=baz”。

$uri:                                    记录不带请求参数的当下
U奥德赛I,$uri 不包涵主机名,如”/foo/bar.html”。 $document_uri:            
       与$uri 相同。

$http_x_forwarded_for           记录远程客户端的 ip 地址

$remote_addr:                     记录远程客户端的 IP 地址。

$remote_port:                      记录远程客户端的端口。

$remote_user                        记录远程客户端用户名称

$time_local                            记录走访时间及时区

$request                               记录请求的 U途乐L 与 HTTP 协议

$status                                 记录请求的情景,例如成功时为
200,页面找不到时为 40四

$body_byte_sent                   记录发送给客户端的文本焦点内容大小

$http_referer                         记录是从哪个页面链接待上访问过来的

URL 分析:

$host:localhost $server_port:88

$request_uri:

$documenturi:/test1/test2/test.php

$document_root:/var/www/html

$request_filename:/var/www/html/test1/test2/test.php

Nginx 日志案例:

log_format main ‘$remote_addr – $remote_user [$time_local]
“$request” ‘

‘$status $body_bytes_sent “$http_referer” ‘

‘”$http_user_agent” “$http_x_forwarded_for”‘;

//IP 地址-用户名 [本土时间] “请求”

//状态码主体内容大小“访问来源链接”

//”浏览器新闻”“客户端 IP 地址”

192.168.200.2 – -[21/Nov/2016:10:14:57
+0800]”GET /
HTTP/1.1″3040″-“”Mozilla/4.0 (compatible; MSIE 7.0;
Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR
3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3;
.NET4.0C; .NET4.0E)”

演示,就算访问的 U冠道L 以”*.sh” “*.bash”结尾,则赶回状态码 40三

location ~ .*\.(sh|bash)?$ {

return 403;

}

将原来要拜访/data 目录重写为/bbs

rewrite ^/data/?$ /bbs/ permanent;

避防盗链

localtion ~*\.(gif|jpg|png|swf|flv)${

valid_referers none blocked www.test.com *.test.com;

if($incalid_referer){

rewrite ^/(.*);

    }

}

贯彻域名跳转

所有对 www.360buy.com 的访问,rewrite 到 www.jd.com

server {

listen 80;

server_name www.jd.com;

charset utf-8;

root html;

index index.html index.htm;

if ($host = “www.360buy.com”) {

rewrite ^/(.*)$ permanent;

}

}

三、Nginx 静动分离

试验环境:两台服务器

192.168.200.102         Nginx 服务器

192.168.200.101         LAMP 服务器

试行时只顾观望是在哪台服务器上实行的安插!看清主机名!

LAMP rpm 格局搭建

澳门金沙国际 1澳门金沙国际 2

[root@LAMP ~]# yum -y install httpd mysql mysql-server php php-mysql

[root@LAMP ~]# vim /etc/httpd/conf/httpd.conf

276 ServerName www.example.com:80

402 DirectoryIndex index.php index.html index.html.var

[root@LAMP ~]# httpd -t

Syntax OK

[root@LAMP ~]# /etc/init.d/httpd start

正在启动 httpd:                                                               [确定]

[root@LAMP ~]# /etc/init.d/mysqld start

正在启动mysqld:                                                              [确定]

[root@LAMP ~]# mysqladmin -uroot password '123123'

[root@LAMP ~]# mysql -uroot -p123123

[root@LAMP ~]# vim /var/www/html/mysql.php

<?php

$link=mysql_connect('localhost','root','123123');

if($link) echo "恭喜你,数据库连接成功啦!!";

mysql_close();

?>

View Code

 

 

宿主机测试: 

澳门金沙国际 3

 

搭建 Nginx,配置情形分离

一、源码包编写翻译安装 Nginx

澳门金沙国际 4澳门金沙国际 5

[root@nginx ~]# yum -y install pcre-devel zlib-devel gcc gcc-c++ make

[root@nginx ~]# useradd -M -s /sbin/nologin nginx

[root@nginx ~]# tar xf nginx-1.6.2.tar.gz -C /usr/src/

[root@nginx ~]#cd /usr/local/nginx-1.6.2/

[root@nginx ~]#./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module&& make && make install

[root@nginx ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/

[root@nginx ~]# nginx

[root@nginx ~]# netstat -napt | grep :80

tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 57200/nginx

View Code

 

二、修改 nginx.conf 主配置文件

澳门金沙国际 6澳门金沙国际 7

[root@nginx ~]# cat /usr/local/nginx/conf/nginx.conf

user nginx nginx;

worker_processes 2;

error_log logs/error.log;

pid logs/nginx.pid;



events { use epoll;

worker_connections 10240;

} 

http {

includemime.types;

default_type application/octet-stream; 

log_format main '$remote_addr - $remote_user [$time_local] "$request" '

                                                '$status $body_bytes_sent "$http_referer" '

                                               '"$http_user_agent" "$http_x_forwarded_for"'; 

access_log logs/access.log  main; 

sendfile on;

keepalive_timeout 65;

gzip on; 

server {

listen 80;

server_name localhost;

charset utf-8; 

location / {

root html;

index index.html index.htm;

                }

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

         } 


              location ~ \.php$ {                                       //区分大小写匹配,以 php 结尾的的网页

                    proxy_pass http://192.168.200.101;       //反向代理给 LAMP 服务器处理

               }

              location ~ \.(gif|jpg|jpeg|bmp|png|swf) {       //区分大小写匹配,以 gif、jpg、swf 等结尾的文件

                          root html/images;                        //指定图片存放路径

                    }

             }

} 


[root@nginx ~]# echo "<h1>www.crushlinux.com</h1>" >/usr/local/nginx/html/index.html 
[root@nginx ~]# ulimit -n 65000       //调整打开最大连接数

[root@nginx ~]# echo "ulimit -n 65000" >>/etc/profile 

[root@nginx ~]# nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@nginx ~]# killall -HUP nginx

View Code

 

 

三、浏览器访问 html 及 php
文件进行测试:

澳门金沙国际 8

 

肆、浏览器访问测试图片文件:

澳门金沙国际 9澳门金沙国际 10

[root@nginx ~]# cd /usr/local/nginx/html/

[root@nginx html]# tree

.

├── 50x.html

├── images

│?? └── linux.png

└── index.html 

1 directory, 3 files 

[root@LAMP ~]# cd /usr/local/httpd/htdocs/

[root@LAMPhtdocs]# catmysql.php

<?php

$link=mysql_connect('localhost','root','123456');

if($link) echo "恭喜你,数据库连接成功啦!!";

mysql_close();

?>

<br />

<img src="http://192.168.200.102/linux.png" /> 

View Code

 

澳门金沙国际 11

 澳门金沙国际 12

       
右键点击图片能够查阅文件路径是“
动态 PHP 语言由 LAMP 服务器提供解析(1玖二.168.200.10一),静态图片由 Nginx
服务器提供 解析(1九二.16八.200.10二)

        抓包测试查看:

    澳门金沙国际 13

 

nginx 配置 proxy_pass 路径带 / 的问题

用户访问的 url 为
eg:

#情况1: proxy_pass 后带 / 
location  /abc/ {
                proxy_pass http://klvchen.com/;
} 
#会被代理成  http://klvchen.com/test.html

#情况2: proxy_pass 后不带 / 
location  /abc/ {
                proxy_pass http://klvchen.com;
} 
#会被代理成  http://klvchen.com/abc/test.html

实在利用指出


所以实际使用中,个人觉得至少有三个匹配规则定义,如下:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
    proxy_pass http://tomcat:8080/
}

http://tengine.taobao.org/book/chapter_02.html
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

nginx location 练习

Nginx location
配置踩坑进程分享
nginx配置location计算及rewrite规则写法
location
匹配规则

在页面输出 nginx 配置文件

server    {
    listen 80;
    server_name tmp.kaibuy.cn;
    index index.php;
    root  /home/web/blog/public/www;
    #error_page   404   /404.html;
    location / {
        default_type  text/plain;
        gzip off;
        set $str "This Host : ";
        return 200 "$str $http_host";
    }

    access_log off;
}
  • default_type
    text/plain;是钦赐以文件格局打字与印刷,假如不加那句,搞不佳会以下载文件的措施现身。当然也能够钦命为HTML,具体代码见前边的mime.types中。
  • gzip off;关闭压缩,也能够不关,这些不根本。
  • set $str “This Host :
    “;设定1个变量,倘诺变量内容是单词,也足以:set $str
    MyValue;,那种不带引号时,中间无法有空格即可。
  • return 200 “$str
    $http_host”;重临内容体,后面200是状态码,能够是专断符合HTML状态码的代码,那任意。前边引号里的是八个变量,$str是刚刚定义的变量,$http_host是nginx系统变量。那儿也得以写成return
    200
    $str$http_host;也便是不带引号,但变量之间倘若再而三的,不能有空格。

location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ]
}
location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ]
}
location /documents/ {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration C ]
}
location ~ /documents/Abc {
  # 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration CC ]
}
location ^~  {
  # 匹配任何以  开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
  [ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
  # 然而,所有请求  下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
  [ configuration E ]
}
location  {
  # 字符匹配到 ,继续往下,会发现 ^~ 存在
  [ configuration F ]
}
location  {
  # 最长字符匹配到 ,继续往下,会发现 ^~ 存在
  # F与G的放置顺序是没有关系的
  [ configuration G ]
}
location ~ / {
  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
    [ configuration H ]
}
location ~* /js/.*/\.js
  • 以=起首表示精确匹配
    如 A 中只匹配根目录结尾的央求,前边不可能带任何字符串。
  • ^~ 开首表示uri以某些常规字符串发轫,不是正则匹配
  • ~ 伊始表示区分轻重缓急写的正则匹配;
  • ~* 起初表示不区分轻重缓急写的正则匹配
  • / 通用匹配, 如若未有别的包容,任何请求都会协作到

顺序 no优先级:
(location =) > (location 完整路径) > (location ^~ 路径) >
(location ,* 正则相继) > (location 部分开场路径) > (/)

  • / -> config A
    精确完全匹配,即便/index.html也协作不了
  • /downloads/download.html -> config B
    匹配B未来,往下未有别的匹配,选取B
  • .gif -> configuration D
    匹配到F,往下匹配到D,停止往下
  • /def -> config D
    最长匹配到G,往下匹配D,结束往下
    您能够见到
    任何以起头的都会合作到D并停止,FG写在此处是尚未其余意义的,H是永远轮不到的,那里只是为着注脚匹配顺序
  • /documents/document.html -> config C
    万分到C,往下并未有任何匹配,接纳C
  • /documents/1.jpg -> configuration E
    特出到C,往下正则匹配到E
  • /documents/Abc.jpg -> config CC
    最长匹配到C,往下正则顺序匹配到CC,不会往下到E

常用正则

.: 匹配除换行符以外的专断字符
?: 重复0次或1次
+: 重复三遍或更频仍
*: 重复0次或更频仍
\d:匹配数字
^: 匹配字符串的上马
$: 匹配字符串的截至
{n}: 重复n次
{n,}: 重复n次或更频繁
[c]: 匹配单个字符c
[a-z]: 匹配a-z小写字母的随机多少个
小括号()之间匹配的剧情,能够在后头通过$1来引用,$二表示的是日前第叁个()里的始末。正则里面简单让人疑心的是\转义特殊字符。

Rewrite规则


rewrite功用正是,使用nginx提供的全局变量或协调安装的变量,结合正则表明式和标志位实现url重写以及重定向。rewrite只好放在server{},location{},if{}中,并且只好对域名前边的除却传递的参数外的字符串起效果,例如
http://seanlook.com/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. 施行选定的location中的rewrite指令
    比方中间某步U途乐I被重写,则再一次循环执行一-3,直到找到实际存在的文本;循环当先十一遍,则赶回500
    Internal Server Error错误。

假设中间某步U安德拉I被重写,则另行循环执行一-三,直到找到实际存在的文件;循环超越13遍,则赶回500
Internal Server Error错误。

实际行使建议

于是实际利用中,个人认为至少有八个相当规则定义,如下:
直白匹配网址根,通过域名访问网站首页比较频仍,使用那个会加快处理,官网如是说。
此处是间接转载给后端应用服务器了,也得以是叁个静态首页
首先个必选规则

location = / {
    proxy_pass http://tomcat:8080/index
}

第3个必选规则是处理静态文件请求,那是nginx作为http服务器的不屈
有二种配备形式,目录匹配或后缀匹配,任选其壹或搭配使用

location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

其八个规则就是通用规则,用来转载动态请求到后端应用服务器
非静态文件请求就默许是动态请求,自身依照实际把握
百川归海方今的某些框架的风行,带.php,.jsp后缀的景况很少了

location / {
    proxy_pass http://tomcat:8080/
}

flag标志位


  • last : 相当于Apache的[L]标志,表示完毕rewrite
  • break : 甘休执行当前虚拟主机的继承rewrite指令集
  • redirect : 重返30二权且重定向,地址栏会突显跳转后的地址
  • permanent : 再次来到30一世代重定向,地址栏会显示跳转后的地点

因为30一和30贰不能不难的只回去状态码,还非得有重定向的U讴歌RDXL,这正是return指令不能重临30一,302的由来了。那里
last 和 break 分化有点难以知晓:

  1. last一般写在server和if中,而break壹般选择在location中
  2. last不甘休重写后的url匹配,即新的url会再从server走三次匹配流程,而break终止重写后的协作
  3. break和last都能组织继续执行前面的rewrite指令

常用正则

  • . : 匹配除换行符以外的4意字符
  • ? : 重复0次或1次
    • : 重复一次或更频仍
    • : 重复0次或更频仍
  • \d :匹配数字

  • ^ : 匹配字符串的发轫
  • $ : 匹配字符串的牵线
  • {n} : 重复n次
  • {n,} : 重复n次或更频仍
  • [c] : 匹配单个字符c
  • [a-z] : 匹配a-z小写字母的私自三个

if指令与全局变量


if判断指令
语法为if(condition){…},对给定的口径condition进行判断。借使为真,大括号内的rewrite指令将被实施,if条件(conditon)能够是之类任何内容:

  • 当表明式只是贰个变量时,倘使值为空或任何以0初叶的字符串都会作为false
  • 直白相比变量和内容时,使用=或!=
  • ~正则表明式匹配,~*不区分轻重缓急写的匹配,!~区分轻重缓急写的不包容

-f和!-f用来判断是或不是留存文件
-d和!-d用来判定是或不是留存目录
-e和!-e用来判定是还是不是留存文件或目录
-x和!-x用来判定文件是或不是可进行

例如:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
 } //如果cookie匹配正则,设置变量$id等于正则引用部分

if ($request_method = POST) {
    return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302

if ($slow) {
    limit_rate 10k;
} //限速,$slow可以通过 set 指令设置

if (!-f $request_filename){
    break;
    proxy_pass  http://127.0.0.1; 
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查

if ($args ~ post=140){
    rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com

location ~* \.(gif|jpg|png|swf|flv)$ {
    valid_referers none blocked www.jefflei.com www.leizhenfang.com;
    if ($invalid_referer) {
        return 404;
    } //防盗链
}

全局变量
上面是足以用作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相同。

例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

常用正则


  • . : 匹配除换行符以外的任意字符
  • ?: 重复0次或1次
  • +: 重复1遍或更频仍
  • *: 重复0次或更频仍
  • \d :匹配数字
  • ^ : 匹配字符串的上马
  • $ : 匹配字符串的介绍
  • {n} : 重复n次
  • {n,} : 重复n次或更频仍
  • [c] : 匹配单个字符c
  • [a-z] : 匹配a-z小写字母的任性2个

小括号()之间匹配的情节,能够在后头通过$1来引用,$贰表示的是日前第贰个()里的内容。正则里面不难令人纳闷的是\转义特殊字符

rewrite实例


http {
    # 定义image日志格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 开启重写日志
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重写规则信息
                error_log logs/rewrite.log notice; 
                # 注意这里要用‘’单引号引起来,避免{}
                rewrite '^([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定针对图片的日志格式,来分析图片类型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 图片不存在返回特定的信息
                return 404 "image not found\n";
        }
}

对形如/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location
/data,先看/datatest.png文件存不设有,若是存在则符合规律响应,如若不存在则重写tryfiles到新的image404location,直接回到404状态码。

例2:

rewrite ^(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

对形如la_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地点,并会再三再四尝试匹配location。

参考

http://www.nginx.cn/216.html
http://www.ttlsa.com/nginx/nginx-rewriting-rules-guide/
《老僧体系nginx之rewrite规则火速上手.pdf》
http://fantefei.blog.51cto.com/2229719/919431

相关文章