一、什么是重定向

学过计算机网络的同学对重定向会有一定的了解,老师在讲到HTTP协议的时候会说到几个状态码。其中 2xx代表成功,3xx代表重定向。在重定向中比较重要的就是301——永久重定向,它表示请求的资源已经被分配到新的URL,以后应使用资源现在所指的URL。和302——临时性重定向,它表示请求的资源已经被分配到新的URL,希望用户本次能使用新的URL访问。说了这么多,什么是重定向呐?个人通俗的理解:服务器上面的资源换了个位置(就是搬新家,原来在那个地方的资源放到了别处。当有客户要访问这个资源时,把新的位置告诉客户,让客户去指定的地方快找)。
说完个人理解来看一下概念:通过各种方法将网络请求重新定个方向转到其他位置(分为外部和内部)。外部重定向就是在URL中能看到重新定位到其它位置,内部重定向URL处没有表现

二、重定向简单实例

在开始说之前先来看一个简单的例子

项目的目录结构

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转


在.htaccess文件中输入下面代码

RewriteEngine on
RewriteRule ^(.*)\.htm$  $1.html

因为我配置了虚拟站点所以需要在apache-》conf-》extra下面找到httpd-vhostxs.conf文件

request 重定向和跳转 httpcatcher重定向_301_02


把AllowOverride none改为all(如果你的已经是ALL就不需要改了)

request 重定向和跳转 httpcatcher重定向_301_03

如果大家对虚拟站点不知道,可以参考一下其他人的博客了解一下

保存配置重新启动apache,就可以访问one.html文件了

request 重定向和跳转 httpcatcher重定向_apache_04

注意:我这里访问的是one.htm但是最后输出的是one.html里面的内容,这里因为我在.htaccess文件里面使用了匹配规则,把访问htm的文件重定向到html文件上面

三、apache mod_rewrite模块基础知识

(一)、RewriteBase

RewriteBase是指定整个URL操作的路径
语法:RewriteBase URL-path
使用说明:设置了目录级别的基准URL

实战

没有设置rewriteBase和设置了rewriteBase的比较

先看一下目录结构

request 重定向和跳转 httpcatcher重定向_重定向_05


①:没有设置RewriteBase

.htaccess文件内容

RewriteEngine on
RewriteRule ^(.*)\.htm$  /$1.html

注意/表示你项目配置的根目录,我配置的根目录为E:/PHPstorm/one

效果图

request 重定向和跳转 httpcatcher重定向_重定向_06


request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_07

②:设置RewriteBase

RewriteEngine on
RewriteBase /two/
RewriteRule ^(.*)\.htm$  $1.html [R]

效果图

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_08


request 重定向和跳转 httpcatcher重定向_302_09


比较可以发现加了RewriteBase,就会以RewriteBase指定的目录为根目录进行访问。如果不加RewriteBase就会按照原来配置的根目录来访问。

(二)、RewriteRule 语法说明

语法:模式匹配 替换的url [flags]

说明
①:模式匹配支持perl格式的正则表达式和rewrite的变量
②:多个flag之间用逗号隔开

①:RewriteRule R flag说明

使用说明
强制外部重定向,后面可以加301或302跳转,缺省值为302
例子

RewriteRule ^/?(.*)\.html /src/$1.php [R=302]
这是一个外部重定向

②:RewriteRule C flag说明

使用说明
连接下一条规则
例子:

RewriteEngine on
RewriteRule ^/?(.*)\.html /src/$1.htm [C]
RewriteRule ^/?(.*)\.html /src/$1.php

解释:只用第一条规则匹配了才能匹配第二条规则,他们是一个整体,如果第一条规则没有匹配,那么第二条规则就不会匹配
实战
.htaccess文件内容

RewriteEngine on
RewriteRule ^(.*)\.htm  /$1.html [C]
RewriteRule ^(.*)\.html  /$1.php

文件的目录结果

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_10


接下来访问two.htm

