Apache之Rewrite和RewriteRule规则梳理以及http强转https的配置总结

 

一. 简单实例介绍
通常来讲,apache配置好http和https后,若是想要作http强转到https,须要设置url重定向规则,大体须要下面几个步骤便可完成配置:php

1)在httpd.conf文件里使下面模块生效
[root@back ~]# cat /usr/local/apache/conf/httpd.conf
.....
LoadModule ssl_module modules/mod_ssl.so                      #打开https功能模块
.....
LoadModule rewrite_module modules/mod_rewrite.so              #打开重写跳转功能模块

2)httpd.conf配置文件或者是在httpd-vhost.conf文件里修改
[root@back ~]# cat /usr/local/apache/conf/httpd.conf
.......
DocumentRoot "/data/vhosts"
<Directory "/data/vhosts">
    Options FollowSymLinks MultiViews Includes
    AllowOverride All                                     #AllowOverride None必定要修改成AllowOverride All!!
    Require all granted
</Directory>

3)在网站根目录下面添加该文件".htaccess"目录访问控制文件,并添加以下内容:
RewriteEngine on          
RewriteBase /             
RewriteCond %{SERVER_PORT} !^443$    
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]    


含义是这样的:为了让用户访问传统的http://转到https://上来,用了一下rewrite规则:
第一句:启动rewrite引擎
第三句:rewrite的条件是访问的服务器端口不是443端口
第四句:这是正则表达式,^是开头,$是结束,/?表示有没有/均可以(0或1个),(.*)是任何数量的任意字符
整句的意思是讲:启动rewrite模块,将全部访问非443端口的域名请求,url地址内容不变,将http://变成https://。

上面的配置实现了将全部域名的http跳转为https,若是只是针对某一个url的https跳转,则配置状况会有所不一样,以下:html

实现单个url类型的https跳转需求:
访问http://bo.kevin.com/beijing/...... 强制跳转到https://bo.kevin.com/beijing/......
配置以下:

[root@docker-test2 web]# cat .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} /beijing
RewriteRule ^(.*$) https://bobo.kevin.com/beijing/ [R,L]
</IfModule>

===========Apache下http跳转至https的案例说明=============
1) 示例一nginx

RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} !^/tz.php
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]

%{SERVER_PORT}     说明访问端口
%{REQUEST_URI}      好比若是url是 http://localhost/tz.php,则是指 /tz.php
%{SERVER_NAME}    好比若是url是 http://localhost/tz.php,则是指 localhostgit

以上规则的意思是,若是访问的url的端口不是443,且访问页面不是tz.php,则应用RewriteRule这条规则。这样便实现了:访问了 http://localhost/index.php 或者 http://localhost/admin/index.php 等页面的时候会自动跳转到 https://localhost/index.php 或者 https://localhost/admin/index.php,可是访问 http://localhost/tz.php 的时候就不会作任何跳转,也就是说 http://localhost/tz.php 和 https://localhost/tz.php 两个地址均可以访问。github

2) 示例二
.htaccess 在每一层独立服务根目录下都存在,例如web

所有网站根目录为   /var/www/html/.htaccess
士博博客根目录位   /var/www/html/shibo-wordpress/.htaccess
士博论坛根目录位   /var/www/html/shibo-discuz/.htaccess
士博学习根目录位   /var/www/html/shibo-study/.htaccess

HTTP 80 强制转 HTTPS
全站采用https协议访问,因此须要http重定向到https,只须要在.htaccess加入下面规则
在相应的网站根目录新建 .htaccess正则表达式

例如,在士博博客的网站根目录下,新建/var/www/html/shibo-wordpress/.htaccess,内容以下:docker

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

或者内容为:thinkphp

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*) https://%{SERVER_NAME}/$1 [R,L]

强制301重定向 HTTPS数据库

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{SERVER_PORT} !^443$
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R=301,L]
</IfModule>

站点绑定多个域名
只容许kevin.con和www.kevin.com 跳转

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^kevin.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.kevin.com [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

高级用法 (可选)

RewriteEngine on

# 强制HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80

# 某些页面强制
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

# 强制HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443

# 某些页面强制
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

Apache mod_rewrite实现HTTP和HTTPS重定向跳转

当你的站点使用了HTTPS以后,你可能会想把全部的HTTP请求(即端口80的请求),所有都重定向至HTTPS(即端口443)。这时候你能够用如下的方式来作到:(Apache mod_rewrite)把这段代码放在.htaccess文件,便可实现HTTP到HTTPS的重定向。

 RewriteEngine On
 RewriteBase /
 RewriteCond %{SERVER_PORT} 80
 RewriteRule ^(.*)$ https://blog.shibo.com/$1 [R=301,L]
</IfModule>

而当你又想用回HTTP的时候,反过来就能够了:

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteCond %{SERVER_PORT} 443
 RewriteRule ^(.*)$ https://blog.shibo.com/$1 [R=301,L]
</IfModule>

其中R=301表示Moved Permanently,即告诉搜索引擎或者浏览器下去直接访问后者的地址,若是只是试验性地重定向,可使用R=302(Found),临时跳转

VirtualHost 添加剧定向
须要注意实测以上方法,对于下面需求场景,都无效!!下面项目场景:
1) 在个人根目录下 /var/www/htmp/
2) 配置有多个网站,如士博博客(/var/www/htmp/shibo-blog/)、士博论坛(/var/www/htmp/shibo-forum/)、士博学习(/var/www/htmp/shibo-study/)等
3) 对于士博博客的http请求,所有定向到https博客;对于士博论坛的http请求,所有定向到https论坛;

最后,解决方案是在 VirtualHost 节点里,添加以下配置:

RewriteEngine on
RewriteCond   %{HTTPS} !=on
RewriteRule   ^(.*)  https://%{SERVER_NAME}$1 [L,R]

完整配置参数以下:

# blog
<VirtualHost *:80>
    ServerAdmin yanggang_2050@163.com
    DocumentRoot /var/www/html/wordpress
    ServerName blog.shibo.com
 
    RewriteEngine on
    RewriteCond   %{HTTPS} !=on
    RewriteRule   ^(.*)  https://%{SERVER_NAME}$1 [L,R]
 
    DirectoryIndex index.php
    ErrorLog /var/log/blog.shibo.com-error_log
    CustomLog /var/log/blog.shibo.com-access_log common
</VirtualHost>

3) 示例三

在启用了https以后,还要保证以前的http端口能够打开,http的80端口是有两个网址的,因此这就致使须要把原来的带www和不带www的kevin.com域名同时指定一个https网址上面(https://kevin.com),须要作两个Apache的301重定向,这个实际上是很简单的,最简单的作法是直接在 .htaccess文件中添加两个301便可,以下所示:

rewritecond %{http_host} ^www.kevin.com [nc]  
RewriteRule ^(.*)?$ https://kevin.com/$1 [R=301,L]  
  
RewriteCond %{SERVER_PORT} !^443$  
RewriteRule ^(.*)?$ https://kevin.com/$1 [R=301,L]  

第一个 301 很天然就是带 www 的跳转到新的 https 上面了,而下面的301重定向则是判断若是端口不是80的话,则进行重定向,这样的话,带www和不带www的域名就一块儿跳转到 https 一个网址上面了,固然这种全站作301的方法是比较暴力的,一般状况下咱们只要把主域名作个301就能够了,我这里是由于启用了原来的两个域名。

4) 示例四:一些其它的 Apache http 跳转到 https 的方法

