Nginx Rewrite

1 Nginx Rewrite 概述

1. Rewrite 跳转场景

Rewrite 跳转场景主要包括以下几种:

  • 可以调整用户浏览的URL , 看起来更规范, 合乎开发及产品人员的需求。
  • 为了让搜索引擎搜录网站内容及用户体验更好, 企业会将动态URL 地址伪装成静态地址提供服务。
  • 网址换新域名后, 让旧的访问跳转到新的域名上。例如, 访问京东的360buy. com 会跳转到jd.com 。
  • 根据特殊变簸、目录、客户端的信息进行URL调整等。

2. Rewrite 跳转实现

N ginx 是通过ngx_ http rewrite_ module 模块支持url 重写、支持if 条件判断, 但不支持else 。另外该模块需要PCRE 支持, 应在编译N ginx 时指定PCRE 支待, 默认已经安装。根据相关变量重定向和选择不同的配置, 从一个location 跳转到另一个location , 不过这样的循环最多可以执行10 次, 超过后Nginx 将返回500 错误。同时, 重写模块包含set 指令,来创建新的变量并设其值, 这在有些情景下非常有用的, 如记录条件标识、传递参数到其他location 、记录做了什么等等。rew「ite 功能就是使用Nginx 提供的全局变量或自己设置的变鼠, 结合正则表达式和标志位实现url 重写以及重定向。

3. Rewrite 实际应用场杲

在实际工作的应用中, Nginx 跳转需求有三种方式可实现。可以直接用re'Nfite 进行匹配跳转, 也可以使用if 匹配全局变械后跳转。另外, 还可以使用location 匹配再跳转。所以rewrite 只能放在serve飞} 、f{}、location{}配置段中。例如location 只能对域名后边的除去传递的参数外的字符串起作用,例如http ://www.kgc.com/index. ph p?id=1 只对/i ndex. php 重写。如果想对域名或参数字符串起作用,可以使用if 全局变量匹配, 也可以使用proxy_pass反向代理。

4. Ngi nx 正则表达式

字符描述
^匹配输入字符串的起始位置
$匹配输入字符串的结束位置
*匹配前面的字符零次或多次。如'ol*“能匹配'o”及'ol” 、“oll"
+匹配前面的字符一次或多次。如'ol+“能匹配'ol”及'oll”、“oll", 但不能匹配”o"
?匹配前面的字符零次或一次, 例如`do(es)?”能匹配“do”或者”does",”?”等效千'{O, 1}"
.匹配除“\n”之外的任何单个字符, 若要匹配包括“\n”在内的任意字符,请使用诸如1\n]”
之类的模式
\将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如'\n"匹配一
个换行符, 而'\$”则匹配`$"
\d匹配纯数字
{n}重复n 次
{n,}重复n 次或更多次
[c]匹配单个字符c
[a-z]匹配a-z 小写字母的任意一个
[a-zA-Z]匹配a-z 小写字母或A-Z 大写字母的任意一个

2 Nginx Rewrite 基本操作

2.1 Rewrite 语法

Rewrite 命令的语法如下所示,其中regex 表示正则匹配规则、rep lacement 表示跳转后的内容、flag表示rewrite 支持的flag 标记。

rewrite<regex><replacement>[flag);

flag 标记说明:

  • last: 相当千Apache 的[L]标记, 表示完成rev-vrite 。
  • break : 本条规则匹配完成即终止, 不再匹配后面的任何规则。
  • red irect: 返回302 临时重定向, 浏览器地址会显示跳转后的URL 地址, 爬虫不会更新url (因为是临时)。
  • permanent: 返回301 永久重定向, 浏览器地址栏会显示跳转后的URL 地址, 爬虫更新url 。

last 和break 区别是: last 一般写在server 和if 中, 而break 一般使用在location 中。
last 不终止重写后的url 匹配, 即新的url 会再从serve「走一遍匹配流程, 而b「eak 终止重写后的匹配。

2.2Location 分类

