Nginx 重写功能(location / rewrite)

发布时间 2023-03-27 19:07:01作者: 靖安yj

目录

一、Nginx常见模块

二、访问路由location

2.1 location常用正则表达式

2.2location的分类

2.3location 常用的匹配规则

2.4location优先级排列说明

2.5location 示例

2.6location 优先级总结

2.7实例

2.7.1location = / {} 与 location / {}

2.7.2 location = /index.html {} 与 location / {}

2.7.3location = /1.jpg {} 和 location ~* .(gif|jpg|png|jpeg)$ {}比较

2.7.4大小写问题

2.8实际网站使用中的三个匹配规则定义

第一个规则

第二个规则

第三个规则

三、REWRITE模块

3.1rewrite功能

3.2Rewrite 跳转场景

3.3Rewrite 跳转实现

3.4Rewrite 执行顺序

3.5Rewrite 语法格式

3.6 Rewrite 实例

3.6.1基于域名的跳转

3.6.2基于客户端IP 访问跳转

3.6.3基于旧域名跳转到新域名后面加目录

3.6.4基于参数匹配的跳转

3.6.5基于 目录下所有的php文件

3.6.6基于 普通的一条url

 

一、Nginx常见模块
http

http块是Nginx服务器配置中的重要部分,代理、缓存和日志定义等绝大多数的功能和第三方模块的配置都可以放在这模块中。作用包括:文件引入、MIME-Type定义、日志自定义、是否使用sendfile传输文件、连接超时时间、单连接请求数上限等。

server

server块,虚拟主机(虚拟服务器)。作用:使得Nginx服务器可以在同一台服务器上只要运行一组Nginx进程,就可以运行多个网站。

location

location块是server块的一个指令。作用:基于Nginx服务器接收到的请求字符串,虚拟主机名称(ip,域名)、url匹配,对特定请求进行处理。

二、访问路由location
2.1 location常用正则表达式

 

 

2.2location的分类

  • 精准匹配:location = / {}

  • 一般匹配:location / {}

  • 正则匹配:location ~ / {}

2.3location 常用的匹配规则

  1. 首先精确匹配 =

  2. 其次前缀匹配 ^~

  3. 其次是按文件中顺序的正则匹配 ~或~*

  4. 然后匹配不带任何修饰的前缀匹配

  5. 最后是交给 / 通用匹配

location = / {
[ configuration A ]
}

location / {
[ configuration B ]
}

location /documents/ {
[ configuration C ]
}

