• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • RewriteRule指令的标志

    介绍

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

    RewriteRule pattern target [Flag1,Flag2,Flag3]
    

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

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

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

    B(转义反向引用)

    [B]标志指示RewriteRule在应用转换之前转义非字母数字字符。

    在2.4.26及更高版本中,您可以通过列出反向引用来将转义限制为特定字符[B=#?;]。注意:可以在字符列表中使用空格字符进行转义,但不能是列表中的最后一个字符。

    mod_rewrite必须先对网址进行转义,然后再对它们进行映射,因此在应用反向引用时不会对转义进行转义。使用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/
    默认情况下,此设置为/-即整个网站。
    安全
    如果设置为secure,,true1,则仅允许通过安全(https)连接翻译cookie。
    httponly
    如果设置为HttpOnly,,true1,则cookie将HttpOnly设置标志,这意味着在支持此功能的浏览器中,JavaScript代码无法访问该cookie。

    考虑以下示例:

    RewriteEngine On
    RewriteRule "^/index\" "-" [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]标志。此处显示的示例将在请求中的每个位置将A替换为B,并将继续这样做,直到不再有替换的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脚本前缀,以迫使URL由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"
    

    这项技术很有用,因为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处理很有用。