request 重定向和跳转 httpcatcher重定向_重定向_11


发现重定向到了two.php里面(内部重定向)

③:RewriteRule L flag说明

使用说明:最后一条匹配,立即停止重写,并不再使用其他重写规则
例子

RewriteEngine on
RewriteRule  ^(.*)\.htm$ /$1.html [L]
RewriteRule  ^(.*)\.tx$   /$1.txt

解释:加上L标签表示当第一行匹配了,下一行就不匹配了。如果没有匹配下一行再匹配
实战
.htaccess文件内容

RewriteEngine on
RewriteRule  ^(.*)\.htm$ /$1.html [L]
RewriteRule  ^(.*)\.tx$   /$1.txt

目录结构

request 重定向和跳转 httpcatcher重定向_301_12


接下来访问doc.tx和one.htm来验证

request 重定向和跳转 httpcatcher重定向_apache_13


request 重定向和跳转 httpcatcher重定向_302_14

④:RewriteRule NE flag说明

使用说明:不对URL中的特殊字符进行hexcode转码
例子

RewriteRule  ^(.*)\.htm$ /index.html#$1 [R,NE] 
加上NE表示不对#号进行转义

实战
.htaccess文件内容

RewriteEngine on
RewriteRule  ^(.*)\.htm$ /index.html#$1 [R,NE]

效果

request 重定向和跳转 httpcatcher重定向_301_15


如果不加NE,效果如下

request 重定向和跳转 httpcatcher重定向_apache_16


把#号转义成了%23

⑤:RewriteRule NC flag说明

使用说明:不区分大小写
例子

RewriteEngine on
RewriteRule ^test/(.*)\.htm  /two/$1.html [NC]
加上NC,表示对test不区分大小写,就是你输入test和TEST是一样的

实战
.htaccess文件内容

RewriteEngine on
RewriteRule ^test/(.*)\.htm  /two/$1.html [NC]

效果图(test小写)

request 重定向和跳转 httpcatcher重定向_apache_17


效果图(TEST大写)

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_18


request 重定向和跳转 httpcatcher重定向_重定向_19


如果在.htaccess文件中把NC去掉

效果图

request 重定向和跳转 httpcatcher重定向_301_20

⑥:RewriteRule G flag说明

使用说明:请求的网页已经失效
例子

RewriteEngine on
RewriteRule ^two/.*$ - [F]
把two目录失效

实战
.htaccess文件内容

RewriteEngine on
RewriteRule ^two/.*$ - [F]

我的目录结构为

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_21


当访问two目录时会出现(403禁止访问)

request 重定向和跳转 httpcatcher重定向_301_22

⑥:RewriteRule QSA flag说明

使用说明:用于在URL截取查询的字符串
例子

RewriteEngine on
RewriteRule ^two/(.*)$ /two.php?url=$1 [R,QSA]

实战
.htaccess文件内容

RewriteEngine on
RewriteRule ^two/(.*)$ /two.php?url=$1 [R,QSA]

效果图

request 重定向和跳转 httpcatcher重定向_302_23


request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_24


如果不加QSA,效果图如下

request 重定向和跳转 httpcatcher重定向_apache_25