方法1

RewriteEngine On  
RewriteBase /  
RewriteCond %{SERVER_PORT} 80  
RewriteRule ^(.*)$ https://kevin.com/$1 [R=301,L]  

#这样跳转的好处是独立IP主机也支持,访问ip能自动跳转到https

方法2

RewriteEngine on 
RewriteCond %{SERVER_PORT} !^443$ 
RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [R=301,L]

#整站跳转

方法3

RewriteEngine on 
RewriteBase /yourfolder 
RewriteCond %{SERVER_PORT} !^443$ 
#RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [R=301,L] 
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

#以上至针对某个目录跳转, yourfolder就是目录名

方法4

RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} /beijing
RewriteRule ^(.*$) https://test.kevin.com/beijing/ [R,L]

#针对url中的次级path路径,好比上面的beijing,上面配置能够实现:
访问http://test.kevin.com/beijing/....  跳转到 https://test.kevin.com/beijing/.....

方法5

# 强制HTTPS方式访问,对WWW或顶级域名不作跳转。
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.kevin.com/$1 [L,R=301]

#强制HTTPS方式访问,并自动将顶级域名跳转到WWW。
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.kevin.com$ [NC]
RewriteRule ^(.*)$ https://www.kevin.com/$1 [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.kevin.com/$1 [L,R=301]

#强制HTTPS方式访问,并自动将WWW跳转到顶级域名。
RewriteEngine On
RewriteCond %{HTTP_HOST} !^kevin.com$ [NC]
RewriteRule ^(.*)$ https://kevin.com/$1 [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://kevin.com/$1 [L,R=301]

方法6

redirect 301 /你的网页 https://你的主机+网页

#针对某个网页跳转

好比:
redirect 301 /beijing.html https://www.kevin.com/beijing.html

方法7

下面是一个http跳转https的配置
修改根目录.htaccess文件,内容配置以下:

<IfModule mod_rewrite.c>
 Options +FollowSymlinks
 RewriteEngine On

#thinkphp去掉index.php
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

 #http自动跳转到https
 RewriteCond %{SERVER_PORT} !^443$

 #只有匹配对应的域名才会跳转
 RewriteCond %{SERVER_NAME} ^hrsc.cc|www.hrsc.cc$
 RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]

</IfModule>

                          Apache的https证书免费申请和http->https跳转配置                         

免费https证书能够参考 (apache和nginx均可以使用,效果很强悍!):
https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc
https://my.oschina.net/jianhui1980/blog/1612469
http://www.javashuo.com/article/p-knasrepf-cr.html (推荐用这个连接,智能从apache配置中自动完成配置, 不须要指定网站根目录)

配置记录以下 (确保服务器的80和443端口在防火墙里已经提早放行):

===========================================================================================
配置http:
  
[root@test-web-php extra]# cat httpd-vhosts.conf
<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    DocumentRoot "/www/wwwroot/www.kevin.com/web"
    ServerName 0207917c.www.kevin.com
    ServerAlias www.kevin.com
    errorDocument 404 /404.html
    ErrorLog "/www/wwwlogs/www.kevin.com-error_log"
    CustomLog "/www/wwwlogs/www.kevin.com-access_log" combined
      
    #DENY FILES
     <Files ~ (\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)$>
       Order allow,deny
       Deny from all
    </Files>
      
    #PHP
    <FilesMatch \.php$>
            SetHandler "proxy:unix:/tmp/php-cgi-70.sock|fcgi://localhost"
    </FilesMatch>
      
    #PATH
    <Directory "/www/wwwroot/www.kevin.com/web">
        SetOutputFilter DEFLATE
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html index.htm default.php default.html default.htm
    </Directory>
</VirtualHost>
  
===========================================================================================
配置https:
  
[root@test-web-php extra]# cat httpd-ssl.conf
Listen 0.0.0.0:443
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder on
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLPassPhraseDialog  builtin
SSLSessionCache        "shmcb:/www/server/apache/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300
   
<VirtualHost *:443>
    ServerAdmin webmaster@example.com
    DocumentRoot "/www/wwwroot/www.kevin.com/web"
    ServerName  www.kevin.com
    ServerAlias www.kevin.com
    errorDocument 404 /404.html
    SSLEngine on
    SSLCertificateFile "/home/ubuntu/www/ssl/cert.pem"
    SSLCertificateKeyFile "/home/ubuntu/www/ssl/key.pem"
    SSLCertificateChainFile "/home/ubuntu/www/ssl/fullchain.pem"
    ErrorLog "/www/wwwlogs/www.kevin.com-error_log"
    CustomLog "/www/wwwlogs/www.kevin.com-access_log" combined
      
    #DENY FILES
     <Files ~ (\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)$>
       Order allow,deny
       Deny from all
    </Files>
      
    #PHP
    <FilesMatch \.php$>
            SetHandler "proxy:unix:/tmp/php-cgi-70.sock|fcgi://localhost"
    </FilesMatch>
      
    #PATH
    <Directory "/www/wwwroot/www.kevin.com/web">
        SetOutputFilter DEFLATE
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html index.htm default.php default.html default.htm
    </Directory>
</VirtualHost>
  
===========================================================================================
配置http->https强转
  
[root@test-web-php extra]# cat /www/wwwroot/www.kevin.com/web/.htaccess
<IfModule mod_rewrite.c>
    Options +FollowSymlinks -Multiviews
    RewriteEngine on
   
    # RewriteBase /
     RewriteCond %{SERVER_PORT} !^443$
     RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
   
    # if a directory or a file exists, use it directly
    RewriteCond %{REQUEST_FILENAME} !-f
   
    # otherwise forward it to index.php
    RewriteRule . index.php
</IfModule>
# General setting to properly handle LimeSurvey paths
# AcceptPathInfo on
  
===========================================================================================
证书路径:
  
[root@test-web-php extra]# ll /home/ubuntu/www/ssl/
total 12
-rw-r--r-- 1 root root 1903 May 23 00:53 cert.pem
-rw-r--r-- 1 root root 3551 May 23 00:53 fullchain.pem
-rw------- 1 root root 1679 May 23 00:53 key.pem

二. Apache中 RewriteRule跳转规则参数

Apache模块mod_rewrite提供了一个基于正则表达式分析器的重写引擎来实时重写URL请求。它支持每一个完整规则能够拥有不限数量的子规则以及附加条件规则的灵活并且强大的URL操做机制。此URL操做能够依赖于各类测试,好比服务器变量、环境变量、HTTP头、时间标记,甚至各类格式的用于匹配URL组成部分的查找数据库。

mod_rewrite模块能够操做URL的全部部分(包括路径信息部分),在服务器级的(httpd.conf)和目录级的(.htaccess)配置都有效,还能够生成最终请求字符串。此重写操做的结果能够是内部子处理,也能够是外部请求的转向,甚至还能够是内部代理处理。

