本文档讨论了可用于该RewriteRule
指令的标志,并
提供了详细的说明和示例。
一个RewriteRule
可以由一个或多个标志修改其行为。规则末尾的方括号中包含标志,多个标志之间用逗号分隔。
RewriteRule pattern target [Flag1,Flag2,Flag3]
每个标志(除少数例外)都具有短格式(例如)和
CO
较长形式(例如)cookie
。虽然最常用的是短格式,但建议您熟悉长格式,以便记住每个标志应该做什么。一些标志带有一个或多个参数。标志不区分大小写。
当在同一轮重写处理中执行替换(“-”除外)时,更改与请求关联的元数据的标志(T =,H =,E =)在按目录和htaccess上下文中不起作用。
这里提供了每个可用的标志,以及如何使用它们的示例。
[B]标志指示RewriteRule
在应用转换之前转义非字母数字字符。
在2.4.26及更高版本中,您可以通过列出反向引用来将转义限制为特定字符[B=#?;]
。注意:可以在字符列表中使用空格字符进行转义,但不能是列表中的最后一个字符。
mod_rewrite
必须先对URL进行转义,然后再对它们进行映射,因此在应用反向引用时不会对转义进行转义。使用B标志,反向引用中的非字母数字字符将被转义。例如,考虑以下规则:
RewriteRule "^search/(.*)$" "/search.php?term=$1"
给定搜索词“ x&y / z”,浏览器会将其编码为“ x%20%26%20y%2Fz”,从而发出请求“ search / x%20%26%20y%2Fz”。没有B标志,此重写规则将映射到'search.php?term = x&y / z',这不是有效的URL,因此将被编码为
search.php?term=x%20&y%2Fz=
,这不是预期的。
在同一规则上设置B标志后,参数将在传递到输出URL之前重新编码,从而正确映射到
/search.php?term=x%20%26%20y%2Fz
。
RewriteRule "^search/(.*)$" "/search.php?term=$1" [B,PT]
请注意,您可能还需要将设置AllowEncodedSlashes
为On
使该特定示例生效,因为httpd不允许在URL中使用编码的斜杠,如果看到则返回404。
在代理情况下,如果后端如果显示有未转义的URL可能会损坏,则这种转义尤其必要。
此标志的替代方法是使用a RewriteCond
捕获%{THE_REQUEST},以捕获编码形式的字符串。
[BNP]标志指示RewriteRule
在对%20的后向引用中转义空格字符,而不是'+'。在路径组件而不是查询字符串中使用反向引用时很有用。
该标志在2.4.26及更高版本中可用。
[C]或[chain]标志指示RewriteRule
链接到下一个规则。也就是说,如果规则匹配,则照常进行处理,然后控制移至下一条规则。但是,如果不匹配,则将跳过下一个规则以及链接在一起的任何其他规则。
[CO]或[cookie]标志允许您在特定RewriteRule
匹配项时设置cookie 。该参数包含三个必填字段和四个可选字段。
该标志的完整语法,包括所有属性,如下所示:
[CO=NAME:VALUE:DOMAIN:lifetime:path:secure:httponly]
如果在任何cookie字段中都需要文字':'字符,则可以使用其他语法。要选择使用其他语法,cookie的“名称”前应带有“;” 字符,并且字段分隔符应指定为“;”。
[CO=;NAME;VALUE:MOREVALUE;DOMAIN;lifetime;path;secure;httponly]
您必须声明名称,值和域才能设置Cookie。
www.example.com
,也可以是一个域,例如.example.com
。它必须至少由两个点隔开。也就是说,它可能不仅是.com
或
.net
。cookie安全模型禁止使用这种cookie。您还可以选择设置以下值:
/customers/
或/files/download/
。/
-即整个网站。secure
,true
或1
,则仅允许通过安全(https)连接翻译cookie。HttpOnly
,,true
或
1
,则cookie将HttpOnly
设置标志,这意味着在支持此功能的浏览器中,JavaScript代码无法访问该cookie。考虑以下示例:
RewriteEngine On RewriteRule "^/index\.html" "-" [CO=frontdoor:yes:.example.com:1440:/]
在给出的示例中,规则不重写请求。“-”重写目标告诉mod_rewrite通过不变的方式传递请求。而是将名为“前门”的cookie设置为“是”。该cookie对.example.com
域中的任何主机均有效。它设置为在1440分钟(24小时)内到期,并为所有URI返回。
DPI标志导致重写的URI的PATH_INFO部分被丢弃。
此标志在2.2.12版和更高版本中可用。
在每个目录上下文中,每个RewriteRule
比较的URI 是URI和PATH_INFO的当前值的串联。
当前URI可以是客户端请求的初始URI,也可以是上一轮mod_rewrite处理的结果,也可以是当前一轮mod_rewrite处理中的先前规则的结果。
相反,在每条规则之前附加到URI的PATH_INFO仅反映此轮mod_rewrite处理之前的PATH_INFO的值。结果,如果匹配大部分URI并将其复制到多个RewriteRule
指令中的替换中
,而不必考虑URI的哪些部分来自当前PATH_INFO,则最终URI可能会附加PATH_INFO的多个副本。
在不需要此请求到文件系统的先前映射而导致的PATH_INFO的任何替换上,请使用此标志。该标志永久忘记在此轮mod_rewrite处理开始之前建立的PATH_INFO。在当前一轮的mod_rewrite处理完成之前,不会重新计算PATH_INFO。在这一轮处理中的后续规则将仅看到替换的直接结果,而未附加任何PATH_INFO。
使用[E]或[env]标志,可以设置环境变量的值。请注意,运行规则后可能会设置一些环境变量,从而取消设置的内容。有关环境变量如何工作的更多详细信息,请参见环境变量文档。
此标志的完整语法为:
[E=VAR:VAL] [E=!VAR]
VAL
可能包含已扩展的反向引用($N
或
%N
)。
使用简写形式
[E=VAR]
您可以将环境变量命名VAR
为空值。
表格
[E=!VAR]
允许取消设置先前设置的名为的环境变量
VAR
。
然后可以在各种上下文中使用环境变量,包括CGI程序,其他RewriteRule指令或CustomLog指令。
如果请求的URI是图像文件,则以下示例将名为“ image”的环境变量设置为“ 1”。然后,该环境变量用于从访问日志中排除那些请求。
RewriteRule "\.(png|gif|jpg)$" "-" [E=image:1] CustomLog "logs/access_log" combined env=!image
请注意,使用可获得相同的效果SetEnvIf
。提供此技术仅作为示例,而不作为推荐。
使用[F]标志会使服务器向客户端返回403 Forbidden状态代码。尽管可以使用Deny
伪指令实现相同的行为,但这在分配禁止状态方面具有更大的灵活性。
以下规则将禁止.exe
从服务器下载文件。
RewriteRule "\.exe" "-" [F]
本示例对重写目标使用“-”语法,这意味着未修改请求的URI。如果您要禁止该请求,则没有理由重写为另一个URI。
使用[F]时,隐含一个[L]-即立即返回响应,并且不评估其他规则。
[G]标志强制服务器返回410 Gone状态和响应。这表明资源曾经可用,但不再可用。
与[F]标志一样,在使用[G]标志时,通常会将“-”语法用于重写目标:
RewriteRule "oldproduct" "-" [G,NC]
当使用[G]时,意味着[L]-即立即返回响应,并且不评估其他规则。
强制使用指定的处理程序处理结果请求。例如,一个人可以用它来强制所有没有文件扩展名的文件被php处理程序解析:
RewriteRule "!\." "-" [H=application/x-httpd-php]
上面的正则表达式!\.
--将匹配任何不包含文字.
字符的请求。
这也可以用于根据某些条件强制处理程序。例如,每个服务器上下文中使用的以下代码段允许
通过扩展名
请求.php
文件时显示文件:mod_php
.phps
RewriteRule "^(/source/.+\.php)s$" "$1" [H=application/x-httpd-php-source]
上面的正则表达式^(/source/.+\.php)s$
--将匹配任何/source/
以1或n个字符开头,后跟.phps
字面意义的请求。向后引用$ 1引用正则表达式括号内的已捕获匹配。
[L]标志导致mod_rewrite
停止处理规则集。在大多数情况下,这意味着如果规则匹配,将不再处理其他规则。这对应
last
于Perl中的break
命令或C中的命令。使用此标志指示应立即应用当前规则,而不考虑其他规则。
如果要RewriteRule
在
.htaccess
文件或
<Directory>
分区中使用,则一定要对规则的处理方式有所了解。简化的形式是,一旦处理了规则,重写的请求就会交还给URL解析引擎,以对其进行处理。处理重写的请求时,可能会再次遇到.htaccess
文件或
<Directory>
节,因此规则集可能会从头开始再次运行。最常见的情况是,如果其中一个规则导致重定向(内部或外部)导致请求过程重新开始,则将发生这种情况。
因此,重要的是,如果您RewriteRule
在其中一种上下文中使用指令,则应采取显式步骤来避免规则循环,而不是仅仅依靠[L]标志来终止一系列规则的执行,如下所示。
替代标志[END]不仅可以用于终止当前的重写处理,而且还可以防止在每个目录(htaccess)上下文中发生任何后续的重写处理。这不适用于外部重定向产生的新请求。
此处给出的示例将重写任何请求
index.php
,将原始请求作为查询字符串参数提供给index.php
,但是,RewriteCond
可以确保如果该请求已经针对index.php
,RewriteRule
则将被跳过。
RewriteBase "/" RewriteCond "%{REQUEST_URI}" "!=/index.php" RewriteRule "^(.*)" "/index.php?req=$1" [L,PT]
[N]标志使用规则集的结果作为起点,使规则集从顶部重新开始。使用时要格外小心,因为这可能会导致循环。
例如,如果您希望在请求中重复替换某个字符串或字母,则可以使用[Next]标志。此处显示的示例将在请求中的所有位置将B替换为A,并将继续这样做,直到不再有替换的A。
RewriteRule "(.*)A(.*)" "$1B$2" [N]
你可以认为这是一个while
循环:在这种模式仍然匹配(即,而URI仍然含有
A
),执行这种替换(即更换
A
用B
)。
在2.4.8及更高版本中,此模块在32,000次迭代后返回错误,以防止意外循环。可以通过添加到N标志来指定替代的最大迭代次数。
# Be willing to replace 1 character in each pass of the loop RewriteRule "(.+)[><;]$" "$1" [N=64000] # ... or, give up if after 10 loops RewriteRule "(.+)[><;]$" "$1" [N=10]
使用[NC]标志会导致RewriteRule
以不区分大小写的方式匹配。也就是说,不在乎字母在匹配的URI中是大写还是小写。
在下面的示例中,对图像文件的任何请求都将被代理到您的专用图像服务器。匹配不区分大小写,例如,
.jpg
和.JPG
文件都是可接受的。
RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [P,NC]
默认情况下,特殊字符(例如&
和)
?
将转换为等效的十六进制代码。使用[NE]标志可以防止这种情况的发生。
RewriteRule "^/anchor/(.+)" "/bigpage.html#$1" [NE,R]
上面的示例将重定向/anchor/xyz
到
/bigpage.html#xyz
。省略[NE]将导致#转换为等效的十六进制代码,%23
然后将导致404 Not Found错误情况。
使用[NS]标志可防止在子请求中使用该规则。例如,使用SSI(服务器端包含)包含的页面是一个子请求,您可能希望避免在这些子请求上发生重写。另外,当mod_dir
尝试查找有关可能的目录默认文件(例如index.html
文件)的信息时,这是一个内部子请求,因此您通常希望避免对此类子请求进行重写。如果应用了完整的规则集,则在子请求上,它并不总是有用的,甚至可能导致错误。使用此标志排除有问题的规则。
决定是否使用此规则:如果给URL加上CGI脚本前缀,以迫使它们由CGI脚本处理,则很可能会在子请求上遇到问题(或大量开销)。在这些情况下,请使用此标志。
作为HTML页面的一部分加载的图像,JavaScript文件或CSS文件不是子请求-浏览器将它们作为单独的HTTP请求进行请求。
使用[P]标志会使请求由处理
mod_proxy
,并通过代理请求处理。例如,如果您希望所有图像请求都由后端图像服务器处理,则可以执行以下操作:
RewriteRule "/(.*)\.(jpg|gif|png)$" "http://images.example.com/$1.$2" [P]
[P]标志的使用表示[L]-即,该请求将立即通过代理推送,并且不会考虑任何以下规则。
您必须确保替换字符串是有效的URI(通常以http://
hostname开头),可以由进行处理mod_proxy
。如果没有,您将从代理模块收到错误。使用此标志可实现ProxyPass
指令的更强大实现,以将远程内容映射到本地服务器的名称空间。
构造规则的目标URL时请务必谨慎,要考虑到允许客户端影响服务器将用作代理的URL集对安全性的影响。确保URL的方案和主机名部分是固定的,或者不允许客户端产生不适当的影响。
使用此标志会触发使用mod_proxy
,而不处理持久连接。这意味着如果使用ProxyPass
或
设置代理,则代理的性能会更好。ProxyPassMatch
这是因为此标志触发使用默认工作程序,该默认工作程序不处理连接池/重用。
避免使用此标志,并尽可能使用这些指令。
注意:mod_proxy
必须启用才能使用此标志。
默认情况下,假定RewriteRule中的目标(或替换字符串)为文件路径。使用[PT]标志会导致将其视为URI。也就是说,使用[PT]标志导致的结果RewriteRule
被传递回通过URL映射,使基于位置的映射,如Alias
,Redirect
或ScriptAlias
,例如,可能有机会生效。
例如,如果您有一个
Alias
for / icons并在其中有一个RewriteRule
指向,则应使用[PT]标志以确保对该
Alias
值进行了评估。
Alias "/icons" "/usr/local/apache/icons" RewriteRule "/pics/(.+)\.jpg$" "/icons/$1.gif" [PT]
在这种情况下省略[PT]标志将导致别名被忽略,从而导致返回“找不到文件”错误。
该PT
标志暗示该L
标志:将停止重写以便将请求传递到处理的下一阶段。
请注意,该PT
标志隐含在按目录的上下文中,例如
<Directory>
节或.htaccess
文件中。唯一的规避方法是重写为-
。
当替换URI包含查询字符串时,的默认行为RewriteRule
是丢弃现有查询字符串,并将其替换为新生成的查询字符串。使用[QSA]标志会使查询字符串组合在一起。
请考虑以下规则:
RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]
使用[QSA]标志,对的请求/pages/123?one=two
将映射到/page.php?page=123&one=two
。如果没有[QSA]标志,则相同的请求将被映射到
/page.php?page=123
-也就是说,现有查询字符串将被丢弃。
当请求的URI包含查询字符串,而目标URI不包含查询字符串时,默认行为RewriteRule
是将该查询字符串复制到目标URI。使用[QSD]标志会导致查询字符串被丢弃。
此标志在2.4.0及更高版本中可用。
一起使用[QSD]和[QSA]将导致[QSD]优先。
如果目标URI具有查询字符串,则将遵循默认行为-也就是说,原始查询字符串将被丢弃,并替换为RewriteRule
目标URI中的查询字符串。
默认情况下,替换中的第一个(最左边)问号会分隔查询字符串的路径。使用[QSL]标志指示
RewriteRule
使用最后一个(最右边)问号来拆分两个组件。
当映射到文件名中带有文字问号的文件时,这很有用。如果替换中未使用任何查询字符串,则可以与此标志一起附加问号。
该标志在2.4.19版和更高版本中可用。
使用[R]标志会导致向浏览器发出HTTP重定向。如果指定了完全限定的URL(即包括
http://servername/
),那么将向该位置发出重定向。否则,将使用当前协议,服务器名称和端口号来生成随重定向发送的URL。
可以使用语法[R = 305]指定任何有效的HTTP响应状态代码,如果未指定,则默认使用302状态代码。指定的状态代码不必一定是重定向(3xx)状态代码。但是,如果状态代码在重定向范围(300-399)之外,则替换字符串将被完全删除,并且重写将停止,就像L
使用了一样。
除了响应状态代码外,您还可以使用其符号名称指定重定向状态:(temp
默认)
permanent
,或seeother
。
您几乎总是希望将[R]与[L]结合使用(即,使用[R,L]),因为[R]标志本身http://thishost[:thisport]
位于URI的前面
,但随后将其传递给下一个规则集中的规则,通常会导致“请求中的URI无效”警告。
[S]标志用于跳过您不想运行的规则。跳过标志的语法为[S = N ],其中N表示要跳过的规则数(提供
RewriteRule
匹配项)。可以将其视为goto
重写规则集中的一条语句。在以下示例中,我们只想RewriteRule
在请求的URI与实际文件不对应的情况下运行。
# Is the request for a non-existent file? RewriteCond "%{REQUEST_FILENAME}" "!-f" RewriteCond "%{REQUEST_FILENAME}" "!-d" # If so, skip these two RewriteRules RewriteRule ".?" "-" [S=2] RewriteRule "(.*\.gif)" "images.php?$1" RewriteRule "(.*\.html)" "docs.php?$1"
该技术很有用,因为a RewriteCond
仅适用于
RewriteRule
紧随其后的位置。因此,如果您想RewriteCond
应用到多个RewriteRule
s,则一种可能的技术是取消这些条件并添加RewriteRule
带有[Skip]标志的a。您可以使用它来构造伪if-then-else构造:then子句的最后一条规则变为skip=N
,其中N是else子句中的规则数目:
# Does the file exist? RewriteCond "%{REQUEST_FILENAME}" "!-f" RewriteCond "%{REQUEST_FILENAME}" "!-d" # Create an if-then-else construct by skipping 3 lines if we meant to go to the "else" stanza. RewriteRule ".?" "-" [S=3] # IF the file exists, then: RewriteRule "(.*\.gif)" "images.php?$1" RewriteRule "(.*\.html)" "docs.php?$1" # Skip past the "else" stanza. RewriteRule ".?" "-" [S=1] # ELSE... RewriteRule "(.*)" "404.php?file=$1" # END
这可能是更容易完成使用这种配置<If>
,<ElseIf>
和<Else>
指令来代替。
设置将发送结果响应的MIME类型。这与AddType
指令具有相同的效果。
例如,如果以特殊方式请求,则可以使用以下技术将Perl源代码作为纯文本提供:
# Serve .pl files as plain text RewriteRule "\.pl$" "-" [T=text/plain]
或者,也许,如果您有一台能生成不带文件扩展名的jpeg图像的相机,则可以凭借其文件名来强制使用正确的MIME类型来提供这些图像:
# Files with 'IMG' in the name are jpg images. RewriteRule "IMG" "-" [T=image/jpg]
请注意,这是一个简单的示例,最好<FilesMatch>
改用。在诉诸重写之前,请务必考虑问题的替代解决方案,这总是比替代方案效率低下。
如果在每个目录的上下文中使用,请仅使用-
(破折号)代替整个mod_rewrite处理,否则,由于内部重新处理(包括后续的mod_rewrite处理),使用此标志设置的MIME类型将丢失。 。L
在这种情况下,该标志对于结束当前一轮的mod_rewrite处理很有用
。