![在这里插入图片描述](

request 重定向和跳转 httpcatcher重定向_302_26


发现它只会截取到two.php后面的参数不会截取

(三)、RewriteCond

语法:RewriteCond testString CondPattern(匹配模式) [flags]
使用说明:RewriteCond定义了一个规则条件

①:RewriteCond访问rule变量

实战
.htaccess文件内容

RewriteEngine on
RewriteCond $1 "two"
RewriteRule ^(.*)\.htm$  /$1.html

说明:只有满足你访问的htm文件名为two时才能完成匹配

如果你访问one.htm,就会出现404

request 重定向和跳转 httpcatcher重定向_重定向_27


如果你访问two.htm,就会成功!

request 重定向和跳转 httpcatcher重定向_重定向_28

②:RewriteCond 服务器变量

TestString 使用说明 %{NAME_OF_VARIABLE}
实战
.htaccess文件内容

RewriteEngine on
RewriteCond %{HTTP_HOST} "127.0.0.1"
RewriteRule ^(.*)\.htm$ http://localhost/$1.html [R]

request 重定向和跳转 httpcatcher重定向_302_29


request 重定向和跳转 httpcatcher重定向_重定向_30


服务器变量还有如下

request 重定向和跳转 httpcatcher重定向_apache_31

----------------------------------------------------------------------------------------------照片来源来源慕课网

③:RewriteCond cond变量

TestString 使用说明%1-9
%1-9是RewriteCond条件中最后符合条件中的分组成分
实战
.htaccess文件内容

RewriteEngine on
RewriteCond %{HTTP_HOST} "127.0.0.(.*)"
RewriteCond %1 "1"
RewriteRule ^(.*)\.htm$ http://localhost/$1.html [R]

效果图

request 重定向和跳转 httpcatcher重定向_apache_32


request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_33


如果把.htaccess文件内容改成下面的代码

RewriteEngine on
RewriteCond %{HTTP_HOST} "127.0.0.(.*)"
RewriteCond %1 "2"
RewriteRule ^(.*)\.htm$ http://localhost/$1.html [R]

效果图

request 重定向和跳转 httpcatcher重定向_302_34


request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_35


是找不到的

③:RewriteCond CondPattern(匹配模式)

CondPattern使用说明 -d表示是否目录 -f表示是否是文件
flag中or的用法,or是条件判断的或如果不加缺省值为and
例子

#RewriteCond %{REQUEST_FILENAME} !-d 的意思是访问的路径不是一个目录时RewriteRule才能生效
  RewriteCond %{REQUEST_FILENAME} !-d

  #RewriteCond的 %{REQUEST_FILENAME} !-f  的意思是访问的路径不是一个文件时RewriteRule才能生效
  RewriteCond %{REQUEST_FILENAME} !-f

实战
.htaccess文件内容

RewriteEngine on
RewriteCond E:/PHPstorm/one -d [OR]
RewriteCond E:/PHPstorm/onew -d
RewriteRule ^(.*)\.htm$  /$1.html

效果图:

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_36


如果把 OR去掉

RewriteEngine on
RewriteCond E:/PHPstorm/one -d 
RewriteCond E:/PHPstorm/onew -d
RewriteRule ^(.*)\.htm$  /$1.html

效果图:

request 重定向和跳转 httpcatcher重定向_302_37

就会出现404,这是因为没有OR,缺省值为and,RewriteCond的两个条件都得满足才能访问,第二个cond条件中不是目录,不符合,所以出现了404

(四)、RewriteMap

语法 RewriteMap MapName MapType MapSource
MapName: 命名给RewriteRule调用
MapType: Map文件类型 有txt,rnd等
MapSource:map文件路径

如何访问txt格式文件
${MapName:LookupKey|DefaultValue}
例子

RewriteMap pages txt:E:\XAMPP\XAMPP\apache\conf\map.txt
test1 pagetest1
test2 pagetest2
RewriteRule ^(.*).shtml $(pages:$1|page).php

实战

虚拟站点配置

request 重定向和跳转 httpcatcher重定向_apache_38


向map.txt中输入一下内容,并重新启动apache

request 重定向和跳转 httpcatcher重定向_request 重定向和跳转_39


.htaccess文件内容

RewriteEngine on
RewriteRule ^(.*)\.shtml$ ${pages:$1|NOTFOUND}.html

在one目录下面建立两个html如下图(为了效果明显)

request 重定向和跳转 httpcatcher重定向_apache_40


效果图:

request 重定向和跳转 httpcatcher重定向_重定向_41


request 重定向和跳转 httpcatcher重定向_apache_42


rnd文件也和txt比较类似,可以参考下面的网站

RewriteMap