apache的重定向主要是用RewriteCond及RewriteRule来完成,前者用于判断匹配条件,条件符合的将会转到下一条的Rewrite进行处理。
先看一个例子
#打开重写模块 RewriteEngine On #定义重写的基准路径 RewriteBase / #定义判断,若"%{http_host}"=="dmesg.top",则继续执行下面的RewriteRule RewriteCond %{http_host} ^dmesg.top$ [NC] #定义重写规则,将所有访问dmesg.top中的请求重定向到www.dmesg.top的相同路径 RewriteRule ^(.*)$ www.dmesg.top/$1 [R=301]
注意点:如果RewriteCond中的域名与RewriteRule跳转的域名相同时,会发生重定向次数过多的错误。原因为跳转符合RewriteCond跳转到RewriteRule中,因为RewriteRule中的域名又和RewriteCond一致,跳转时又匹配了RewriteCond。 例如: RewriteEngine On RewriteCond %{http_host} ^js.chd.edu.cn$ [NC] RewriteRule ^(.*)$ http://js.chd.edu.cn/index.htm [L] 如果想要跳转相同域名可不写RewriteCond RewriteEngine On RewriteRule ^(.*)$ http://js.chd.edu.cn/index.htm [L] 扩展 ^(.*)$ 表示贪婪匹配,即符合任何条件即可 ^(.*)?$ 表示懒惰匹配,需满足?后面的规则 例如^(.*)?.htm$
RewriteCond 语法
RewriteCond String Pattern [flags]
定义一个条件,当String所规定的内容与Pattern规则匹配时,才会执行RewriteRule规定重写。
string
(1) N : R e w r i t e R u l e 后 向 引 用 。 N:RewriteRule后向引用。 N:RewriteRule后向引用。N引用紧跟在RewriteCond之后的RewriteRule中Pattern的小括号中的规则在当前URL中匹配的内容。N是0 <= N <= 9之间的整数。
(2)%N:RewriteCond后向引用 。%N引用最后一个RewriteCond的Pattern中的小括号中的规则在当前URL中匹配的内容。N是0 <= N <= 9之间的整数。
pattern
(1) !:表示TestString不与当前正则匹配;格式是!CondPattern。 (2) >: 将condPattern作为普通字符串与String比较,String大于Pattern为真;格式是>Pattern。 (3) =:将condPattern作为普通字符串与String比较,String与Pattern相同时为真;格式是=Pattern。 (4) -d:将String当作一个目录名,检查它是否存在以及是否是一个目录;格式是-d。 (5) -f:将String当作一个文件名,检查它是否存在以及是否是一个文件;格式是-f。 (6) -s:将String当作一个文件名,检查它是否存在以及是否是一个长度大于0的文件;格式是-s。 (7) -l: 将String当作一个文件名,检查它是否存在以及是否是一个 symbolic link;格式是-l。 (8) -F:检查String是否是一个合法的文件,而且通过服务器范围内的当前设置的访问控制进行访问。检查通过一个内部subrequest完成的, 因此需要谨慎使用,以防止降低服务器的性能。 (9) -U:检查String是否是一个合法的URL,而且通过服务器范围内的当前设置的访问控制进行访问。检查通过一个内部subrequest完成的, 因此需要谨慎使用,以防止降低服务器的性能。
[flags]
(1)NC:表示不区分大小写。 (2)OR:默认的情况下,二个RewriteCond之间是AND的关系,用这个标志将关系改为OR,即满足任一的RewriteCond即执行RewriteRule。 RewriteEngine On RewriteCond [regex1] [OR] RewrireCond [regex2] RewriteRule [rule]
RewriteRule
RewriteRule Pattern Substitution [flags]
pattern
作用于当前URL的正则表达式;此url不包含协议、域名和查询字符串部分。
Substitution
当RewriteCond满足时,用来替换原始URL指定内容的字符串,还可以包括以下扩展:
(1) N : R e w r i t e R u l e 后 向 引 用 。 N:RewriteRule后向引用。 N:RewriteRule后向引用。N引用紧跟在RewriteCond之后的RewriteRule中Pattern的小括号中的规则在当前URL中匹配的内容。N是0 <= N <= 9之间的整数。
(2)%N:RewriteCond后向引用 。%N引用最后一个RewriteCond的Pattern中的小括号中的规则在当前URL中匹配的内容。N是0 <= N <= 9之间的整数。
[flags]
(1) R:表示重定性,[R=301]表示301永久重定向,如果未指定,则默认使用302状态代码。除了响应状态代码外,您还可以使用其符号名称指定重定向状态:(temp默认) permanent,或seeother。 临时重定向与永久重定向的区别:永久重定向会自动更改访问的路径,而临时重定向不会更改路径,只是显示新内容。 例如:旧网站域名为 a.com 新网站域名为 b.com。在nginx或apache中使用重定向将a.com转发到b.com.如果使用永久重定向,浏览器中输入a.com的域名时会自动变为b.com,如果使用临时重定向浏览器中输入a.com的域名时,域名并不会变成b.com但是展示的内容时b.com的内容。 (2) F:强制当前URL为被禁止的,即,立即反馈一个HTTP响应代码403(被禁止的)。 (3) G:强制当前URL为已废弃的,即,立即反馈一个HTTP响应代码410(已废弃的)。 (4) L:立即停止重写操作,并不再应用其他重写规则。 (5) N:重新执行重写操作(从第一个规则重新开始). 这时再次进行处理的URL已经不是原始的URL了,而是最后一个重写规则处理的URL。 (6) C:此标记使当前规则与下一个(其本身又可以与其后继规则相链接的, 并可以如此反复的)规则相链接。 它产生这样一个效果: 如果一个规则被匹配,通常会继续处理其后继规则, 即,这个标记不起作用;如果规则不能被匹配,则其后继的链接的规则会被忽略。 (7) NC:忽略大小写。 (8) QSA:此标记强制重写引擎在已有的替换串中追加一个请求串,而不是简单的替换。
示例
全站强制https跳转
#开启Rewrite重写功能 RewriteEngine on #判断规则为端口非443结尾 RewriteCond %{SERVER_PORT} !^443$ #强制访问到https的相应路径,响应状态码是302临时重定向 RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R] 例如: [root@localhost apache2]# wget http://webmanage.ecust.edu.cn --2020-12-19 15:48:33-- http://webmanage.ecust.edu.cn/ .......... 已发出 HTTP 请求,正在等待回应... 302 Found 位置:https://webmanage.ecust.edu.cn/ [跟随至新的 URL] --2020-12-19 15:48:33-- https://webmanage.ecust.edu.cn/
只针对某个站点跳转https
#开启Rewrite重写功能 RewriteEngine on #判断规则为访问端口为80 RewriteCond %{SERVER_PORT} 80 #并且(默认是and)HTTP_HOST=webmanage.ecust.edu.cn 忽略大小写 RewriteCond %{HTTP_HOST} ^webmanage.ecust.edu.cn [NC] #强制访问到https的相应路径,响应状态码是301永久重定向 RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301] 例如: [root@localhost apache2]# wget http://webmanage.ecust.edu.cn --2020-12-19 15:49:29-- http://webmanage.ecust.edu.cn/ 正在解析主机 webmanage.ecust.edu.cn (webmanage.ecust.edu.cn)... 172.20.7.170 正在连接 webmanage.ecust.edu.cn (webmanage.ecust.edu.cn)|172.20.7.170|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 301 Moved Permanently 位置:https://webmanage.ecust.edu.cn/ [跟随至新的 URL] --2020-12-19 15:49:30-- https://webmanage.ecust.edu.cn/ 正在连接 webmanage.ecust.edu.cn (webmanage.ecust.edu.cn)|172.20.7.170|:443... 已连接。
两个域名跳转https
#开启Rewrite重写功能 RewriteEngine on #判断规则为端口非443结尾 RewriteCond %{SERVER_PORT} 80 #并且(默认是and)HTTP_HOST=bo.kevin.com 忽略大小写 RewriteCond %{HTTP_HOST} ^bo.kevin.com [NC,OR] RewriteCond %{HTTP_HOST} ^bo.kevin.cN [NC] #强制访问到https的相应路径,响应状态码是302临时重定向 RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
当访问corpus.shisu.edu.cn/honghuaqing跳转到另一个网站
#开启Rewrite重写功能 RewriteEngine on #HTTP_HOST=corpus.shisu.edu.cn 忽略大小写 RewriteCond %{HTTP_HOST} corpus.shisu.edu.cn [NC] RewriteRule ^(/honghuaqing) http://10.1.76.67/ [L,R]
404页面
#开启Rewrite重写功能 RewriteEngine on #请求的文件名为一个常规文件但不存在,默认是AND,所以此处的flags不用设置 RewriteCond %{REQUEST_FILENAME} !-f #请求的文件名为一个目录但不存在 RewriteCond %{REQUEST_FILENAME} !-d #如果既不是常规文件,也不是常规目录,那么就跳转到404页面。 RewriteRule (.*) /404.htm
基于User-Agent的访问控制
#开启Rewrite重写功能 RewriteEngine on #判断客户端user-agent信息是否为IE浏览器 RewriteCond %{HTTP_USER_AGENT} ^.*MSIE.* [NC] #满足是IE浏览器,跳转到404页面,。表示访问任何URL RewriteRule . /404.html [L]
QSA
RewriteEngine On RewriteRule /pages/(.+) /page.php?page=$1
假如现在访问/pages/88?count=1页面,只会映射到:/page.php?page=88。
因为默认条件下,不会获取到查询字符串部分,(.+)只能匹配到88。
RewriteEngine On RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
访问/pages/88?count=1页面,将会映射到:/page.php?page=88&count=1
(1)[QSA]和正则表达式的子表达式配合使用。
(2)88?count=1中的问号被更换为$1
伪静态
RewriteRule ^article-([0-9]+)-([0-9]+)\.html$ portal.php?mod=view&aid=$1&page=$2&%1
输入article-8342-1.html实质访问portal.php?mod=view&aid=8342&page=1
访问路径添加/结尾
#开启Rewrite重写功能 RewriteEngine on #如果当前路径不是完整的文件路径,则不生效 RewriteCond ${REQUEST_FILENAME} ! -f #如果请求路径是以/结尾,则不生效 RewriteCond ${REQUEST_URI} !(.*)/$ #在路径后加上/,返回状态码301 RewriteRule ^(.*)$ $1/ [L,R=301]