如下重点介绍下RewriteRule 的规则以及参数说明。RewriteRule指令是重写引擎的根本。此指令能够屡次使用。每一个指令定义一个简单的重写规则。这些规则的定义顺序尤其重要——在运行时,规则是按这个顺序逐一辈子效的

配置格式:
RewriteRule Pattern Substitution [flags]

1) Pattern是一个做用于当前URL的perl兼容的正则表达式
"当前URL"是指该规则生效时刻的URL的值。它可能与被请求的URL大相径庭,由于其余规则可能在此以前已经发生匹配并对它作了改动。

2) Substitution是当原始URL与Pattern相匹配时,用来替代(或替换)的字符串。除了纯文本,还能够包含:
-  对Pattern的反向引用($N)
-  对最后匹配的RewriteCond的反向引用(%N)
-  规则条件测试字符串(%{VARNAME})中的服务器变量
-  映射函数调用(${mapname:key|default})

3) [flags]标记做为RewriteRule指令的第三个参数,是一个包含以逗号分隔的下列标记的列表:

3.1) 'chain|C'(连接下一规则)
此标记使当前规则与下一个规则相连接。它产生这样的效果:
若是一个规则被匹配,则继续处理其后继规则,也就是这个标记不起做用;
若是该规则不被匹配,则其后继规则将被跳过。

好比:
在一个目录级规则中执行一个外部重定向时,你可能须要删除".www"(此处不该该出现".www")。
'cookie|CO=NAME:VAL:domain[:lifetime[:path]]'(设置cookie):在客户端设置一个cookie。cookie的名称是NAME,值是VAL。
domain是该cookie的域,好比'.apache.org',可选的lifetime是cookie的有效期(分钟),可选的path是cookie的路径。

3.2) 'env|E=VAR:VAL'(设置环境变量)
此标记将环境变量VAR的值设为VAL,VAL能够包含可扩展的正则表达式反向引用($N和%N)。此标记能够屡次使用以设置多个变量。
这些变量能够在其后许多状况下被间接引用,一般是在XSSI(<!--#echo var="VAR"-->)或CGI($ENV{'VAR'})中,也能够在后继的
RewriteCond指令的CondPattern参数中经过%{ENV:VAR}引用。使用它能够记住从URL中剥离的信息。

3.3) 'forbidden|F'(强制禁止URL)
强制禁止当前URL,也就是当即反馈一个HTTP响应码403(被禁止的)。使用这个标记,能够连接若干个RewriteConds来有条件地阻塞某些URL。

3.4) 'gone|G'(强制废弃URL)
强制当前URL为已废弃,也就是当即反馈一个HTTP响应码410(已废弃的)。使用这个标记,能够标明页面已经被废弃而不存在了。

3.5) 'handler|H=Content-handler'(强制指定内容处理器)
强自制定目标文件的内容处理器为Content-handler。例如,用来模拟mod_alias模块的ScriptAlias指令,以强制映射文件夹内的全部文件都
由"cgi-script"处理器处理。

3.6) 'last|L'(结尾规则)
当即中止重写操做,并再也不应用其余重写规则。它对应于Perl中的last命令或C语言中的break命令。
这个标记用于阻止当前已被重写的URL被后继规则再次重写。例如,使用它能够重写根路径的URL('/')为实际存在的URL(好比:'/e/www/')。

3.7) 'next|N'(从头再来)
从新执行重写操做(从第一个规则从新开始)。此时再次进行处理的URL已经不是原始的URL了,而是经最后一个重写规则处理过的URL。
它对应于Perl中的next命令或C语言中的continue命令。此标记能够从新开始重写操做(当即回到循环的开头)。可是要当心,不要制造死循环!

3.8) 'nocase|NC'(忽略大小写)
它使Pattern忽略大小写,也就是在Pattern与当前URL匹配时,'A-Z'和'a-z'没有区别。

3.9) 'noescape|NE'(在输出中不对URI进行转义)
此标记阻止mod_rewrite对重写结果应用常规的URI转义规则。 通常状况下,特殊字符('%', '$', ';'等)会被转义为等值的十六进制编码('%25', '%24', '%3B'等)。
此标记能够阻止这样的转义,以容许百分号等符号出如今输出中,好比:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] ,可使'/foo/zed转向到一个安全的请求'/bar?arg=P1=zed'。

3.10) 'nosubreq|NS'(不对内部子请求进行处理)
在当前请求是一个内部子请求时,此标记强制重写引擎跳过该重写规则。好比,在mod_include试图搜索目录默认文件(index.xxx)时,Apache会在内部产生子请求。对于子请求,重写规则不必定有用,并且若是整个规则集都起做用,它甚至可能会引起错误。因此,能够用这个标记来排除某些规则。
使用原则:若是你为URL添加了CGI脚本前缀,以强制它们由CGI脚本处理,但对子请求处理的出错率(或资源开销)很高,在这种状况下,可以使用这个标记。

3.11) 'proxy|P'(强制为代理)
此标记使替换成分被内部地强制做为代理请求发送,并当即中断重写处理,而后把处理移交给mod_proxy模块。
你必须确保此替换串是一个可以被mod_proxy处理的有效URI(好比以http://hostname开头),不然将获得一个代理模块返回的错误。
使用这个标记,能够把某些远程成分映射到本地服务器域名空间,从而加强了ProxyPass指令的功能。
注意:要使用这个功能,必须已经启用了mod_proxy模块。

3.12) 'passthrough|PT'(移交给下一个处理器)
此标记强制重写引擎将内部request_rec结构中的uri字段设置为filename字段的值,这个小小的修改使得RewriteRule指令的输出可以被(从URI转换到文件名的)Alias, ScriptAlias, Redirect等指令进行后续处理。

举一个能说明其含义的例子:
若是要将/abc重写为/def, 而后再使用mod_alias将/def转换为/ghi,能够这样:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi

若是省略了PT标记,虽然将uri=/abc/...重写为filename=/def/...的部分运做正常,可是后续的mod_alias在试图将URI转换到文件名时会遭遇失效。
注意:若是须要混合使用多个将URI转换到文件名的模块时,就必须使用这个标记。此处混合使用mod_alias和mod_rewrite就是个典型的例子。

3.13) 'qsappend|QSA'(追加查询字符串)
此标记强制重写引擎在已有的替换字符串中追加一个查询字符串,而不是简单的替换。若是须要经过重写规则在请求串中增长信息,就可使用这个标记。

3.14) 'redirect|R [=code]'(强制重定向)
若Substitution以http://thishost[:thisport]/(使新的URL成为一个URI)开头,能够强制性执行一个外部重定向。若是没有指定code,则产生一个HTTP响应码302(临时性移动)。若是须要使用在300-400范围内的其余响应代码,只需在此指定便可(或使用下列符号名称之一:temp(默认), permanent, seeother)。使用它能够把规范化的URL反馈给客户端,如将"/~"重写为"/u/",或始终对/u/user加上斜杠,等等。

