Nginx之URL重写

1.URL重写模块(Rewrite)

摘要

这个模块允许使用正则表达式重写URI(需PCRE库),并且可以根据相关变量重定向和选择不同的配置。如果这个指令在server字段中指定,那么将在被请求的location确定之前执行,如果在指令执行后所选择的location中有其他的重写规则,那么它们也被执行。如果在location中执行这个指令产生了新的URI,那么location又一次确定了新的URI。这样的循环可以最多执行10次,超过以后nginx将返回500错误。

指令

break

语法:break

默认值:none

使用字段:server, location, if

完成当前设置的规则,停止执行其他的重写指令。

示例:


1

2

3

4

if ($slow) {

  limit_rate  10k;

  break;

}

if

语法:if (condition) { … }

默认值:none

使用字段:server, location

注意:在使用if指令之前请查看if
is evil page
并且尽量考虑用try_files代替。

判断一个条件,如果条件成立,则后面的大括号内的语句将执行,相关配置从上级继承。

可以在判断语句中指定下列值:

  • 一个变量的名称;不成立的值为:空字符传”“或者一些用“0”开始的字符串。
  • 一个使用=或者!=运算符的比较语句。
  • 使用符号~*和~模式匹配的正则表达式:
  • ~为区分大小写的匹配。
  • ~*不区分大小写的匹配(firefox匹配FireFox)。
  • !~和!~*意为“不匹配的”。
  • 使用-f和!-f检查一个文件是否存在。
  • 使用-d和!-d检查一个目录是否存在。
  • 使用-e和!-e检查一个文件,目录或者软链接是否存在。
  • 使用-x和!-x检查一个文件是否为可执行文件。

正则表达式的一部分可以用圆括号,方便之后按照顺序用$1-$9来引用。

示例配置:


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

if ($http_user_agent ~ MSIE) {

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

}

                                                                                                                                                       

if ($http_cookie ~* "id=([^;]
+)(?:;|$)"
 ) {

  set  $id  $1;

}

                                                                                                                                                       

if ($request_method = POST ) {

  return 405;

}

                                                                                                                                                       

if (!-f $request_filename) {

  break;

  proxy_pass  http://127.0.0.1;

}

                                                                                                                                                       

if ($slow) {

  limit_rate  10k;

}

                                                                                                                                                       

if ($invalid_referer) {

  return   403;

}

                                                                                                                                                       

if ($args ~ post=140){

  rewrite ^ http://example.com/
permanent;

}

内置变量$invalid_referer用指令valid_referers指定。

return

语法:return code

默认值:none

使用字段:server, location, if

这个指令结束执行配置语句并为客户端返回状态代码,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416与500-504。此外,非标准代码444将关闭连接并且不发送任何的头部。

rewrite

语法:rewrite regex replacement flag

默认值:none

使用字段:server, location, if

按照相关的正则表达式与字符串修改URI,指令按照在配置文件中出现的顺序执行。

可以在重写指令后面添加标记。

如果替换的字符串以http://开头,请求将被重定向,并且不再执行多余的rewrite指令。

尾部的标记(flag)可以是以下的值:

  • last - 完成重写指令,之后搜索相应的URI或location。
  • break - 完成重写指令。
  • redirect - 返回302临时重定向,如果替换字段用http://开头则被使用。
  • permanent - 返回301永久重定向。

注意如果一个重定向是相对的(没有主机名部分),nginx将在重定向的过程中使用匹配server_name指令的“Host”头或者server_name指令指定的第一个名称,如果头不匹配或不存在,如果没有设置server_name,将使用本地主机名,如果你总是想让nginx使用“Host”头,可以在server_name使用“*”通配符(查看http核心模块中的server_name)。例如:


1

2

3

rewrite  ^(/download/.*)/media/(.*)\..*$ 
$1
/mp3/$2.mp3  last;

rewrite  ^(/download/.*)/audio/(.*)\..*$ 
$1
/mp3/$2.ra   last;

return   403;

但是如果我们将其放入一个名为/download/的location中,则需要将last标记改为break,否则nginx将执行10次循环并返回500错误。


1

2

3

4

5

location /download/ {

  rewrite  ^(/download/.*)/media/(.*)\..*$ 
$1
/mp3/$2.mp3  break;

  rewrite  ^(/download/.*)/audio/(.*)\..*$ 
$1
/mp3/$2.ra   break;

  return   403;

}