location ^~ /images/ {
[ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}

2.5location 示例

(1)精确匹配

location = / {}
=为精确匹配 / , 主机名后不能携带任何字符串,比如 / 和 /data ,则/匹配,/data不匹配

(2)一般匹配/通用匹配

location / {}
代表以/开头,所以这条规则将匹配所有的请求

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

location /documents/abc {}
匹配任何以/documents/abc开头的地址,匹配符合后,还会继续往下搜索其他 location,只有其它location后面的正则表达式没有匹配到时,才会用这一条

(3)正则匹配

location ^~ /images/ {}
匹配任何已/images/ 开头的地址,匹配符合后,停止往下搜索,采用这一条

location ~* \.(gif|jpg|jpeg)$ {}
匹配所有 gif jpg 或 jepg 结尾的请求
如果 有上面的location ^~ /images/ {}匹配 则会先匹配上一请求,所以到不了这一条。

2.6location 优先级总结

如果是匹配某个具体文件: (location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径) >(location ~ 完整路径) > (location /)通用匹配

2.7实例

2.7.1location = / {} 与 location / {}

实例1:location = / {} 和 location / {} ,按道理应匹配前者,但实际确实匹配后者,匹配只写域名精确匹配不生效,接下来一个小例子说明一下

1. #在配置文件添加匹规则
vim /usr/local/nginx/conf/nginx.conf

#添加的网页
location = / {
root /web/dog/;
}

#默认网页
location / {
root html;
index index.html index.htm; }

2. #新建网页站点目录
mkdir -p /web/dog

3. #在站点目录下新建index.html
vim /web/dog/index.html

this is dog web

4. #检查语法并重启
nginx -t
systemctl restart nginx.service

5. #在网页中测试
http://192.168.59.118/

在配置文件添加匹规则

 

 

新建网页站点目录,新建index.html文件

 

 检查语法并重启

 

 

 在网页中测试

 

 

 

2.7.2 location = /index.html {} 与 location / {}

在 根后 加上index.html 后生效

1. #修改一下配置文件
vim /usr/local/nginx/conf/nginx.conf

location = /index.html { # 加上index.html
root /web/dog/;
}


2. #重启服务,并网页中测试
systemctl restart nginx.service

 

 

 

 

2.7.3location = /1.jpg {} 和 location ~* .(gif|jpg|png|jpeg)$ {}比较

1. #修改一下配置文件
vim /usr/local/nginx/conf/nginx.conf

location = /1.jpg {
root /web/dog/; #小狗的网页
}

location ~* \.(jpg|gif|png) {
root /web/cat/; #小猫的网页
}

2. #在刚刚创建的dog的站点下添加图片
cd /web/dog/
拖入图片

3. #新建一个cat目录,添加图片
mkdir cat
cd cat
拖入图片


4. #检查语法,重启服务
nginx -t
nginx -s reload

5. #在网页中测试
http://192.168.59.118/1.jpg
结果可以看出=精确匹配


修改配置文件

 

 

 

在刚刚创建的dog的站点下添加图片

 

 

 新建一个cat目录,添加图片

 

 

 

 

 在网页中测试

 

 

2.7.4大小写问题

1. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf

location ~ /A.?\.jpg {
root /web/image;
index index.html index.htm;
}


2. #新建站点目录并拖入图片
cd /web
mkdir image
cd image/
拖入图片,然后改名为A.jpg
mv a.webp A.jpg

3. #重启并在网页中测试
nginx -s reload

 

修改配置文件

 

 

新建站点目录并拖入图片

 

 

 重启后,测试

 

 

 

 

 

 

 

1 .#在Linux中将A.jpg拷贝一份命名为a.jpg
cd /web/image/
cp A.jpg a.jpg

2. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf

location ~* /A.?\.jpg {
root /web/image;
index index.html index.htm;
}

3. #重启服务并测试
nginx -s reload
http://192.168.59.118/a.jpg

 

在Linux中将A.jpg拷贝一份命名为a.jpg

 

 

 修改配置文件

 

 

 重启再测试

 

 

 

2.8实际网站使用中的三个匹配规则定义

第一个规则

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

  • 可以是一个静态首页,也可以直接转发给后端应用服务器

  • location = / {
    root html;
    index index.html index.htm;
    }

第二个规则

是处理静态文件请求,这是nginx作为http服务器的强项有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用。

location ^~ /static/ {
root /webroot/static/ ;
}

location ~* \.(gif|jpg|jpeg)$ {
root /webroot/static/ ;
}

第三个规则

就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器。

location / {
proxy_pass http://tomcat_server;
}

三、REWRITE模块
现在 Nginx 已经成为很多公司作为前端反向代理服务器的首选,在实际工作中往往会 遇到很多跳转(重写 URL)的需求。比如更换域名后需要保持旧的域名能跳转到新的域名 上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的 Apache 服务器,虽然也能做跳转,规则库也很强大,但是用 Nginx 跳转效率会更高,这也是学习 本章的目的所在。

3.1rewrite功能
rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。

rewrite 只能在
server {}
location {}
if {}
中,并且默认只能对域名后边的除去传递的参数外的字符串起作用
例如:
http://www.yxp.com/abc/bbs/index.html?a=1&b=2 只针对/abc/bbs/index.html重写

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

1.可以调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求

2.为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态 URL 地址伪装成静态地址提供服务

3.网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com会跳转到 jd.com

4.根据特殊变量、目录、客户端的信息进行 URL 调整等。

3.3Rewrite 跳转实现
Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持 if 条件判断,但不支 持 else。

另外该模块需要 PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装。

根据相关变量重定向和选择不同的配置,从一个 location 跳转到另一个 location,不过这样 的循环最多可以执行 10 次,超过后 Nginx 将返回 500 错误。

同时,重写模块包含 set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。

3.4Rewrite 执行顺序

  1. 执行server块里面的rewrite指令。

  2. 执行location 匹配。

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

3.5Rewrite 语法格式

rewrite <regex> <replacement> [flag];
regex:表示正则匹配规则
replacement:表示跳转后的内容
flag:表示rewrite 支持的 flag 标记

flag 标记说明:
last:本条规则匹配完成后,继续向下匹配新的location URL规则,一般用在server和if中

break:本条规则匹配完成即终止,不再匹配后面的任何规则。一般用在location中

redirect:返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址,爬虫不会更新 url(因为是临时)。

permanent:返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址,爬虫更新 url。

 

 

3.6 Rewrite 实例

3.6.1基于域名的跳转

例如现在访问的是 域名yxp.com启用了顺米网shunmi.com的DNS服务!,现在需要将这个域名下面的发帖都跳转到 http://www.dhc.com,注意保持域名跳转后的参数不变。

 

1. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name www.yxp.com;

charset utf-8;

#access_log logs/host.access.log main;

location / {
root html;
index index.html index.htm;
}

location /index.html {
if ($host = 'www.yxp.com') {
rewrite ^/(.*)$ http://www.dhc.com/$1 permanent;
}
root /web/test;
}

2. #新建站点目录
mkdir /web/test

3. #新建文件
vim /web/test/index.html
this is test web!!!

4. #重启服务
nginx -s reload


5. #另外开一台虚拟机,修改/etc/hosts文件
vim /etc/hosts
192.168.59.118 www.yxp.com www.dhc.com

6. #打开新开的虚拟机的浏览器网页测试
http://www.yxp.com

修改配置文件

 

 

 新建站点目录和文件

 

 

 重启服务

 

 

 另外开一台虚拟机,修改/etc/hosts文件

 

 

 

在网页测试

 

 

 

3.6.2基于客户端IP 访问跳转

1. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name www.yxp.com;

charset utf-8;

#access_log logs/host.access.log main;
set $rewrite true;
if ($remote_addr = '192.168.91.103'){
set $rewrite false;
}
if ($rewrite = true){
rewrite (.+) /weihu.html;
}

location /weihu.html {
root /var/www/html;
}

location / {
root html;
index index.html index.htm;
}

2. #新建站点目录及文件
mkdir -p /var/www/html
vim /var/www/html/weihu.html

we are busing now,please wait for a moment!

3. #重启服务 nginx -s reload

4. #在网页测试
http://192.168.59.118/

修改配置文件

 

 

 新建站点目录及文件

 

 

 重启服务后在网页测试

 

 

 

 

 

3.6.3基于旧域名跳转到新域名后面加目录

例如现在访问的是 http://bbs.yxp.com/post 现在需要将这个域名下面的发帖都跳转到 http://www.yxp.com/bbs/post,注意保持域名跳转 后的参数不变

1. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.yxp.com;

charset utf-80;

#access_log logs/host.access.log main;
location /post {
rewrite (.+) http://www.yxp.com/bbs$1 permanent;
}

location / {
root html;
index index.html index.htm;
}

2. #新建站点目录,并创建文件
mkdir -p /usr/local/nginx/html/bbs/post
vim /usr/local/nginx/html/bbs/post/index.html

this is the test!!

3. #开一台服务器,修改/etc/hosts文件
vim /etc/hosts
192.168.59.118 www.yxp.com www.dhc.com bbs.yxp.com

4. #重启服务并在浏览器中测试
nginx -s reload
http://bbs.yxp.com/post

修改配置文件

 

 

 

新建站点目录

 

 

 创建文件

 

 

 开一台服务器,修改/etc/hosts文件

 

 

 

重启服务并在浏览器中测试

 

 

 

 

 

3.6.4基于参数匹配的跳转

http://www.yxp.com/100-(100|200)-100.html 跳转到 域名yxp.com启用了顺米网shunmi.com的DNS服务! 页面

1. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name www.yxp.com;

charset utf-8;

#access_log logs/host.access.log main;
location ~ /100-(100|200)-(\d+).html$ {
rewrite (.+) http://www.kgc.com permanent;
}

location / {
root html;
index index.html index.htm;
}


2. #重启服务
nginx -s reload

3. #验证
http://www.yxp.com/100-100-100

修改配置文件

 

 

 重启服务

 

 

 验证

 

 

 

3.6.5基于 目录下所有的php文件

要求访问 http://www.yxp.com/upload/123.php 跳转到首页

1. #修改配置文件
vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name www.yxp.com;

charset utf-8;

#access_log logs/host.access.log main;
location ~* /upload/.*\.php$ {
rewrite (.+) http://www.yxp.com permanent;
}

location / {
root html;
index index.html index.htm;
}

2. #重启服务
systemctl restart nginx

3. #在网页测试
http://www.yxp.com/upload/123.php

 

修改配置文件

 

 

 

重启服务

 

 

 在网页测试