注意:在使用这个标记时,必须确保该替换字段是一个有效的URL。不然,它会指向一个无效的位置!而且要记住,此标记自己只是对URL加上http://thishost[:thisport]/前缀,重写操做仍然会继续进行。一般,你还会但愿中止重写操做而当即重定向,那么就还须要使用'L'标记。

3.15) 'skip|S=num'(跳事后继规则)
此标记强制重写引擎跳过当前匹配规则以后的num个规则。它能够模拟if-then-else结构:最后一个规则是then从句,而被跳过的skip=N个规则是else从句。注意:它和'chain|C'标记是不一样的!

3.16)'type|T=MIME-type'(强制MIME类型)
强制目标文件的MIME类型为MIME-type,能够用来基于某些特定条件强制设置内容类型。好比,下面的指令可让.php文件在以.phps扩展名调用的状况下由mod_php按照PHP源代码的MIME类型(application/x-httpd-php-source)显示:RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]

===========RewriteRule跳转设置案例===========
下列配置内容都写到.htaccess文件中,且 .htaccess文件放到apache站点根目录下.

1) 若是http://kevin.com/foo/bar不存在,则跳转到http://other.kevin.com/foo/bar  (.htaccess文件放在kevin.com域名的root根目录下)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://other.kevin.com/$1 [R]

2)http://kevin.com/foo/bar的GET请求重定向到http://kevin.com/bar(或是将http://kevin.com/foo/bar.html请求重定向到http://kevin.com/bar.html)。用PHP程序处理POST请求,而不是试图重定向一个帖子(这不太可能奏效)。 (.htaccess文件放在kevin.com域名的root根目录下):

RewriteEngine On
RewriteCond   %{REQUEST_METHOD}   GET
RewriteRule   ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$   /$1   [R,L,NS]
RewriteCond   %{REQUEST_METHOD}   POST
RewriteRule   ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$   /foo/show.php   [L,NS]

3) 用一个PHP程序/foo/show.php.处理对没有扩展名的top-level.html文件和文件的全部请求.实现http://www.kevin.com/bobo跳转到http://www.kevin.com/bobo.html  (.htaccess文件放在www.kevin.com域名的root根目录下):

RewriteRule   ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$   /foo/show.php   [L,NS]

3、Apache Rewrite 规则详解

1) Rewrite规则简介:
Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的(.htaccess)两种方式。若是要想用到rewrite模块,必须先安装或加载rewrite模块。方法有两种一种是编译apache的时候就直接安装rewrite模块,别一种是编译apache时以DSO模式安装apache,而后再利用源码和apxs来安装rewrite模块。

基于服务器级的(httpd.conf)有两种方法:
一种是在httpd.conf的全局下直接利用RewriteEngine on来打开rewrite功能;
另外一种是在局部里利用RewriteEngine on来打开rewrite功能;

下面将会举例说明,须要注意的是,必须在每一个virtualhost里用RewriteEngine on来打开rewrite功能。不然virtualhost里没有RewriteEngine on, 它里面的规则也不会生效。

基于目录级的(.htaccess),要注意一点那就是必须打开此目录的FollowSymLinks属性且在.htaccess里要声明RewriteEngine on。

2) 案例说明:

案例一
下面是在一个虚拟主机里定义的规则。功能是把client请求的主机前缀不是www.kevin.com和192.168.100.29都跳转到主机前缀为http://www.kevin.com,避免当用户在地址栏写入http://kevin.com时不能以会员方式登陆网站。

NameVirtualHost 192.168.100.8:80

ServerAdmin
DocumentRoot "/web/webapp"
ServerName www.kevin.com.cn
ServerName kevin.com.cn
RewriteEngine on 
RewriteCond   %{HTTP_HOST}   !^www.kevin.cn   [NC]   
RewriteCond   %{HTTP_HOST}   !^192.168.10.29   [NC]   
RewriteCond   %{HTTP_HOST}   !^$   
RewriteRule   ^/(.*)   http://www.kevin.cn/  [L]  

以上配置解释:
RewriteEngine on      表示打开rewirte功能
RewriteCond %{HTTP_HOST} !^www.kevin.com [NC]       表示声明Client请求的主机中前缀不是www.kevin.com,[NC]的意思是忽略大小写
RewriteCond %{HTTP_HOST} !^192.168.100.29 [NC]       表示声明Client请求的主机中前缀不是192.168.100.29,[NC]的意思是忽略大小写
RewriteCond %{HTTP_HOST} !^$       表示声明Client请求的主机中前缀不为空
RewriteRule ^/(.*) http://www.kevin.com/ [L]       表示若是Client请求的主机中的前缀符合上述条件,则直接进行跳转到http://www.kevin.com/,[L]意味着当即中止重写操做,并再也不应用其余重写规则。这里的.*是指匹配全部URL中不包含换行字符,()括号的功能是把全部的字符作一个标记,以便于后面的应用。$1就是引用前面里的(.*)字符。

案例二
将输入 test.kevin.com 的域名时跳转到tech.kevin.com

listen 8080
NameVirtualHost 192.168.10.25:8080
ServerAdmin
DocumentRoot  "/usr/local/www/apache22/data1/"
ServerName  tech.kevin.com
RewriteEngine on
RewriteCond   %{HTTP_HOST}   ^test.kevin.com  [NC]
RewriteRule   ^/(.*)   tech.kevin.com  [L]

3) Apache mod_rewrite规则重写的标志一览(上面其实已经介绍了)
3.1)  R[=code](force redirect) 强制外部重定向
强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.若是code不指定,将用缺省的302 HTTP状态码。
3.2)  F(force URL to be forbidden)禁用URL,返回403HTTP状态码。
3.3)  G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。
3.4)  P(force proxy) 强制使用代理转发。
3.5)  L(last rule) 代表当前规则是最后一条规则,中止分析之后规则的重写。
3.6)  N(next round) 从新从第一条规则开始运行重写过程。
3.7)  C(chained with next rule) 与下一条规则关联
若是规则匹配则正常处理,该标志无效,若是不匹配,那么下面全部关联的规则都跳过。
3.8)  T=MIME-type(force MIME type) 强制MIME类型
3.9)  NS (used only if no internal sub-request) 只用于不是内部子请求
3.10)  NC(no case) 不区分大小写
3.11)  QSA(query string append) 追加请求字符串
3.12)  NE(no URI escaping of output) 再也不输出转义特殊字符
例如:

RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]         #能正确的将/foo/zoo转换成/bar?arg=P1=zed

3.13)  PT(pass through to next handler) 传递给下一个处理
例如:

RewriteRule ^/abc(.*) /def$1 [PT]      #将会交给/def规则处理
lias /def /ghi 

3.14)  S=num(skip next rule(s)) 跳过num条规则
3.15)  E=VAR:VAL(set environment variable) 设置环境变量

4) Apache rewrite例子集合
在httpd中将一个域名转发到另外一个域名,新域名为www.kevin.com, 更加简短好记。这时须要将原来的域名kevin.cn, 以及论坛所在地址kevin.com/forums/定向到新的域名,以便用户能够找到,而且使原来的论坛 URL 继续有效而不出现 404 未找到,好比原来的http://www.kevin.com/forums/f60.html, 让它在新的域名下继续有效,点击后转发到http://bbs.kevin.com/f60.html, 这就须要用apache的Mod_rewrite功能来实现。
在.htaccess中添加下面的重定向规则:

RewriteEngine On
# Redirect webhosting-kevin.com/forums to bbs.kevin.com
RewriteCond   %{REQUEST_URI}   ^/forums/
RewriteRule    /forums/(.*)    http://bbs.kevin.com/$1   [R=permanent,L]
# Redirect webhosting-kevin.com to kevin.com
RewriteCond   %{REQUEST_URI}   !^/forums/
RewriteRule   /(.*)   http://www.kevin.com/$1   [R=permanent,L]

5) URL重定向

5.1) 案例一
访问   http://www.kevin.com/xxx.php   重定向跳转到   http://www.kevin.com/xxx/
访问   http://yyy.kevin.com   重定向跳转到   http://www.kevin.com/user.php?username=yyy

RewriteEngine On
RewriteCond   %{HTTP_HOST}   ^www.kevin.com
RewriteCond   %{REQUEST_URI}   !^user\.php$
RewriteCond   %{REQUEST_URI}   \.php$
RewriteRule    (.*)\.php$   http://www.kevin.com/$1/  [R]
RewriteCond   %{HTTP_HOST}   !^www.kevin.com
RewriteRule   ^(.+) %{HTTP_HOST}   [C]
RewriteRule   ^([^\.]+)\.kevin\.com   http://www.kevin.com/user.php?username=$1

5.2) 例子二
/type.php?typeid=*   重定向跳转到   /type*.html
/type.php?typeid=*&page=*    重定向跳转到   /type*page*.html

RewriteRule   ^/type([0-9]+).html$   /type.php?typeid=$1   [PT]
RewriteRule   ^/type([0-9]+)page([0-9]+).html$   /type.php?typeid=$1&page=$2   [PT]

6) 使用Apache的URL Rewrite配置多用户虚拟服务器
要实现这个功能,首先要在DNS服务器上打开域名的泛域名解析(本身作或者找域名服务商作)。
好比,我就把 *.kevin.com和 *.zzz.net所有解析到了个人这台Linux Server上。而后,看一下个人Apache中关于*.kevin.com的虚拟主机的设定。

#*.com,*.kevin.net

ServerAdmin
DocumentRoot  /home/www/www.kevin.com
ServerName dns.kevin.com
ServerAlias dns.kevin.com kevin.com kevin.net *.kevin.com *.kevin.net
CustomLog /var/log/httpd/zzz/access_log.log" common
ErrorLog /var/log/httpd/zzz/error_log.log"
AllowOverride None
Order deny,allow
#AddDefaultCharset GB2312


RewriteEngine on
RewriteCond   %{HTTP_HOST}   ^[^.]+\.zzz\.(com|net)$
RewriteRule   ^(.+) %{HTTP_HOST}$1  [C]
RewriteRule   ^([^.]+)\.zzz\.(com|net)(.*)$   /home/www/www.kevin.com/sylvan$3?un=$1&%{QUERY_STRING}   [L]

在上面这段设置中,把*.kevin.net和*.kevin.com 的Document Root都设定到了/home/www/www.kevin.com,后面都配置了URL Rewrite规则。
RewriteEngine on      #打开URL Rewrite功能
RewriteCond %{HTTP_HOST} ^[^.]+.zzz.(com|net)$     #匹配条件,若是用户输入的URL中主机名是相似 xxxx.kevin.com 或者 xxxx.kevin.net 就执行下面一句
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]    #把用户输入完整的地址(GET方式的参数除外)做为参数传给下一个规则,[C]是Chain串联下一个规则的意思
RewriteRule ^([^.]+)\.zzz\.(com|net)(.*)$ /home/www/www.kevin.com/sylvan$3?un=$1&%{QUERY_STRING} [L]
# 最关键的是这一句,使用证则表达式解析用户输入的URL地址,把主机名中的用户名信息做为名为un的参数传给/home/www/www.kevin.com目录下的脚本,并在后面跟上用户输入的GET方式的传入参数。并指明这是最后一条规则([L]规则)。注意,在这一句中指明的重写后的地址用的是服务器上的绝对路径,这是内部跳转。若是使用http://xxxx这样的URL格式,则被称为外部跳转。使用外部跳转的话,浏览着的浏览器中的URL地址会改变成新的地址,而使用内部跳转则浏览器中的地址不发生改变,看上去更像实际的二级域名虚拟服务器。

这样设置后,重启Apache服务器,测试一下,就大功告成了!

4、分享13个mod_rewrite 应用实例

1) 给子域名加www标记

RewriteCond   %{HTTP_HOST}   ^([a-z.]+)?example\.com$ [NC] 
RewriteCond   %{HTTP_HOST}   !^www\. [NC] 
RewriteRule   .?   http://www.%1example.com%{REQUEST_URI}   [R=301,L] 

这个规则抓取二级域名的%1变量,若是不是以www开始,那么就加www,之前的域名以及{REQUEST_URI}会跟在其后。

2) 去掉域名中的www标记

RewriteCond   %{HTTP_HOST}   !^example\.com$   [NC] 
RewriteRule   .?   http://example.com%{REQUEST_URI}   [R=301,L]

3) 去掉www标记,可是保存子域名

RewriteCond   %{HTTP_HOST}   ^www\.(([a-z0-9_]+\.)?example\.com)$   [NC] 
RewriteRule   .?   http://%1%{REQUEST_URI}   [R=301,L]

这里,当匹配到1%变量之后,子域名才会在%2(内部原子)中抓取到,而咱们须要的正是这个%1变量。

4) 防止图片盗链
一些站长不择手段的将你的图片盗链在他们网站上,耗费你的带宽。你能够加一下代码阻止这种行为。

RewriteCond   %{HTTP_REFERER}   !^$ 
RewriteCond    %{HTTP_REFERER}   !^http://(www\.)?example\.com/   [NC] 
RewriteRule   \.(gif|jpg|png)$   - [F] 

若是{HTTP_REFERER}值不为空,或者不是来自你本身的域名,这个规则用[F]FLAG阻止以gif|jpg|png 结尾的URL 
若是对这种盗链你是坚定鄙视的,你还能够改变图片,让访问盗链网站的用户知道该网站正在盗用你的图片。

RewriteCond   %{HTTP_REFERER}   !^$ 
RewriteCond   %{HTTP_REFERER}   !^http://(www\.)?example\.com/.*$ [NC] 
RewriteRule   \.(gif|jpg|png)$   http://你的图片地址   [R=301,L] 

除了阻止图片盗链连接,以上规则将其盗链的图片所有替换成了你设置的图片。 
你还能够阻止特定域名盗链你的图片:

RewriteCond   %{HTTP_REFERER}   !^http://(www\.)?leech_site\.com/   [NC] 
RewriteRule   \.(gif|jpg|png)$   - [F,L]

这个规则将阻止域名黑名单上全部的图片连接请求。 
固然以上这些规则都是以{HTTP_REFERER}获取域名为基础的,若是你想改用成IP地址,用{REMOTE_ADDR}就能够了。