如果替换字段中包含参数,那么其余的请求参数将附加到后面,为了防止附加,可以在最后一个字符后面跟一个问号:


1

rewrite  ^/users/(.*)$  /show?user=$1? 
last;

注意:大括号({和}),可以同时用在正则表达式和配置块中,为了防止冲突,正则表达式使用大括号需要用双引号(或者单引号)。例如要重写以下的URL:


1

/photos/123456

为:


1

/path/to/photos/12/1234/123456.png

则使用以下正则表达式(注意引号):


1

rewrite  "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;

如果指定一个“?”在重写的结尾,Nginx将丢弃请求中的参数,即变量$args,当使用$request_uri$uri&$args时可以在rewrite结尾使用“?”以避免nginx处理两次参数串。

在rewrite中使用$request_uri将www.example.com重写到example.com:


1

2

3

4

server {

   server_name www.example.com;

   rewrite ^ http://example.com$request_uri?
permanent;

}

同样,重写只对路径进行操作,而不是参数,如果要重写一个带参数的URL,可以使用以下代替:


1

2

3

if ($args ^~ post=100){

  rewrite ^ http://example.com/new-address.html?
permanent;

}

注意$args变量不会被编译,与location过程中的URI不同(参考http核心模块中的location)。

rewrite_log

语法:rewrite_log on | off

默认值:rewrite_log off

使用字段:server, location, if

变量:无

启用时将在error log中记录notice 标记的重写日志。

set

语法:set variable value

默认值:none

使用字段:server, location, if

指令设置一个变量并为其赋值,其值可以是文本,变量和它们的组合。

你可以使用set定义一个新的变量,但是不能使用set设置$http_xxx头部变量的值。

uninitialized_variable_warn

语法:uninitialized_variable_warn on|off

默认值:uninitialized_variable_warn on

使用字段:http, server, location, if

开启或关闭在未初始化变量中记录警告日志。

事实上,rewrite指令在配置文件加载时已经编译到内部代码中,在解释器产生请求时使用。

这个解释器是一个简单的堆栈虚拟机,如下列指令:


1

2

3

4

5

6

7

8

