<-
Apache HTTP 服务器 2.4 > RewriteRule标志

RewriteRule标志

本文档讨论了可用于该RewriteRule指令的标志,并 提供了详细的说明和示例。

支持Apache!

也可以看看

最佳

介绍

一个RewriteRule可以由一个或多个标志修改其行为。规则末尾的方括号中包含标志,多个标志之间用逗号分隔。

RewriteRule pattern target [Flag1,Flag2,Flag3]

每个标志(除少数例外)都具有短格式(例如)和 CO较长形式(例如)cookie。虽然最常用的是短格式,但建议您熟悉长格式,以便记住每个标志应该做什么。一些标志带有一个或多个参数。标志不区分大小写。

当在同一轮重写处理中执行替换(“-”除外)时,更改与请求关联的元数据的标志(T =,H =,E =)在按目录和htaccess上下文中不起作用。

这里提供了每个可用的标志,以及如何使用它们的示例。

最佳

B(转义反向引用)

[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]

请注意,您可能还需要将设置AllowEncodedSlashesOn使该特定示例生效,因为httpd不允许在URL中使用编码的斜杠,如果看到则返回404。

在代理情况下,如果后端如果显示有未转义的URL可能会损坏,则这种转义尤其必要。

此标志的替代方法是使用a RewriteCond捕获%{THE_REQUEST},以捕获编码形式的字符串。

最佳

BNP | backrefnoplus(不要将空格转义为+)

[BNP]标志指示RewriteRule在对%20的后向引用中转义空格字符,而不是'+'。在路径组件而不是查询字符串中使用反向引用时很有用。

该标志在2.4.26及更高版本中可用。

最佳

C |链

[C]或[chain]标志指示RewriteRule链接到下一个规则。也就是说,如果规则匹配,则照常进行处理,然后控制移至下一条规则。但是,如果不匹配,则将跳过下一个规则以及链接在一起的任何其他规则。

最佳

CO | cookie

[CO]或[cookie]标志允许您在特定RewriteRule 匹配项时设置cookie 。该参数包含三个必填字段和四个可选字段。

该标志的完整语法,包括所有属性,如下所示:

[CO=NAME:VALUE:DOMAIN:lifetime:path:secure:httponly]

如果在任何cookie字段中都需要文字':'字符,则可以使用其他语法。要选择使用其他语法,cookie的“名称”前应带有“;” 字符,并且字段分隔符应指定为“;”。

[CO=;NAME;VALUE:MOREVALUE;DOMAIN;lifetime;path;secure;httponly]

您必须声明名称,值和域才能设置Cookie。

您希望Cookie有效的域。这可以是一个主机名,例如www.example.com,也可以是一个域,例如.example.com。它必须至少由两个点隔开。也就是说,它可能不仅是.com.net。cookie安全模型禁止使用这种cookie。

您还可以选择设置以下值:

一生
Cookie将持续的时间(以分钟为单位)。
值为0表示cookie仅在当前浏览器会话中持久存在。如果未指定,则为默认值。
路径
Cookie在当前网站上有效的路径,例如/customers//files/download/
默认情况下,此设置为/-即整个网站。
安全
如果设置为securetrue1,则仅允许通过安全(https)连接翻译cookie。
httponly
如果设置为HttpOnly,,true1,则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 |丢弃路径

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]或[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。提供此技术仅作为示例,而不作为推荐。

最佳

结束

使用[END]标志不仅终止当前的重写处理(如[L]),而且还可以防止在每个目录(htaccess)上下文中发生任何后续的重写处理。

这不适用于外部重定向产生的新请求。

最佳

F |禁止

使用[F]标志会使服务器向客户端返回403 Forbidden状态代码。尽管可以使用Deny伪指令实现相同的行为,但这在分配禁止状态方面具有更大的灵活性。

以下规则将禁止.exe从服务器下载文件。

RewriteRule "\.exe" "-" [F]

本示例对重写目标使用“-”语法,这意味着未修改请求的URI。如果您要禁止该请求,则没有理由重写为另一个URI。

使用[F]时,隐含一个[L]-即立即返回响应,并且不评估其他规则。

最佳

G |消失

[G]标志强制服务器返回410 Gone状态和响应。这表明资源曾经可用,但不再可用。

与[F]标志一样,在使用[G]标志时,通常会将“-”语法用于重写目标:

RewriteRule "oldproduct" "-" [G,NC]

当使用[G]时,意味着[L]-即立即返回响应,并且不评估其他规则。

最佳

H |处理程序

强制使用指定的处理程序处理结果请求。例如,一个人可以用它来强制所有没有文件扩展名的文件被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 | last

[L]标志导致mod_rewrite停止处理规则集。在大多数情况下,这意味着如果规则匹配,将不再处理其他规则。这对应 last于Perl中的break命令或C中的命令。使用此标志指示应立即应用当前规则,而不考虑其他规则。

如果要RewriteRule.htaccess文件或 <Directory>分区中使用,则一定要对规则的处理方式有所了解。简化的形式是,一旦处理了规则,重写的请求就会交还给URL解析引擎,以对其进行处理。处理重写的请求时,可能会再次遇到.htaccess文件或 <Directory>节,因此规则集可能会从头开始再次运行。最常见的情况是,如果其中一个规则导致重定向(内部或外部)导致请求过程重新开始,则将发生这种情况。

因此,重要的是,如果您RewriteRule在其中一种上下文中使用指令,则应采取显式步骤来避免规则循环,而不是仅仅依靠[L]标志来终止一系列规则的执行,如下所示。

替代标志[END]不仅可以用于终止当前的重写处理,而且还可以防止在每个目录(htaccess)上下文中发生任何后续的重写处理。这不适用于外部重定向产生的新请求。

此处给出的示例将重写任何请求 index.php,将原始请求作为查询字符串参数提供给index.php,但是,RewriteCond可以确保如果该请求已经针对index.phpRewriteRule则将被跳过。

RewriteBase "/"
RewriteCond "%{REQUEST_URI}" "!=/index.php"
RewriteRule "^(.*)" "/index.php?req=$1" [L,PT]
最佳

N |下一个

[N]标志使用规则集的结果作为起点,使规则集从顶部重新开始。使用时要格外小心,因为这可能会导致循环。

例如,如果您希望在请求中重复替换某个字符串或字母,则可以使用[Next]标志。此处显示的示例将在请求中的所有位置将B替换为A,并将继续这样做,直到不再有替换的A。

RewriteRule "(.*)A(.*)" "$1B$2" [N]

你可以认为这是一个while循环:在这种模式仍然匹配(即,而URI仍然含有 A),执行这种替换(即更换 AB)。

在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 |无案

使用[NC]标志会导致RewriteRule以不区分大小写的方式匹配。也就是说,不在乎字母在匹配的URI中是大写还是小写。

在下面的示例中,对图像文件的任何请求都将被代理到您的专用图像服务器。匹配不区分大小写,例如, .jpg.JPG文件都是可接受的。

RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [P,NC]
最佳

NE | noescape

默认情况下,特殊字符(例如&和) ?将转换为等效的十六进制代码。使用[NE]标志可以防止这种情况的发生。

RewriteRule "^/anchor/(.+)" "/bigpage.html#$1" [NE,R]

上面的示例将重定向/anchor/xyz/bigpage.html#xyz。省略[NE]将导致#转换为等效的十六进制代码,%23然后将导致404 Not Found错误情况。

最佳

NS | nosubreq

使用[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必须启用才能使用此标志。

最佳

PT |直通

默认情况下,假定RewriteRule中的目标(或替换字符串)为文件路径。使用[PT]标志会导致将其视为URI。也就是说,使用[PT]标志导致的结果RewriteRule被传递回通过URL映射,使基于位置的映射,如AliasRedirectScriptAlias,例如,可能有机会生效。

例如,如果您有一个 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文件中。唯一的规避方法是重写为-

最佳

QSA | qsappend

当替换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-也就是说,现有查询字符串将被丢弃。

最佳

QSD | qsdiscard

当请求的URI包含查询字符串,而目标URI不包含查询字符串时,默认行为RewriteRule是将该查询字符串复制到目标URI。使用[QSD]标志会导致查询字符串被丢弃。

此标志在2.4.0及更高版本中可用。

一起使用[QSD]和[QSA]将导致[QSD]优先。

如果目标URI具有查询字符串,则将遵循默认行为-也就是说,原始查询字符串将被丢弃,并替换为RewriteRule目标URI中的查询字符串。

最佳

QSL | qslast

默认情况下,替换中的第一个(最左边)问号会分隔查询字符串的路径。使用[QSL]标志指示 RewriteRule使用最后一个(最右边)问号来拆分两个组件。

当映射到文件名中带有文字问号的文件时,这很有用。如果替换中未使用任何查询字符串,则可以与此标志一起附加问号。

该标志在2.4.19版和更高版本中可用。

最佳

R |重定向

使用[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]标志用于跳过您不想运行的规则。跳过标志的语法为[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应用到多个RewriteRules,则一种可能的技术是取消这些条件并添加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>指令来代替。

最佳

T |类型

设置将发送结果响应的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处理很有用 。

可用语言: zh  |  fr 

最佳

注释

注意:
这不是“问答”部分。此处放置的评论应指向有关改进文档或服务器的建议,如果实施或被认为无效/偏离主题,我们的主持人可以将其删除。有关如何管理Apache HTTP Server的问题,应直接指向我们的IRC频道#httpd(位于Freenode上),或发送至我们的邮件列表
目前,此页面已禁用评论。