5) 若是文件不存在重定向到404页面
若是你的主机没有提供404页面重定向服务,那么咱们本身建立。

RewriteCond   %{REQUEST_FILENAME}   !-f 
RewriteCond   %{REQUEST_FILENAME}   !-d 
RewriteRule   .?   /404.php   [L] 

这里-f匹配的是存在的文件名,-d匹配的存在的路径名。这段代码在进行404重定向以前,会判断你的文件名以及路径名是否存在。你还能够在404页面上加一个?url=$1参数:

RewriteRule ^/?(.*)$ /404.php?url=$1 [L]

这样,你的404页面就能够作一些其余的事情,例如默认信心,发一个邮件提醒,加一个搜索,等等。

6) 重命名目录

若是你想在网站上重命名目录,试试这个:

RewriteRule   ^/?old_directory/([a-z/.]+)$   new_directory/$1   [R=301,L]

在规则里我添加了一个“.”(注意不是表明得全部字符,前面有转义符)来匹配文件的后缀名。

7) 将.html后缀名转换成.php

前提是.html文件能继续访问的状况下,更新你的网站连接。 

RewriteRule   ^/?([a-z/]+)\.html$   $1.php   [L]

这不是一个网页重定向,因此访问者是不可见的。让他做为一个永久重定向(可见的),将FLAG修改[R=301,L]。

8) 建立无文件后缀名连接

若是你想使你的PHP网站的连接更加简洁易记-或者隐藏文件的后缀名,试试这个: 

RewriteRule   ^/?([a-z]+)$   $1.php   [L]

若是网站混有PHP以及HTML文件,你能够用RewriteCond先判断该后缀的文件是否存在,而后进行替换

RewriteCond   %{REQUEST_FILENAME}.php   -f 
RewriteRule   ^/?([a-zA-Z0-9]+)$   $1.php   [L] 
RewriteCond   %{REQUEST_FILENAME}.html   -f 
RewriteRule   ^/?([a-zA-Z0-9]+)$   $1.html   [L]

若是文件是以.php为后缀,这条规则将被执行。

9) 检查查询变量里的特定参数

若是在URL里面有一个特殊的参数,你可用RewriteCond鉴别其是否存在

RewriteCond   %{QUERY_STRING}   !uniquekey= 
RewriteRule   ^/?script_that_requires_uniquekey\.php$   other_script.php   [QSA,L]

以上规则将检查{QUERY_STRING}里面的uniquekey参数是否存在,若是{REQUEST_URI}值为script_that_requires_uniquekey,将会定向到新的URL。 

10)删除查询变量

Apache的mod_rewrite模块会自动辨识查询变量,除非你作了如下改动: 

a).分配一个新的查询参数(你能够用[QSA,L]FLAG保存最初的查询变量) 

b).在文件名后面加一个“?”(好比index.php?)。符号“?”不会在浏览器的地址栏里显示。

11) 用新的格式展现当前URI 

若是这就是咱们当前正在运行的URLs:/index.php?id=nnnn。咱们很是但愿将其更改为/nnnn而且让搜索引擎以新格式展示。首先,咱们为了让搜索引擎更新成新的,得将旧的URLs重定向到新的格式,可是,咱们还得保证之前的index.php照样可以运行。

实现以上功能,诀窍就在于在查询变量中加了一个访问者看不到的标记符“marker”。咱们只将查询变量中没有出现“marker”标记的连接进行重定向,而后将原有的连接替换成新的格式,而且经过[QSA]FLAG在已有的参数加一个“marker”标记。如下为实现的方式: 

RewriteCond   %{QUERY_STRING}   !marker 
RewriteCond   %{QUERY_STRING}   id=([-a-zA-Z0-9_+]+) 
RewriteRule   ^/?index\.php$   %1?   [R=301,L] 
RewriteRule   ^/?([-a-zA-Z0-9_+]+)$   index.php?marker&id=$1  [L]

这里,原先的URL:http://www.example.com/index.php?id=nnnn,不包含marker,因此被第一个规则永久重定向到http://www.example.com/nnnn,第二个规则将http://www.example.com/nnnn反定向到http://www.example.com/index.php?marker&id=nnnn,而且加了marker以及id=nnnn两个变量,最后mod_rewrite就开始进行处理过程。

第二次匹配,marker被匹配,因此忽略第一条规则,这里有一个“.”字符会出如今http://www.example.com/index.php?marker&id=nnnn中,因此第二条规则也会被忽略,这样咱们就完成了。

注意,这个解决方案要求Apache的一些扩展功能,因此若是你的网站放于在共享主机中会遇到不少障碍。

12) 保证安全服务启用

Apache能够用两种方法辨别你是否开启了安全服务,分别引用{HTTPS}和{SERVER_PORT}变量: 

RewriteCond   %{REQUEST_URI}   ^secure_page\.php$ 
RewriteCond   %{HTTPS}   !on 
RewriteRule   ^/?(secure_page\.php)$   https://www.kevin.com/$1 [R=301,L]

以上规则测试{REQUEST_URI}值是否等于咱们的安全页代码,而且{HTTPS}不等于on。若是这两个条件同时知足,请求将被重定向到安全服务URI.另外你可用{SERVER_PORT}作一样的测试,443是经常使用的安全服务端口 

RewriteCond    %{REQUEST_URI}    ^secure_page\.php$ 
RewriteCond    %{SERVER_PORT}    !^443$ 
RewriteRule    ^/?(secure_page\.php)$    https://www.kevin.com/$1   [R=301,L]

13) 在特定的页面上强制执行安全服务 

遇到同一个服务器根目录下分别有一个安全服务域名和一个非安全服务域名,因此你就须要用RewriteCond 判断安全服务端口是否占用,而且只将如下列表的页面要求为安全服务: 

RewriteCond    %{SERVER_PORT}    !^443$ 
RewriteRule    ^/?(page1|page2|page3|page4|page5)$    https://www.kevin.com/%1  [R=301,L] 

如下是怎样将没有设置成安全服务的页面返回到80端口:

RewriteCond    %{ SERVER_PORT }   ^443$ 
RewriteRule   !^/?(page6|page7|page8|page9)$   zzz.com%{REQUEST_URI} [R=301,L]

5、因为有些例子是针对特殊路径或特别状况的,如下列出一些例子供参考:

目标 重写设置 说明
规范化URL RewriteRule   ^/~([^/]+)/?(.*)   /u/$1/$2 [R] 将/~user重写为/u/user的形式
  RewriteRule   ^/([uge])/([^/]+)$   /$1/$2/ [R] 将/u/user末尾漏掉的/补上
     
规范化HostName RewriteCond   %{HTTP_HOST}   !^fully\.qualified\.domain\.name   [NC] 域名不合格
  RewriteCond   %{HTTP_HOST}   !^$ 不空
  RewriteCond   %{SERVER_PORT}   !^80$ 不是80端口
  RewriteRule   ^/(.*)   http://fully.qualified.domain.name:%{SERVER_PORT}/$1   [L,R] 重写
  RewriteCond   %{HTTP_HOST}   !^fully\.qualified\.domain\.name   [NC]  
  RewriteCond   %{HTTP_HOST}   !^$  
  RewriteRule   ^/(.*)   http://fully.qualified.domain.name/$1   [L,R]  
     