locati on 大致可以分为三类, 语法如下:

location = patt {}[精准匹配]
location patt {}[一般匹配]
location ~ patt {}[正则匹配]

  • ~ : 表示执行一个正则匹配, 区分大小写。
  • ~*: 表示执行一个正则匹配, 不区分大小写。
  • ~: 表示执行一个正则匹配, 区分大小写不匹配。
  • ~* : 表示执行一个正则匹配,不区分大小写不匹配。
  • ~: 表示普通字符匹配。使用前缀匹配。如果匹配成功, 则不再匹配其他location 。
  • = : 进行普通字符精确匹配, 也就是完全匹配。
  • @ : 它定义一个命名的location, 使用在内部定向时, 例如error_page, try_files 。

2.3Location 优先级

在Nginx 的location 配置中location 的顺序没有太大关系。匹配优先级和location 表达式的类型有关: 相同类型的表达式, 字符串长的会优先匹配。

  • 等号类型( = ) 的优先级最高。一旦匹配成功, 则不再查找其他匹配项。
  • ~类型表达式。一旦匹配成功, 则不再查找其他匹配项。
  • 正则表达式类型( ~和~* )的优先级次之。
  • 常规字符串匹配类型。按前缀匹配。
  • 通用匹配( /) , 如果没有其它匹配, 任何请求都会匹配到。

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

(1) 执行server 块里面的rel/I/rite 指令。
(2) 执行location 匹配。
(3) 执行选定的location 中的「el/I/rite 指令。

location = / {
[ configurationA]

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

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

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

}
# 匹配任何以/images/ 开头的地址, 匹配符合以后, 停止向下匹配
location ^~ /images/ {
[ configuration E]

}
# 匹配所有以gif.jpg 或jpeg 结尾的请求, 然而所有请求/images/下的图片会被[ configuration E] 处理, 因为^~ 的优先级更高
location ~* \.(gifljpglipeg)$ {
[ configuration F]

}
# 最长字符匹配到/images/abc , 优先级砐低
location /images/abc {
[ configuration G]

}
# 匹配以/i mag es/abc 开头的, 优先级次之
location~ /images/abc {
[ configuration H]

}
# 匹配/i mages/abc/1.html 文件, 如果和正则~ /images/abc/1.html 相比, 正则优先级更高
location /images/abc/1.html {
[ configuration I]

}

如果是匹配某个具体文件:

(location= 完整路径) > (location ^~ 完整路径) > (location~* 完整路径)
> (location ~ 完整路径) > ( lo cation 完整路径) > (location /)

如果是用目录做匹配访问某个文件:

(location= 目录) > (location ^~ 目录/) >(location ~ 目录)
> (location ~*目录) > (location 目录) > (location /)

2.4 Rewrite 常见示例

1 . 安装Ngi nx 服务

[root@localhost ~]# rpm -Uvh
http ://n gi nx.org/packag es/centos/7/noarch/RPMS/ngi nx-rel ease-centos干0.el7. ng x.noarch.rpm
[root@localhost ~]#yum install -y nginx

2 . 修改Ngi nx 默认站点配置文件

修改/etc/nginx/conf .d/default. conf 文件中如下两行红色字体。

