nginx配置location总结及rewrite规则写法

1. location正则写法

一个示例:php

 

1css

2html

3nginx

4web

5正则表达式

6后端

7tomcat

8服务器

9cookie

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

 

location = / {

# 精确匹配 / ,主机名后面不能带任何字符串

[ configuration A ]

}

location / {

# 由于全部的地址都以 / 开头,因此这条规则将匹配到全部请求

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

[ configuration B ]

}

location /documents/ {

# 匹配任何以 /documents/ 开头的地址,匹配符合之后,还要继续往下搜索

# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条

[ configuration C ]

}

location ~ /documents/Abc {

# 匹配任何以 /documents/Abc 开头的地址,匹配符合之后,还要继续往下搜索

# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条

[ configuration CC ]

}

location ^~ /images/ {

# 匹配任何以 /images/ 开头的地址,匹配符合之后,中止往下搜索正则,采用这一条。

[ configuration D ]

}

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

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

# 然而,全部请求 /images/ 下的图片会被 config D 处理,由于 ^~ 到达不了这一条正则

[ configuration E ]

}

location /images/ {

# 字符匹配到 /images/,继续往下,会发现 ^~ 存在

[ configuration F ]

}

location /images/abc {

# 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在

# F与G的放置顺序是没有关系的

[ configuration G ]

}

location ~ /images/abc/ {

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

[ configuration H ]

}

location ~* /js/.*/\.js

  • =开头表示精确匹配
    如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。
  • ^~ 开头表示uri以某个常规字符串开头,不是正则匹配
  • ~ 开头表示区分大小写的正则匹配;
  • ~* 开头表示不区分大小写的正则匹配
  • / 通用匹配, 若是没有其它匹配,任何请求都会匹配到

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

上面的匹配结果
按照上面的location写法,如下的匹配示例成立:

  • / -> config A
    精确彻底匹配,即便/index.html也匹配不了
  • /downloads/download.html -> config B
    匹配B之后,往下没有任何匹配,采用B
  • /images/1.gif -> configuration D
    匹配到F,往下匹配到D,中止往下
  • /images/abc/def -> config D
    最长匹配到G,往下匹配D,中止往下
    你能够看到 任何以/images/开头的都会匹配到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

实际使用建议

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

 

因此实际使用中,我的以为至少有三个匹配规则定义,以下:

#直接匹配网站根,经过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。

#这里是直接转发给后端应用服务器了,也能够是一个静态首页

# 第一个必选规则

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

2. 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指令

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

2.1 flag标志位

  • last : 至关于Apache的[L]标记,表示完成rewrite
  • 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指令

2.2 if指令与全局变量

if判断指令
语法为if(condition){...},对给定的条件condition进行判断。若是为真,大括号内的rewrite指令将被执行,if条件(conditon)能够是以下任何内容:

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

-f!-f用来判断是否存在文件
-d!-d用来判断是否存在目录
-e!-e用来判断是否存在文件或目录
-x!-x用来判断文件是否可执行

例如:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

 

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

2.3 经常使用正则

  • . : 匹配除换行符之外的任意字符
  • ? : 重复0次或1次
  • + : 重复1次或更屡次
  • * : 重复0次或更屡次
  • \d :匹配数字
  • ^ : 匹配字符串的开始
  • $ : 匹配字符串的介绍
  • {n} : 重复n次
  • {n,} : 重复n次或更屡次
  • [c] : 匹配单个字符c
  • [a-z] : 匹配a-z小写字母的任意一个

小括号()之间匹配的内容,能够在后面经过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。

2.4 rewrite实例

例1

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

 

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 '^/images/([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";

}

}

 

对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,因而匹配到location /data,先看/data/images/test.png文件存不存在,若是存在则正常响应,若是不存在则重写tryfiles到新的image404 location,直接返回404状态码。

例2

 

1

 

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

 

对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。

例3
见 ssl部分页面加密 。

相关文章
相关标签/搜索