location /download/ {

  if ($forbidden)
{

    return   403;

  }

  if ($slow)
{

    limit_rate  10k;

  }

  rewrite  ^/(download/.*)/media/(.*)\..*$ 
/$1
/mp3/$2.mp3  break;

将被编译成以下顺序:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

variable $forbidden

checking to zero

recovery 403

completion of entire code

variable $slow

checking to zero

checkings of regular excodession

copying "/"

copying $1

copying "/mp3/"

copying $2

copying ".mp3"

completion of regular excodession

completion of entire sequence

注意并没有关于limit_rate的代码,因为它没有提及ngx_http_rewrite_module模块,“if”块可以类似”location”指令在配置文件的相同部分同时存在。

如果$slow为真,对应的if块将生效,在这个配置中limit_rate的值为10k。

指令:


1

rewrite  ^/(download/.*)/media/(.*)\..*$ 
/$1
/mp3/$2.mp3  break;

如果我们将第一个斜杠括入圆括号,则可以减少执行顺序:


1

rewrite  ^(/download/.*)/media/(.*)\..*$ 
$1
/mp3/$2.mp3  break;

之后的顺序类似如下:


1

2

3

4

5

6

7

checking regular excodession

copying $1

copying "/mp3/"

copying $2

copying ".mp3"

completion of regular excodession

completion of entire code

2.简单案例
注,由于配置文件内容较多,为了让大家看着方便,我们备份一下配置文件,打开一个新的配置文件。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[[email protected] ~]# cd /etc/nginx/

[[email protected] nginx]# mv nginx.conf nginx.conf.proxy

[[email protected] nginx]# cp nginx.conf.bak nginx.conf

[[email protected] nginx]# vim /etc/nginx/nginx.conf

server {

      listen       80;

      server_name  localhost;

      #charset koi8-r;

      #access_log  logs/host.access.log  main;

      location / {

          root   html;

          index  index.html index.htm;

          rewrite ^/bbs/(.*)$
http:
//192.168.18.201/forum/$1;

      }

}

准备forum目录与测试文件

1

2

3

4

5

6

7

[[email protected] ~]# cd /var/www/html/

[[email protected] html]# ls

index.html

[[email protected] html]# mkdir forum

[[email protected] html]# cd forum/

[[email protected] forum]# vim index.html

<h1>forum page!</h1>

测试一下

好了,下面我们来测试一下rewrite重写。

3.重新加载一下配置文件

1

2

3

4

[[email protected] 63]# service nginx reload

nginx: the configuration file /etc/nginx/nginx.conf
syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is
successful

重新载入 nginx:                                           [确定]

4.测试一下

注,大家可以从图中看出,status code 302指的是临时重定向,那就说明我们rewrite重写配置成功。大家知道302是临时重定向而301是永久重定向,那么怎么实现永久重定向呢。一般服务器与服务器之间是临时重定向,服务器内部是永久重定向。下面我们来演示一下永久重定向。

5.配置永久重定向


1

2

3

4

5

6

7

8

9

10

11

12

[[email protected] nginx]# vim /etc/nginx/nginx.conf

server {

        listen       80;

        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {

            root   html;

            index  index.html index.htm;

            rewrite ^/bbs/(.*)$ /forum/$1;

        }

}

准备forum目录与测试文件

1

2

3

4

5

6

7

[[email protected] ~]# cd /usr/html/

[[email protected] html]# ls

50x.html  index.html

[[email protected] html]# mkdir forum

[[email protected] html]# cd forum/

[[email protected] forum]# vim index.html

<h1>192.168.18.208 forum page</h1>

6.重新加载一下配置文件


1

2

3

4

[[email protected] ~]# service nginx reload

nginx: the configuration file /etc/nginx/nginx.conf
syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is
successful

重新载入 nginx:                                           [确定]

7.测试一下

注,大家从图中可以看到,我们访问bbs/是直接帮我们跳转到forum/下,这种本机的跳转就是永久重定向也叫隐式重定向。好了,rewrite重定向我们就说到这里了,想要查询更多关于重定向的指令请参考官方文档。最后,我们来说一下读写分离。

时间: 2024-08-09 21:46:20

Nginx之URL重写的相关文章

Cento7+Nginx 之 URL重写

Cento7+Nginx  之  URL重写 我们前一篇文章写了一个Cento7+Nginx 反向代理实现多域名跳转,今天主要介绍一下Cento7+Nginx  之  URL重写, Hostname:A-S.IXMSOFT.COM IP:192.168.5.20 Role:Nginx server 我们首先准备安装Nginx仓库 Yum install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.

夺命雷公狗---linux NO:37 linux下nginx的URL重写或者伪静态页面

最终效果如下所示: 其实很简单,首先在  html   目录下创建一个test.php 的文件,如下所示: 然后使用vi打开他,写份测试源码,源码如下所示: 然后保存退出,去到   /usr/local/nginx/conf   找nginx.conf   配置文件,修改一下即可.. 在46行加入修改规则即可,说白了就玩正则表达式而已,$1 是nginx给我们预留的变量,直接使用即可 rewrite leigood-(\d+)\.html /test.php?id=$1; 修改完成后回到   s

nginx配置url重写

url重写是指通过配置conf文件,以让网站的url中达到某种状态时则定向/跳转到某个规则,比如常见的伪静态.301重定向.浏览器定向等 rewrite 语法 在配置文件的server块中写,如: server { rewrite 规则 定向路径 重写类型; } 规则:可以是字符串或者正则来表示想匹配的目标url 定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用$index来表示正则里的捕获分组 重写类型: last :相当于Apache里德(L)标记,表示完成rewrite

nginx-url重写

location /game_web{ if (!-e $request_filename){//请求不是文件或者目录 rewrite ^/game_web/(\w*)/(\w*)$ /game_web_dyn/index.php/$ 1/init/$2 last; break; } }

nginx discuz url重写

rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last; rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last; rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdispl

Nginx反向代理、负载均衡、页面缓存、URL重写及读写分离详解

大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载:http://yunpan.cn/QXIgqMmVmuZrm 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.ngin

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载:http://yunpan.cn/QXIgqMmVmuZrm 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.ngin

Nginx反向代理 负载均衡 页面缓存 URL重写及读写分离

大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载:http://yunpan.cn/QXIgqMmVmuZrm 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.ngin

[转载]Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载:http://yunpan.cn/QXIgqMmVmuZrm 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.ngin