URL根目录转移 RewriteEngine on  
  RewriteRule   ^/$   /e/www/ [R] 从/移到/e/www/
     
末尾目录补斜线 RewriteEngine on  
(目录范围内) RewriteBase   /~quux/  
  RewriteRule   ^foo$   foo/   [R] /~quux/foo是一个目录,补/
     
  RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteCond   %{REQUEST_FILENAME}   -d 若是请文件名是个目录
  RewriteRule   ^(.+[^/])$   $1/ [R] URL末尾不是斜线时补上
     
Web集群 RewriteEngine on  
  RewriteMap   user-to-host   txt:/path/to/map.user-to-host 用户-服务器映射
  RewriteMap   group-to-host   txt:/path/to/map.group-to-host 组-服务器映射
  RewriteMap   entity-to-host   txt:/path/to/map.entity-to-host 实体-服务器映射
  RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2 用户均衡
  RewriteRule   ^/g/([^/]+)/?(.*)   http://${group-to-host:$1|server0}/g/$1/$2 组均衡
  RewriteRule   ^/e/([^/]+)/?(.*)   http://${entity-to-host:$1|server0}/e/$1/$2 实体均衡
  RewriteRule   ^/([uge])/([^/]+)/?$   /$1/$2/.www/  
  RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\  
     
URL根目录搬迁 RewriteEngine on  
  RewriteRule   ^/~(.+)   http://newserver/~$1   [R,L] 到其它服务器
     
所用户名首字母分 RewriteEngine on  
  RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)   /home/$2/$1/.www$3 内一层括号为$2
     
NCSA imagemap移 RewriteEngine on  
植为mod_imap RewriteRule   ^/cgi-bin/imagemap(.*)   $1   [PT]  
     
多目录查找资源 RewriteEngine on  
  # first try to find it in custom/...  
  RewriteCond   /your/docroot/dir1/%{REQUEST_FILENAME}   -f  
  RewriteRule   ^(.+) /your/docroot/dir1/$1   [L]  
  # second try to find it in pub/...  
  RewriteCond   /your/docroot/dir2/%{REQUEST_FILENAME}   -f  
  RewriteRule   ^(.+)   /your/docroot/dir2/$1   [L]  
  # else go on for other Alias or ScriptAlias directives,  
  RewriteRule   ^(.+)   - [PT]  
     
据URL设置环境变量 RewriteEngine on  
  RewriteRule   ^(.*)/S=([^/]+)/(.*)   $1/$3 [E=STATUS:$2]  
     
虚拟主机 RewriteEngine on  
  RewriteCond   %{HTTP_HOST}   ^www\.[^.]+\.host\.com$ 基于用户名
  RewriteRule   ^(.+)   %{HTTP_HOST}$1   [C]  
  RewriteRule   ^www\.([^.]+)\.host\.com(.*)   /home/$1$2  
     
内外人有别 RewriteEngine on  
  RewriteCond   %{REMOTE_HOST}   !^.+\.ourdomain\.com$ 基于远程主机
  RewriteRule   ^(/~.+)   http://www.somewhere.com/$1   [R,L]  
     
错误重定向 RewriteEngine on  
  RewriteCond   /your/docroot/%{REQUEST_FILENAME}   !-f 不是regular文件
  RewriteRule   ^(.+)   http://webserverB.dom/$1  
     
程序处理特殊协议 RewriteRule   ^xredirect:(.+)   /path/to/nph-xredirect.cgi/$1 \ Xredirect协议
  [T=application/x-httpd-cgi,L]  
     
最近镜像下载 RewriteEngine on  
  RewriteMap   multiplex   txt:/path/to/map.cxan 顶级域名与最近ftp服务器映射
  RewriteRule   ^/CxAN/(.*)   %{REMOTE_HOST}::$1 [C]  
  RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$   ${multiplex:$1|ftp.default.dom}$2   [R,L] 据顶级域名不一样提供不一样的FTP服务器
     
基于时间重写 RewriteEngine on  
  RewriteCond   %{TIME_HOUR}%{TIME_MIN}   >0700  
  RewriteCond   %{TIME_HOUR}%{TIME_MIN}   <1900  
  RewriteRule   ^foo\.html$   foo.day.html 白天为迟早7点间
  RewriteRule   ^foo\.html$   foo.night.html 其他为夜间
     
向前兼容扩展名 RewriteEngine on  
  RewriteBase /~quux/  
  # parse out basename, but remember the fact  
  RewriteRule   ^(.*)\.html$   $1   [C,E=WasHTML:yes]  
  # rewrite to document.phtml if exists  
  RewriteCond   %{REQUEST_FILENAME}.phtml -f 若是存在$1.phtml则重写
  RewriteRule   ^(.*)$   $1.phtml   [S=1]  
  # else reverse the previous basename cutout  
  RewriteCond   %{ENV:WasHTML}   ^yes$ 若是不存在$1.phtml,则保持不变
  RewriteRule   ^(.*)$   $1.html  
     
文件更名(目录级) RewriteEngine on 内部重写
  RewriteBase   /~quux/  
  RewriteRule   ^foo\.html$   bar.html  
     
  RewriteEngine on 重定向由客户端再次提交
  RewriteBase   /~quux/  
  RewriteRule   ^foo\.html$   bar.html   [R]  
     
据浏览器类型重写 RewriteCond   %{HTTP_USER_AGENT}   ^Mozilla/3.*  
  RewriteRule   ^foo\.html$ foo.NS.html   [L]  
  RewriteCond   %HTTP_USER_AGENT}   ^Lynx/.* [OR]  
  RewriteCond   %{HTTP_USER_AGENT}   ^Mozilla/[12].*  
  RewriteRule   ^foo\.html$   foo.20.html [L]  
  RewriteRule   ^foo\.html$   foo.32.html [L]  
     
动态镜像远程资源 RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteRule   ^hotsheet/(.*)$   http://www.tstimpreso.com/hotsheet/$1   [P] 利用了代理模块
     
  RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteRule   ^usa-news\.html$   http://www.quux-corp.com/news/index.html [P]  
     
反向动态镜像 RewriteEngine on  
  RewriteCond   /mirror/of/remotesite/$1   -U  
  RewriteRule   ^http://www\.remotesite\.com/(.*)$   /mirror/of/remotesite/$1  
     
负载均衡 RewriteEngine on 利用代理实现round-robin效果
  RewriteMap   lb   prg:/path/to/lb.pl  
  RewriteRule   ^/(.+)$   ${lb:$1} [P,L]  
     
  #!/path/to/perl  
  $| = 1;  
  $name = "www"; # the hostname base  
  $first = 1; # the first server (not 0 here, because 0 is myself)  
  $last = 5; # the last server in the round-robin  
  $domain = "foo.dom"; # the domainname  
  $cnt = 0;  
  while () {  
  $cnt = (($cnt+1) % ($last+1-$first));  
  $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);  
  print "http://$server/$_";  
  }  
  ##EOF##  
     
