mod_rewrite语法顺序
mod_rewrite具有一些影响处理的特定排序规则。在完成任何操作之前,RewriteEngine On
需要先给出指令,因为这会打开mod_rewrite处理。这应该在任何其他重写指令之前。
RewriteCond
前面RewriteRule
的条件使ONE规则受条件限制。后续的任何RewriteRules都将被视为没有条件的处理。
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
在这种简单情况下,如果HTTP引荐来源网址是来自serverfault.com,则将博客请求重定向到特殊的serverfault页面(我们就是这么特殊)。但是,如果上面的块有额外的RewriteRule行:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg $/blog/$1.sf.jpg
所有.jpg文件都将转到特殊的serverfault页面,而不仅仅是带有引荐来源网址的文件。显然,这不是这些规则的编写方式。可以使用多个RewriteCond规则来完成:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
但是可能应该使用一些更棘手的替换语法来完成。
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
更复杂的RewriteRule包含要处理的条件。最后一个括号,(html|jpg)
告诉RewriteRule匹配html
或jpg
,并在重写的字符串中将匹配的字符串表示为$ 2。从逻辑上讲,这与上一个块相同,只有两个RewriteCond / RewriteRule对,它只在两行而不是四行上执行。
多个RewriteCond行是隐式AND的,可以显式OR。要处理来自ServerFault和超级用户的引荐来源网址(显式OR):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [OR]
RewriteCond %{HTTP_REFERER} ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
要使用Chrome浏览器(隐含AND)投放ServerFault引用的页面,请执行以下操作:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteBase
也是特定于订单的,因为它指定以下RewriteRule
指令如何处理它们。在.htaccess文件中,它非常有用。如果使用,它应该是.htaccess文件中“ RewriteEngine on”下的第一个指令。举个例子:
RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
这告诉mod_rewrite当前正在处理的此特定URL是通过http://example.com/blog/而不是物理目录路径(/ home / $ Username / public_html / blog)到达的,并相应地对其进行了处理。因此,用户RewriteRule
认为它的字符串开始位于URL中的“ / blog”之后。这是用两种不同的方式写的同一件事。一个带有RewriteBase,另一个没有:
RewriteEngine On
##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg) $1.sf.$2
##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
如您所见,RewriteBase
允许重写规则利用网站内容而不是Web 服务器的路径,这可以使编辑这些文件的人更容易理解它们。而且,它们可以使指令更短,从而具有美学吸引力。
RewriteRule匹配语法
RewriteRule本身具有用于匹配字符串的复杂语法。我将在另一部分介绍标志(诸如[PT]之类的东西)。因为系统管理员通过示例进行学习比通过阅读手册页进行学习的频率更高,所以我将给出示例并解释其工作方式。
RewriteRule ^/blog/(.*)$ /newblog/$1
该.*
构造匹配.
零或多次(*
)的任何单个字符()。将其括在圆括号中告诉它提供与$ 1变量匹配的字符串。
RewriteRule ^/blog/.*/(.*)$ /newblog/$1
在这种情况下,第一个。*不会括在括号中,因此不会提供给重写的字符串。此规则将删除新博客站点上的目录级别。(/blog/2009/sample.html变为/newblog/sample.html)。
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$2
在这种情况下,第一个括号表达式将设置一个匹配组。这将变成$ 1,这是不需要的,因此不会在重写的字符串中使用。
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$1/$2
在这种情况下,我们在重写的字符串中使用$ 1。
RewriteRule ^/blog/(20[0-9][0-9])/(.*)$ /newblog/$1/$2
该规则使用特殊的括号语法指定字符范围。[0-9]匹配数字0到9。此特定规则将处理2000年到2099年之间的年份。
RewriteRule ^/blog/(20[0-9]{2})/(.*)$ /newblog/$1/$2
这和以前的规则具有相同的作用,但是{2}部分告诉它两次匹配先前的字符(在这种情况下为方括号表达式)。
RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html /newblog/$1/$2.shtml
这种情况下将匹配第二个匹配表达式中的任何小写字母,并尽可能匹配所有字符。该\.
结构告诉它来治疗期间作为实际的时期,而不是特殊字符是在前面的例子。但是,如果文件名中包含破折号,它将中断。
RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html /newblog/$1/$2.shtml
这会在其中包含破折号的文件名被捕获。但是,正如方-
括号表达式中的特殊字符一样,它必须是表达式中的第一个字符。
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
此版本使用文件名中的字母,数字或-
字符来捕获任何文件名。这是您在方括号表达式中指定多个字符集的方式。
RewriteRule标志
重写规则上的标志具有许多特殊含义和用例。
RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html /newblog/$1/$2.shtml [L]
该标志[L]
在上述表达式的末尾。可以使用多个标志,以逗号分隔。链接的文档描述了每个文档,但是无论如何它们都在这里:
L =最后。一旦匹配,则停止处理RewriteRules。订单数!
C =链。继续处理下一个RewriteRule。如果此规则不匹配,则不会执行下一个规则。稍后再详细介绍。
E =设置环境变量。Apache具有各种可能影响Web服务器行为的环境变量。
F =禁止。如果此规则匹配,则返回403-Forbidden错误。
G =消失。如果此规则匹配,则返回410-Gone错误。
H =处理程序。强制将请求视为指定的MIME类型进行处理。
N =下一步。强制规则重新开始并重新匹配。小心!可能会导致循环。
NC =无情况。允许jpg
匹配jpg和JPG。
NE =无法逃脱。防止将特殊字符(。?#&等)重写为等效的十六进制代码。
NS =没有子请求。如果您使用的是服务器端包含文件,则将阻止与包含文件的匹配。
P =代理。强制该规则由mod_proxy处理。透明地从其他服务器提供内容,因为您的网络服务器会获取并重新提供内容。这是一个危险的标志,因为写得不好的标志会将您的Web服务器变成开放式代理,那就不好了。
PT =直通。在RewriteRule匹配中考虑Alias语句。
QSA = QSAppend。当原始字符串包含查询(http://example.com/thing?asp=foo)将原始查询字符串附加到重写后的字符串中。通常,它将被丢弃。对于动态内容很重要。
R =重定向。提供HTTP重定向到指定的URL。也可以提供确切的重定向代码[R = 303]。与极为相似RedirectMatch
,后者速度更快,应尽可能使用。
S =跳过。跳过此规则。
T =类型。指定返回内容的MIME类型。与AddType
指令非常相似。
您知道我怎么说RewriteCond
仅适用于一条规则吗?好吧,您可以通过链接解决该问题。
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html [C]
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
因为第一个RewriteRule具有Chain标志,所以第二个rewrite-rule将在第一个rewriteRule匹配时执行,即与前一个RewriteCond规则匹配时执行。如果Apache正则表达式使您的大脑受伤,该功能非常方便。但是,从优化的角度来看,我在第一部分中指出的“一站式”方法更快。
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
可以通过标志使它更简单:
RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html /newblog/$1/$2.shtml [NC]
另外,某些标志也适用于RewriteCond。值得注意的是,NoCase。
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [NC]
将匹配“ ServerFault.com”