[root@localhost ~]#vim /etc/ng i nx/ co nf.d/defa u It. co nf
server {
listen  80;
server_name www.kgc.com;
#charset koi8-r;

access_log /var/log/nginx/www.kgc.com-access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
#error_page 404       /404.html;
…...//省略部分
[root@localhost ~]#systemctl start nginx

3. Rewrite 示例

( 1) 基千域名的跳转

假如, 现在公司旧域名www.kgc.com 有业务需求变更, 需要使用新域名www.newkgc.com 代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。在/etc/nginx/conf.d/default .conf 文件里的location /下面添加如下内容。

[root@localhost~]#vim /etc/nginx/conf.d/default.conf
if ($host ='www.kgc.com')

{
rewrite ^/(.*)$ http://www.newkgc.com/$1 permanent;

}
[root@localhost ~]#systemctl reload nginx

域名直接跳转

按F12 可以清楚的看到从旧域名www.kgc.com 跳转到了新域名www.newkgc.com 上,状态码是30 1 永久重定向。页面效果如图所示。

域名后面加参数跳转

因为在代码中很多请求是带参数的, 所以要保证参数都能正常跳转。浏览器输入模拟访问http ://www.kgc.com/test/1 /index. ph p( 虽然这个请求内容是不存在的) 跳转到http://www.newkgc.com/test/1 /index. php , 可以看到301 实现了永久重定向跳转,而且域名后的参数也正常跳转,如图所示。

( 2 ) 基于客户端IP 访问跳转

例如今天公司业务版本上线, 要求所有IP 访问任何内容都显示一个固定维护页面,只有公司IP 访问正常。在/etc/nginx/conf.d/default.conf 文件里添加如下内容。

[root@localhost~]#vim /etc/ngin x/conf.d/default.conf
set $rewrite true ;
if ($remote_addr=“192.168.6.125") {
set $rewrite false;

}
if ($rewrite = true) {

rewrite (.+) /maintenance.html;

}
location= /maintenance.html {
root /usr/sha「e/ng i nx/html ;

}
[root@localhost ~]#echo "Website is Maintaining,Please visit later.">
/usr/share/nginx/html/maintenance.html
[root@localhost ~]#systemctl reload nginx

只有IP 为192.168.6.125 能正常访问, 其它地址都是维护页面, 使用一个局域网的其它IP 地址用浏览器访问http://www. kgc.com 域名和加参数都是请求的ma intenance. html页面的内容, 而且状态码是200, 如图所示。

浏览器使用http://www.kgc. com/test 带参数访问也是显示维护页面内容,如图所示。

( 3 ) 基千旧域名跳转到新域名后面加目录

例如现在访问的是http ://bbs.kgc.com, 现在需要将这个域名下面的发帖都跳转到咄p ://www.kg c.com/bbs , 注意保待域名跳转后的参数不变。在/etc/ngi nx/conf.d/default .conf文件里修改如下内容。

[root@localhost~]#vim /etc/nginx/conf.d/default.conf
server_name bbs.kgc.com;
location /post {
rewrite (.+) http://www.kgc.com/bbs$1 permanent ;

}
[root@localhost ~]#systemctl reload nginx

模拟使用浏览器访问http ://bbs .kgc.com/post/1. php 跳转到http ://www.kg c.com/bbs/post/1.php ,如图所示。

( 4 ) 基于参数匹配的跳转

例如现在访问http://www. kgc.com/100-(1001200)-100. html 跳转到http://www. kgc.com页面。在/etc/nginx/conf .d/default. conf 文件里添加如下内容。

[「oot@localhost~]#vim /etc/nginx/conf.d/default.conf
if($「equest_uri~ ^/100-(100i200)-(\d+).html$) {
「ewrite (.*) http://www.kgc.com permanent;
(root@localhost ~]#systemctl reload nginx

使用浏览器访问http ://www.kg c.com/100-100-100.html , 如图所示。

使用浏览器访问http ://www.kg c.com/100-200-100 .html, 如图所示。

( 5 ) 基于目录下所有ph p 结尾的文件跳转
要求访问http ://www.kgc.com/upload/1.ph p 跳转到首页。在/etc/ngi nx/conf.d/default.conf 文件里添加如下内容。

[root@localhost ~]#vim /etc/ngin x/conf.d/default.conf
loc ation ~* /upload/. *\.php$ {
「ewrite (. +) http://wwwkgc.com permanent;
[root@localhos t ~]#sys temctl reload nginx

浏览器访问http ://www.kgc.com/upload/1 . php , 如图所示。

关千Ngi nx 「ew甘te 本章的内容就这么多。其实在实际工作中远远不止这些场景, 而且会更加复杂繁琐, 希望大家能举一反二, 多加练习。

  • 16
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值