静态页面变脚本 RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteRule   ^foo\.html$   foo.cgi   [T=application/x-httpd-cgi]  
     
阻击机器人 RewriteCond   %{HTTP_USER_AGENT}   ^NameOfBadRobot.*  
  RewriteCond   %{REMOTE_ADDR}   ^123\.45\.67\.[8-9]$  
  RewriteRule   ^/~quux/foo/arc/.+   - [F]  
     
阻止盗连你的图片 RewriteCond   %{HTTP_REFERER}   !^$  
  RewriteCond   %{HTTP_REFERER}   !^http://www.quux-corp.de/~quux/.*$   [NC] 本身的链接可不能被阻止
  RewriteRule   .*\.gif$   - [F]  
     
  RewriteCond   %{HTTP_REFERER}   !^$  
  RewriteCond   %{HTTP_REFERER}   !.*/foo-with-gif\.html$  
  RewriteRule   ^inlined-in-foo\.gif$   - [F]  
     
拒绝某些主机访问 RewriteEngine on  
  RewriteMap   hosts-deny   txt:/path/to/hosts.deny  
  RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}   !=NOT-FOUND   [OR]  
  RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}   !=NOT-FOUND  
  RewriteRule   ^/.*   - [F]  
     
用户受权 RewriteCond   %{REMOTE_IDENT}@%{REMOTE_HOST}   !^friend1@client1.quux-corp\.com$  
  RewriteCond   %{REMOTE_IDENT}@%{REMOTE_HOST}   !^friend2@client2.quux-corp\.com$  
  RewriteCond   %{REMOTE_IDENT}@%{REMOTE_HOST}   !^friend3@client3.quux-corp\.com$  
  RewriteRule   ^/~quux/only-for-friends/   - [F]  
     
外部重写程序模板 RewriteEngine on  
  RewriteMap   quux-map   prg:/path/to/map.quux.pl  
  RewriteRule   ^/~quux/(.*)$   /~quux/${quux-map:$1}  
     
  #!/path/to/perl  
  $| = 1;  
  while (<>) {  
  s|^foo/|bar/|;  
  print $_;  
  }  
     
搜索引擎友好 RewriteRule   ^/products$   /content.php  
  RewriteRule   ^/products/([0-9]+)$   /content.php?id=$1  
  RewriteRule   ^/products/([0-9]+),([ad]*),([0-9]{0,3}),([0-9]*),([0-9]*$)   /marso/content.php?id=$1&sort=$2&order=$3&start=$4  

==============================================================================
针对apache的route路由转发设置,注意下面几个配置点

1)修改httpd.conf主配置文件
[root@kevin01 ~]# cat /usr/local/apache/conf/httpd.conf
........
LoadModule rewrite_module modules/mod_rewrite.so        #打开重写转发功能模块

DocumentRoot "/data/www/public"                                     
<Directory "/data/www/public">                                          # apache的站点根目录注意修改
    Options FollowSymLinks MultiViews Includes
    AllowOverride All                                                             #要将默认的None改成All
    Require all granted
</Directory>

DirectoryIndex index.html index.php                                    #网站首页默认读出index.php和index.html

2)配置vhosts虚拟主机
[root@kevin01 ~]# cat /usr/local/apache/conf/extra/kevin.conf 
<VirtualHost *:80>
   ServerName www.kevin-inc.com
   DocumentRoot /data/www/public
   DirectoryIndex index.php index.html

   ErrorLog "/var/log/httpd/www.kevin.com-error_log"
   CustomLog "/var/log/httpd/www.kevin.com-access_log" common

</VirtualHost>

3)配置站点根目录/data/www/public路径下的.htaccess文件
[root@kevin01 ~]# cat /data/www/public/.htaccess 
<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

4)重启apache服务
[root@kevin01 ~]# /usr/local/apache/bin/httpd -t
Syntax OK
[root@kevin01 ~]# /usr/local/apache/bin/httpd -k restart

5)另外要注意apache站点根目录下的权限,必定要修改成apache启动用户的权限
[root@kevin01 ~]# ps -ef|grep apache
root      3631     1  0 Oct14 ?        00:00:27 /usr/local/apache/bin/httpd
daemon   13770  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd
daemon   13775  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd

[root@kevin01 ~]# chown -R daemon.daemon /data/www/public


==================================================
若是apache是http强转为https关系的route路由转发的配置,基本配置注意点以下:

1)配置httpd.conf主配置文件
[root@kevin01 ~]# cat /usr/local/apache/conf/httpd.conf

LoadModule ssl_module modules/mod_ssl.so                        #打开https访问的功能模块

LoadModule rewrite_module modules/mod_rewrite.so            #打开重写跳转功能模块

DocumentRoot "/data/www/public"
<Directory "/data/www/public">
    Options FollowSymLinks MultiViews Includes
    AllowOverride All
    Require all granted
</Directory>

DirectoryIndex index.html index.php

2)配置vhosts虚拟主机
[root@kevin01 ~]# cat /usr/local/apache/conf/extra/kevin.conf 
<VirtualHost *:80>
   ServerName www.kevin.com
   DocumentRoot /data/www/public
   DirectoryIndex index.php index.html

   ErrorLog "/var/log/httpd/www.kevin.com-error_log"
   CustomLog "/var/log/httpd/www.kevin.com-access_log" common

</VirtualHost>

[root@kevin01 ~]# cat /usr/local/apache/conf/extra/httpd-ssl.conf
Listen 443
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder on 
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLPassPhraseDialog  builtin
SSLSessionCache        "shmcb:/usr/local/apache/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300
 
<VirtualHost *:443>
DocumentRoot "/data/www/public"
ServerName www.kevin.com
DirectoryIndex index.php index.html

SSLEngine on
SSLCertificateFile "/usr/local/apache/conf/ssl/ssl.kevin.com.crt"
SSLCertificateKeyFile "/usr/local/apache/conf/ssl/ssl.kevin.com.key"
     ErrorLog "logs/www.kevin.com-https-error_log"
     CustomLog "logs/www.kevin.com-https-access_log" combined
</VirtualHost>

[root@kevin01 ~]# ll /usr/local/apache/conf/ssl/
total 8
-rw-rw-r-- 1 root root 4085 Apr  8  2018 ssl.kevin.com.crt
-rw-rw-r-- 1 root root 1706 Apr  8  2018 ssl.kevin.com.key

3)配置站点根目录/data/www/public路径下的.htaccess文件(包括http强转到https的配置)
[root@kevin01 ~]# cat /data/www/public/.htaccess 
<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On

 RewriteCond %{SERVER_PORT} !^443$
 RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

4)重启apache服务
[root@kevin01 ~]# /usr/local/apache/bin/httpd -t
Syntax OK
[root@kevin01 ~]# /usr/local/apache/bin/httpd -k restart

5)另外要注意apache站点根目录下的权限,必定要修改成apache启动用户的权限
[root@kevin01 ~]# ps -ef|grep apache
root      3631     1  0 Oct14 ?        00:00:27 /usr/local/apache/bin/httpd
daemon   13770  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd
daemon   13775  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd

[root@kevin01 ~]# chown -R daemon.daemon /data/www/public
相关文章
相关标签/搜索