<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </IfModule>
RewriteCond的 %{REQUEST_FILENAME} !-d 的意思是访问的路径不是一个目录时RewriteRule才能生效php
RewriteCond的 %{REQUEST_FILENAME} !-f 的意思是访问的路径不是一个文件时RewriteRule才能生效html
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 的意思是将访问路径重写到index.php/的后面,最为参数传递给index.php文件mysql
Apache中 RewriteRule 规则参数介绍 linux
摘要: Apache模块 mod_rewrite 提供了一个基于正则表达式分析器的重写引擎来实时重写URL请求。它支持每一个完整规则能够拥有不限数量的子规则以及附加条件规则的灵活并且强大的URL操做机制。这里着重介绍 RewriteRule 规则以及参数说明。web
Apache模块 mod_rewrite 提供了一个基于正则表达式分析器的重写引擎来实时重写URL请求。它支持每一个完整规则能够拥有不限数量的子规则以及附加条件规则的灵活并且强大的URL操做机制。此URL操做能够依赖于各类测试,好比服务器变量、环境变量、HTTP头、时间标记,甚至各类格式的用于匹配URL组成部分的查找数据库。正则表达式
此模块能够操做URL的全部部分(包括路径信息部分),在服务器级的(httpd.conf)和目录级的(.htaccess)配置都有效,还能够生成最终请求字符串。此重写操做的结果能够是内部子处理,也能够是外部请求的转向,甚至还能够是内部代理处理。sql
这里着重介绍一下 RewriteRule 的规则以及参数说明。RewriteRule指令是重写引擎的根本。此指令能够屡次使用。每一个指令定义一个简单的重写规则。这些规则的定义顺序尤其重要——在运行时,规则是按这个顺序逐一辈子效的。数据库
Pattern是一个做用于当前URL的perl兼容的正则表达式。"当前URL"是指该规则生效时刻的URL的值。它可能与被请求的URL大相径庭,由于其余规则可能在此以前已经发生匹配并对它作了改动。apache
Substitution是当原始URL与Pattern相匹配时,用来替代(或替换)的字符串。除了纯文本,还能够包含:
对Pattern的反向引用($N)
对最后匹配的RewriteCond的反向引用(%N)
规则条件测试字符串(%{VARNAME})中的服务器变量
映射函数调用(${mapname:key|default})api
[flags]标记做为RewriteRule指令的第三个参数,是一个包含以逗号分隔的下列标记的列表:
'chain|C'(连接下一规则)
此标记使当前规则与下一个规则相连接。它产生这样的效果:若是一个规则被匹配,则继续处理其后继规则,也就是这个标记不起做用;若是该规则不被匹配,则其后继规则将被跳过。好比,在一个目录级规则中执行一个外部重定向时,你可能须要删除".www"(此处不该该出现".www")。
'cookie|CO=NAME:VAL:domain[:lifetime[:path]]'(设置cookie)
在客户端设置一个cookie。cookie的名称是NAME,值是VAL。domain是该cookie的域,好比'.apache.org',可选的lifetime是cookie的有效期(分钟),可选的path是cookie的路径。
'env|E=VAR:VAL'(设置环境变量)
此标记将环境变量VAR的值为VAL,VAL能够包含可扩展的正则表达式反向引用($N和%N)。此标记能够屡次使用以设置多个变量。这些变量能够在其后许多状况下被间接引用,一般是在XSSI(<!--#echo var="VAR"-->)或CGI($ENV{'VAR'})中,也能够在后继的RewriteCond指令的CondPattern参数中经过%{ENV:VAR}引用。使用它能够记住从URL中剥离的信息。
'forbidden|F'(强制禁止URL)
强制禁止当前URL,也就是当即反馈一个HTTP响应码403(被禁止的)。使用这个标记,能够连接若干个RewriteConds来有条件地阻塞某些URL。
'gone|G'(强制废弃URL)
强制当前URL为已废弃,也就是当即反馈一个HTTP响应码410(已废弃的)。使用这个标记,能够标明页面已经被废弃而不存在了。
'handler|H=Content-handler'(强制指定内容处理器)
强自制定目标文件的内容处理器为Content-handler。例如,用来模拟mod_alias模块的ScriptAlias指令,以强制映射文件夹内的全部文件都由"cgi-script"处理器处理。
'last|L'(结尾规则)
当即中止重写操做,并再也不应用其余重写规则。它对应于Perl中的last命令或C语言中的break命令。这个标记用于阻止当前已被重写的URL被后继规则再次重写。例如,使用它能够重写根路径的URL('/')为实际存在的URL(好比:'/e/www/')。
'next|N'(从头再来)
从新执行重写操做(从第一个规则从新开始)。此时再次进行处理的URL已经不是原始的URL了,而是经最后一个重写规则处理过的URL。它对应于Perl中的next命令或c语言中的continue命令。此标记能够从新开始重写操做(当即回到循环的开头)。可是要当心,不要制造死循环!
'nocase|NC'(忽略大小写)
它使Pattern忽略大小写,也就是在Pattern与当前URL匹配时,'A-Z'和'a-z'没有区别。
'noescape|NE'(在输出中不对URI进行转义)
此标记阻止mod_rewrite对重写结果应用常规的URI转义规则。 通常状况下,特殊字符('%', '$', ';'等)会被转义为等值的十六进制编码('%25', '%24', '%3B'等)。此标记能够阻止这样的转义,以容许百分号等符号出如今输出中,好比:
可使'/foo/zed转向到一个安全的请求'/bar?arg=P1=zed'。
'nosubreq|NS'(不对内部子请求进行处理)
在当前请求是一个内部子请求时,此标记强制重写引擎跳过该重写规则。好比,在mod_include试图搜索目录默认文件(index.xxx)时,Apache会在内部产生子请求。对于子请求,重写规则不必定有用,并且若是整个规则集都起做用,它甚至可能会引起错误。因此,能够用这个标记来排除某些规则。
使用原则:若是你为URL添加了CGI脚本前缀,以强制它们由CGI脚本处理,但对子请求处理的出错率(或者资源开销)很高,在这种状况下,可使用这个标记。
'proxy|P'(强制为代理)
此标记使替换成分被内部地强制做为代理请求发送,并当即中断重写处理,而后把处理移交给mod_proxy模块。你必须确保此替换串是一个可以被mod_proxy处理的有效URI(好比以http://hostname开头),不然将获得一个代理模块返回的错误。使用这个标记,能够把某些远程成分映射到本地服务器域名空间,从而加强了ProxyPass指令的功能。
注意:要使用这个功能,必须已经启用了mod_proxy模块。
'passthrough|PT'(移交给下一个处理器)
此标记强制重写引擎将内部request_rec结构中的uri字段设置为filename字段的值,这个小小的修改使得RewriteRule指令的输出可以被(从URI转换到文件名的)Alias, ScriptAlias, Redirect等指令进行后续处理[原文:This flag is just a hack to enable post-processing of the output of RewriteRule directives, using Alias, ScriptAlias, Redirect, and other directives from various URI-to-filename translators.]。举一个能说明其含义的例子: 若是要将/abc重写为/def, 而后再使用mod_alias将/def转换为/ghi,能够这样:
若是省略了PT标记,虽然将uri=/abc/...重写为filename=/def/...的部分运做正常,可是后续的mod_alias在试图将URI转换到文件名时会遭遇失效。
注意:若是须要混合使用多个将URI转换到文件名的模块时,就必须使用这个标记。。此处混合使用mod_alias和mod_rewrite就是个典型的例子。
'qsappend|QSA'(追加查询字符串)
此标记强制重写引擎在已有的替换字符串中追加一个查询字符串,而不是简单的替换。若是须要经过重写规则在请求串中增长信息,就可使用这个标记。
'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'标记。
'skip|S=num'(跳事后继规则)
此标记强制重写引擎跳过当前匹配规则以后的num个规则。它能够模拟if-then-else结构:最后一个规则是then从句,而被跳过的skip=N个规则是else从句。注意:它和'chain|C'标记是不一样的!
'type|T=MIME-type'(强制MIME类型)
强制目标文件的MIME类型为MIME-type,能够用来基于某些特定条件强制设置内容类型。好比,下面的指令可让.PHP文件在以.phps扩展名调用的状况下由mod_php按照php源代码的MIME类型(application/x-httpd-php-source)显示:
RewriteRule example
1.If http://example.com/foo/bar
does not exist, redirect to http://other.example.com/foo/bar
. (Put this in an .htaccess file in your top-level web directory.)
2. Handle all requests for top-level .html
files and files with no extensions (http://example.com/foo
,http://example.com/foo.html
) with a single PHP program /foo/show.php
. Also, ignore trailing characters in set { : ; , .
} so URLs like "http://example.com/foo.
" can be copied-n-pasted from plain text sentences by inattentive users.
Examples:
3. Redirect GET requests for http://example.com/foo/bar
to http://example.com/bar
(and /foo/bar.html
to /bar.html
). Handle POST requests with PHP program rather than attempting to redirect a POST (which is unlikely to work well).
Examples:
Apache Rewrite 规则详解
一、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。
二、举例说明:
下面是在一个虚拟主机里定义的规则。功能是把client请求的主机前缀不是www.updateweb.cn和203.81.23.202都跳转到主机前缀为http://www.updateweb.cn,避免当用户在地址栏写入http://updateweb.cn时不能以会员方式登陆网站。
例二.将输入 folio.test.com 的域名时跳转到profile.test.com
3.Apache mod_rewrite规则重写的标志一览
1) R[=code](force redirect) 强制外部重定向
强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.若是code不指定,将用缺省的302 HTTP状态码。
2) F(force URL to be forbidden)禁用URL,返回403HTTP状态码。
3) G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。
4) P(force proxy) 强制使用代理转发。
5) L(last rule) 代表当前规则是最后一条规则,中止分析之后规则的重写。
6) N(next round) 从新从第一条规则开始运行重写过程。
7) C(chained with next rule) 与下一条规则关联
若是规则匹配则正常处理,该标志无效,若是不匹配,那么下面全部关联的规则都跳过。
8) T=MIME-type(force MIME type) 强制MIME类型
9) NS (used only if no internal sub-request) 只用于不是内部子请求
10) NC(no case) 不区分大小写
11) QSA(query string append) 追加请求字符串
12) NE(no URI escaping of output) 不在输出转义特殊字符
例如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 将能正确的将/foo/zoo转换成/bar?arg=P1=zed
13) PT(pass through to next handler) 传递给下一个处理
例如:
RewriteRule ^/abc(.*) /def$1 [PT] # 将会交给/def规则处理
Alias /def /ghi
14) S=num(skip next rule(s)) 跳过num条规则
15) E=VAR:VAL(set environment variable) 设置环境变量
4.Apache rewrite例子集合
在 httpd 中将一个域名转发到另外一个域名虚拟主机世界近期更换了域名,新域名为 www.updateweb.cn, 更加简短好记。这时须要将原来的域名updateweb.cn, 以及论坛所在地址 updateweb.cn/forums/定向到新的域名,以便用户能够找到,而且使原来的论坛 URL 继续有效而不出现 404 未找到,好比原来的http://www.updateweb.cn/forums/-f60.html, 让它在新的域名下继续有效,点击后转发到http://bbs.updateweb.cn/-f60.html, 这就须要用 apache 的 Mod_rewrite 功能来实现。
在中添加下面的重定向规则:
添加了上面的规则之后, 里的所有内容以下:
URL重定向
例子一:
1.http://www.zzz.com/xxx.php-> http://www.taobaoxs.com/xxx/
2.http://yyy.zzz.com-> http://www.taobaoxs.com/user.php?username=yyy 的功能
例子二:
/type.php?typeid=* --> /type*.html
/type.php?typeid=*&page=* --> /type*page*.html
5.使用Apache的URL Rewrite配置多用户虚拟服务器
要实现这个功能,首先要在DNS服务器上打开域名的泛域名解析(本身作或者找域名服务商作)。好比,我就把 *.semcase.com和 *.semcase.cn所有解析到了个人这台Linux Server上。
而后,看一下个人Apache中关于*.semcase.com的虚拟主机的设定。
在这段设定中,我把*.semcase.NET和*.semcase.com 的Document Root都设定到了 /home/www/www.taobaoxs.com
可是,继续看下去,看到...配置了吗?在这里我就配置了URL Rewrite规则。
RewriteEngine on #打开URL Rewrite功能
RewriteCond %{HTTP_HOST} ^[^.]+.osall.(com|net)$ #匹配条件,若是用户输入的URL中主机名是相似 xxxx.semcase.com 或者 xxxx.semcase.cn 就执行下面一句
RewriteRule ^(.+) %{HTTP_HOST}$1 [C] #把用户输入完整的地址(GET方式的参数除外)做为参数传给下一个规则,[C]是Chain串联下一个规则的意思
RewriteRule ^([^.]+).osall.(com|net)(.*)$ /home/www/dev.semcase.com/sylvan$3?un=$1&%{QUERY_STRING} [L]
# 最关键的是这一句,使用证则表达式解析用户输入的URL地址,把主机名中的用户名信息做为名为un的参数传给/home/www/dev.semcase.com目录下的脚本,并在后面跟上用户输入的GET方式的传入参数。并指明这是最后一条规则([L]规则)。注意,在这一句中指明的重写后的地址用的是服务器上的绝对路径,这是内部跳转。若是使用http://xxxx这样的URL格式,则被称为外部跳转。使用外部跳转的话,浏览着的浏览器中的URL地址会改变成新的地址,而使用内部跳转则浏览器中的地址不发生改变,看上去更像实际的二级域名虚拟服务器。
这样设置后,重启Apache服务器,测试一下,就大功告成了!
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)$ 你的图片地址 [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.taobaoxs.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.taobaoxs.com/$1 [R=301,L]
13.在特定的页面上强制执行安全服务
遇到同一个服务器根目录下分别有一个安全服务域名和一个非安全服务域名,因此你就须要用RewriteCond 判断安全服务端口是否占用,而且只将如下列表的页面要求为安全服务:
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/?(page1|page2|page3|page4|page5)$ https://www.taobaoxs.com/%1 [R=301,L]
如下是怎样将没有设置成安全服务的页面返回到80端口:
RewriteCond %{ SERVER_PORT } ^443$
RewriteRule !^/?(page6|page7|page8|page9)$ taobaoxs.com%{REQUEST_URI} [R=301,L]