• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • mod_rewrite

    描述:提供 rule-based 重写引擎,以便动态 rewrite 请求的 URL
    状态:延期
    模块标识符:rewrite_module
    源文件:mod_rewrite.c

    摘要

    mod_rewrite模块使用基于 PCRE regular-expression 解析器的 rule-based 重写引擎来动态地编写请求的 URL。默认情况下,mod_rewrite maps 指向文件系统路径的 URL。但是,它也可用于将一个 URL 重定向到另一个 URL,或调用内部代理提取。

    mod_rewrite提供了一种灵活而强大的方法,可以使用无限数量的规则来操纵 URL。每个规则可以具有无限数量的附加规则条件,以允许您基于服务器变量,环境变量,HTTP headers 或 time 标记 rewrite URL。

    mod_rewrite在完整的 URL 路径上运行,包括 path-info 部分。可以在httpd.conf.htaccess中调用 rewrite 规则。 rewrite 规则生成的路径可以包含查询 string,也可以导致内部 sub-processing,外部请求重定向或内部代理吞吐量。

    详细的 mod_rewrite 文件中提供了更多详细信息,讨论和示例。

    Logging

    mod_rewrite在trace1trace8 log 级别提供详细的 logging 操作。可以使用LogLevel指令专门为mod_rewrite设置 log level:最多 level debug,不记录任何操作,而trace8表示实际上记录了所有操作。

    对mod_rewrite使用高跟踪 log level 会大大减慢 Apache HTTP Server 的速度!使用高于trace2的 log level 仅用于调试!

    LogLevel alert rewrite:trace3
    

    RewriteLog

    那些熟悉早期版本的mod_rewrite的人无疑会寻找RewriteLogRewriteLogLevel指令。此功能已完全被上面提到的新 per-module logging configuration 取代。

    要获取mod_rewrite-specific log 消息,请通过 grep 管道 log 文件:

    tail -f error_log|fgrep '[rewrite:'

    RewriteBase 指令

    描述:设置 per-directory 重写的基本 URL
    句法:RewriteBase URL-path
    默认:None
    Context:目录,.htaccess
    覆盖:FileInfo
    状态:延期
    模块:mod_rewrite

    RewriteBase指令指定用于替换相对路径的 per-directory(htaccess)重写规则指令的 URL 前缀。

    在 per-directory(htaccess)context 中的替换中使用相对路径时,此指令是必需的,除非以下任何条件是 true:

    • 原始请求和替换位于DocumentRoot之下(而不是通过其他方式可达,例如别号)。
    • 包含重写规则的目录的文件系统路径(以相对替换为后缀)也可用作服务器上的 URL 路径(这种情况很少见)。
    • 在 Apache HTTP Server 2.4.16 及更高版本中,当通过别号或mod_userdir映射请求时,可以省略此伪指令。

    在下面的 example 中,RewriteBase是必要的,以避免重写为 http://example.com/opt/myapp-1.2.3/welcome.html,因为资源不是相对于文档根目录。这种错误配置通常会导致服务器在文档根目录下查找“opt”目录。

    DocumentRoot "/var/www/example.com"
    AliasMatch "^/myapp" "/opt/myapp-1.2.3"
    <Directory "/opt/myapp-1.2.3">
        RewriteEngine On
        RewriteBase "/myapp/"
        RewriteRule "^index.html$"  "welcome.html"
    </Directory>
    

    RewriteCond 指令

    描述:定义重写将发生的条件
    句法:RewriteCond TestString CondPattern[flags]
    Context:server config,virtual host,directory,.htaccess
    覆盖:FileInfo
    状态:延期
    模块:mod_rewrite

    RewriteCond指令定义规则条件。一个或多个RewriteCond可以在重写规则指令之前。然后,仅当 URI 的当前 state 与其 pattern 匹配时才使用以下规则,如果满足这些条件。

    TestString 是一个 string,除了纯文本之外还可以包含以下扩展结构:

    • RewriteRule 反向引用:这些是**$N**(0 <= N <= 9)形式的反向引用。$1 到$9 提供对 pattern 的分组部分(括号中)的访问,该RewriteRule受当前RewriteCond条件集的约束。$0 提供对该 pattern 匹配的整个 string 的访问。
    • RewriteCond 反向引用:这些是**%N**(0 <= N <= 9)形式的反向引用。%1 到%9 提供对 pattern 的分组部分(同样,在括号中)的访问,从当前条件集中的最后一个匹配的RewriteCond开始。%0 提供对该 pattern 匹配的整个 string 的访问。
    • RewriteMap 扩展:这些是**${mapname:key | default}**形式的扩展。有关详细信息,请参阅RewriteMap 的文档。
    • Server-Variables:这些是**%{形式的变量.99}**其中 NAME_OF_VARIABLE 可以是从以下列表中获取的 string:
    HTTP headers:连接和请求:
    HTTP_ACCEPT
    HTTPCOOKIE
    HTTP_FORWARDED
    HTTPHOST
    HTTP_PROXY_CONNECTION
    HTTP_REFERER
    HTTP_USER_AGENT
    AUTH_TYPE
    CONNREMOTE_ADDR
    CONTEXT_PREFIX
    CONTEXT_DOCUMENT_ROOT
    IPV6
    PATH_INFO
    QUERYSTRING
    REMOTE_ADDR
    REMOTEHOST
    REMOTE_IDENT
    REMOTEPORT
    REMOTE_USER
    服务器内部:日期和时间:特价:
    DOCUMENT_ROOT
    SCRIPTGROUP
    SCRIPT_USER
    SERVER_ADDR
    SERVER_ADMIN
    SERVERNAME
    SERVERPORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE
    TIME_YEAR
    TIME_MON
    TIME_DAY
    TIME_HOUR
    TIME_MIN
    TIME_SEC
    TIME_WDAY
    TIME
    APIVERSION
    CONNREMOTE_ADDR
    HTTPS
    IS_SUBREQ
    REMOTE_ADDR
    REQUEST_FILENAME
    REQUESTSCHEME
    REQUEST_URI
    THE_REQUEST

    这些变量都对应于 Apache HTTP Server 的类似命名的 HTTP MIME-headers,C 变量或 Unix 系统的struct tm字段。大多数都记录在这里或手册或 CGI 规范中的其他地方。

    SERVERNAME 和 SERVERPORT 分别取决于UseCanonicalName和UseCanonicalPhysicalPort的值。

    对mod_rewrite特别的那些包括下面的那些。

    • API_VERSION
      这是当前 httpd build 中 Apache httpd 模块 API(服务器和模块之间的内部接口)的 version,如 include/ap_mmn.h 中所定义。模块 API version 对应于 Apache httpd 正在使用的 version(在 Apache httpd 1.3.14 的发布 version 中,例如,它是 19990320:10),但主要是模块作者感兴趣。
    • CONN_REMOTE_ADDR
      从 2.4.8 开始:连接的对等 IP 地址(参见 mod_remoteip 模块)。
    • HTTPS
      如果连接使用 SSL/TLS,则包含文本“on”,否则包含“off”。(无论是否加载了 mod_ssl,都可以安全地使用此变量)。
    • IS_SUBREQ
      如果当前正在处理的请求是 sub-request,则包含文本“true”,否则将包含“false”。 Sub-requests 可能由需要在 order 中解析其他 files 或 URI 以完成其任务的模块生成。
    • REMOTE_ADDR
      remote host 的 IP 地址(请参阅 mod_remoteip 模块)。
    • REQUEST_FILENAME
      如果已由 time REQUEST_FILENAME 处的服务器确定,则引用与请求匹配的文件或脚本的完整本地文件系统路径。否则,例如在虚拟 host context 中使用时,_val与 REQUEST_URI 相同。根据 AcceptPathInfo 的 value,服务器可能只使用了 REQUEST_URI 的一些主要组件来将请求映射到文件。
    • REQUEST_SCHEME
      将包含请求的 scheme(通常为“http”或“https”)。 ServerQ 可以影响此 value。
    • REQUEST_URI
      请求的 URI 的路径 component,例如“/index.html”。这显然排除了查询 string,它可以作为自己的名为 QUERYSTRING 的变量。
    • THE_REQUEST
      浏览器向服务器发送的完整 HTTP 请求 line(e.g.,“GET /index.html HTTP/1.1”)。这不包括浏览器发送的任何其他 headers。与以下大多数其他变量不同,此 value 尚未转义(解码)。

    如果 TestString 具有特殊的 value expr,则 CondPattern 将被视为ap_expr。如果没有给出novary flag,表达式中引用的 HTTP headers 将被添加到 Vary 头。

    您应该注意的其他事项:

    • 变量 SCRIPT_FILENAME 和 REQUEST_FILENAME 包含相同的 value - Apache HTTP Server 的内部request_rec结构的filename字段的 value。第一个 name 是众所周知的 CGI 变量 name,而第二个 name 是 REQUEST_URI 的适当对应物(其中包含request_recuri字段的 value)。

    如果发生替换并且重写继续,则两个变量的 value 将相应地更新。

    如果在 per-server context(i.e.,在请求映射到文件系统之前)中使用,则 SCRIPT_FILENAME 和 REQUEST_FILENAME 不能包含完整的本地文件系统路径,因为在此处理阶段路径未知。在这种情况下,两个变量最初都包含 REQUEST_URI 的 value。在 order 中获取 per-server context 中请求的完整本地文件系统路径,使用 URL-based look-ahead %{LA-U:REQUEST_FILENAME}来确定 REQUEST_FILENAME 的最终 value。

    • %{ENV:variable},其中 variable 可以是任何环境变量,也可用。这是 looked-up 通过内部 Apache httpd 结构和(如果没有找到)来自 Apache httpd 服务器 process 的getenv()
    • %{SSL:variable},其中 variable 是SSL 环境变量的 name,无论是否加载mod_ssl都可以使用,但如果不加载,则总是扩展为空 string。例如:%{SSL:SSL_CIPHER_USEKEYSIZE}可能会扩展为128。即使不设置SSLOptions指令的StdEnvVars选项,这些变量也可用。
    • %{HTTP:header},其中 header 可以是任何 HTTP MIME-header name,始终可用于获取 HTTP 请求中发送的标头的 value。示例:%{HTTP:Proxy-Connection}是 HTTP 标头“Proxy-Connection:”的 value。
      如果在条件中使用 HTTP 标头,则此标头将添加到响应的 Vary 标头中,以防条件评估为请求的 true。如果条件评估为请求的 false,则不会**。正确的缓存需要将 HTTP 标头添加到响应的 Vary 标头。

    必须记住,在'ornext | OR'标志的情况下,条件遵循短路逻辑,因此可能根本不评估某些条件。

    • %\{LA-U:variable}可用于执行内部(URL-based)sub-request 的 look-aheads,以确定变量的最终 value。这可以用于访问重写的变量,这在当前阶段是不可用的,但将在稍后阶段设置。
      例如,要根据 per-server context(httpd.conf文件)中的REMOTE_USER变量 rewrite,必须使用%{LA-U:REMOTE_USER}-此变量由 URL 转换阶段(在此期间mod_rewrite运行)之后的授权阶段设置。

    另一方面,因为mod_rewrite通过 API 的 Fixup 阶段实现了 per-directory context(.htaccess文件),并且因为授权阶段在此阶段之前,所以你可以在 context 中使用%{REMOTE_USER}

    • %{LA-F:variable}可用于执行内部(filename-based)sub-request,以确定变量的最终 value。大多数 time,这与上面的 LA-U 相同。

    CondPattern 是条件 pattern,一个正则表达式,应用于 TestString 的当前实例。在与 CondPattern 匹配之前,首先评估 TestString。

    CondPattern 通常是 perl 兼容的正则表达式,但是还有其他语法可用于对 Teststring 执行其他有用的测试:

    • 无论使用何种 CondPattern,您都可以在 pattern string 前加上'!'字符(感叹号)来否定条件的结果。
    • 您可以执行词典 string 比较:
    • <CondPattern
      按字典顺序排列将 CondPattern 视为普通 string 并将其按字典顺序与 TestString 进行比较。 True 如果 TestString 按字典顺序排在 CondPattern 之前。
    • > CondPattern
      按字典顺序,将 CondPattern 视为普通的 string,并按字典顺序将其与 TestString 进行比较。 True,如果 TestString 按字典顺序跟随 CondPattern。
    • =CondPattern
      Lexicographically equal 将 CondPattern 视为普通的 string 并将其按字典顺序与 TestString 进行比较。 True 如果 TestString 在词典上与 CondPattern 相等(两个 strings 完全相同,则为 character 的字符)。如果 CondPattern 是“”(两个引号),则将 TestString 与空 string 进行比较。
    • <=CondPattern
      按字典顺序小于或等于将 CondPattern 视为普通 string 并将其按字典顺序与 TestString 进行比较。 True 如果 TestString 按字典顺序位于 CondPattern 之前,或者等于 CondPattern(两个 strings 相等,则为字符字符)。
    • >=CondPattern
      按字典顺序大于或等于将 CondPattern 视为普通 string 并将其按字典顺序与 TestString 进行比较。 True 如果 TestString 按字典顺序跟随 CondPattern,或等于 CondPattern(两个 strings 相等,字符为字符)。
    • 您可以执行 integer 比较:
    • -eq
      在数值上等于 TestString 被视为 integer,并在数字上与 CondPattern 进行比较。 True 如果两者在数值上相等。
    • -ge
      在数值上大于或等于 TestString 被视为 integer,并在数字上与 CondPattern 进行比较。 True 如果 TestString 在数值上大于或等于 CondPattern。
    • -gt
      在数值上大于 TestString 被视为 integer,并在数字上与 CondPattern 进行比较。 True 如果 TestString 在数字上大于 CondPattern。
    • -le
      在数值上小于或等于 TestString 被视为 integer,并在数字上与 CondPattern 进行比较。 True 如果 TestString 在数值上小于或等于 CondPattern。使用-L 或-h 变体避免与-l 混淆。
    • -lt
      在数值上小于 TestString 被视为 integer,并在数字上与 CondPattern 进行比较。 True 如果 TestString 在数值上小于 CondPattern。使用-L 或-h 变体避免与-l 混淆。
    • -ne
      在数值上不等于 TestString 被视为 integer,并在数字上与 CondPattern 进行比较。 True 如果两者在数值上不同。这相当于!-eq。
    • 您可以执行各种文件属性测试:
    • -d
      是目录。将 TestString 视为路径名并测试它是否存在,并且是一个目录。
    • -f
      是常规文件。将 TestString 视为路径名并测试它是否存在,并且是常规文件。
    • -F
      是现有文件,通过子请求。检查 TestString 是否是有效文件,可通过该路径的所有服务器的 currently-configured 访问控制进行访问。这使用内部子请求来进行检查,因此请小心使用它-它会影响服务器的 performance!
    • -h
      是符号链接,bash 约定。见-l。
    • -l
      是象征性的联系。将 TestString 视为路径名并测试它是否存在,并且是一个符号链接。如果存在混淆的可能性,例如使用-lt 或-le 测试时,也可以使用-L 或-h 的 bash 约定。
    • -L
      是符号链接,bash 约定。见-l。
    • -s
      是常规文件,大小。将 TestString 视为路径名并测试它是否存在,并且是一个大小大于零的常规文件。
    • -U
      是现有的 URL,通过子请求。检查 TestString 是否是有效的 URL,可通过该路径的所有服务器的 currently-configured 访问控制访问。这使用内部子请求来进行检查,因此请小心使用它-它会影响服务器的 performance!此 flag 仅返回有关访问控制,身份验证和授权等信息。这个 flag 没有 return 有关状态的信息 code 配置的处理程序(静态文件,CGI,代理,etc.)将返回。
    • -x
      具有可执行权限。将 TestString 视为路径名并测试它是否存在,并具有可执行权限。这些权限是根据底层的 OS 确定的。

    例如:

    RewriteCond /var/www/%{REQUEST_URI} !-f
    RewriteRule ^(.+) /other/archive/$1 [R]
    
    • 如果 TestString 具有特殊的 value expr,则 CondPattern 将被视为ap_expr。

    在下面的示例中,-strmatch用于将REFERER与站点主机名进行比较,以阻止不需要的热链接。

    RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
    RewriteRule "^/images" "-" [F]
    

    您还可以通过附加**[206]**作为RewriteCond指令的第三个参数来为 CondPattern 设置特殊标志,其中 flags 是以下任何标志的 comma-separated 列表:

    • 'nocase | NC'(n o c ase)
      这使得测试 case-insensitive -在扩展的 TestString 和 CondPattern 中忽略'A-Z'和'a-z'之间的差异。此 flag 仅对 TestString 和 CondPattern 之间的比较有效。它对文件系统和子请求检查没有影响。
    • 'ornext | OR'(下一个条件)
      使用此选项可将规则条件与本地 OR 组合,而不是隐式 AND。典型示例:
    RewriteCond "%{REMOTE_HOST}"  "^host1"  [OR]
    RewriteCond "%{REMOTE_HOST}"  "^host2"  [OR]
    RewriteCond "%{REMOTE_HOST}"  "^host3"
    RewriteRule ...some special stuff for any of these hosts...
    

    如果没有这个 flag,你必须编写 condition/rule 对三次。

    • 'novary | NV'(n o v ary)
      如果在条件中使用 HTTP 标头,则此 flag 会阻止将此标头添加到响应的 Vary 标头中。
      如果此响应的表示在此标头的 value 上有所不同,则使用此 flag 可能会 break 正确缓存响应。所以只有在很好地理解 Vary 头的含义时才应该使用这个 flag。

    例:

    要根据请求的“User-Agent:”标题 rewrite 网站的主页,您可以使用以下内容:

    RewriteCond  "%{HTTP_USER_AGENT}"  "(iPhone|Blackberry|Android)"
    RewriteRule  "^/$"                 "/homepage.mobile.html"  [L]
    
    RewriteRule  "^/$"                 "/homepage.std.html"     [L]
    

    说明:如果您使用的浏览器将自己标识为移动浏览器(请注意 example 不完整,因为还有许多其他移动平台),将提供主页的移动 version。否则,将提供标准页面。

    RewriteEngine 指令

    描述:启用或禁用运行时重写引擎
    句法:RewriteEngine on\|off
    默认:RewriteEngine off
    Context:server config,virtual host,directory,.htaccess
    覆盖:FileInfo
    状态:延期
    模块:mod_rewrite

    RewriteEngine指令启用或禁用运行时重写引擎。如果设置为off,则该模块根本不进行运行时处理。它甚至不更新SCRIPT_URx环境变量。

    使用此伪指令禁用特定 context 中的规则,而不是注释掉所有重写规则伪指令。

    请注意,虚拟主机不会继承 rewrite 配置。这意味着您需要为要使用 rewrite 规则的每个虚拟 host 指定一个RewriteEngine on指令。

    RewriteMap 指令类型的RewriteMap 指令指令在服务器初始化期间未启动,如果它们是在没有RewriteEngine设置为on的 context 中定义

    RewriteMap 指令

    描述:为 key-lookup 定义映射 function
    句法:RewriteMap MapName MapType:MapSource[MapTypeOptions]
    Context:server config,virtual host
    状态:延期
    模块:mod_rewrite
    兼容性:第 3 个参数 MapTypeOptions 仅在 Apache 2.4.29 及更高版本中可用

    RewriteMap指令定义了一个重写 Map,它可以通过 key 查找在 mapping-functions 到 insert/substitute 字段的规则替换 strings 中使用。此查找的来源可以是各种类型。

    MAPNAME是 map 的 name,将用于通过以下构造之一为重写规则的替换 strings 指定 mapping-function:

    ${.256.257 258}${MapName:LookupKey |默认值}

    当发生这样的构造时,查询 map MapName 并且 key LookupKey 是 looked-up。如果找到 key,则 map-function 构造将被 SubstValue 替换。如果未找到 key,则如果未指定 DefaultValue,则将其替换为 DefaultValue 或空 string。空值的行为就像 key 不存在一样,因此无法区分 empty-valued 键和缺少键。

    对于 example,您可以将RewriteMap定义为:

    RewriteMap examplemap "txt:/path/to/file/map.txt"
    

    然后,您可以在重写规则中使用此 map,如下所示:

    RewriteRule "^/ex/(.*)" "${examplemap:$1}"
    

    MapTypeOptions 参数的含义取决于特定的 MapType。有关详细信息,请参阅使用 RewriteMap。

    可以使用以下 MapType 和 MapSource 组合:

    • 文本
      包含 space-separated key-value 对的纯文本文件,每个 line 一个。(详情...)
    • RND
      从纯文本文件中随机选择一个条目(详情...)
    • DBM
      在包含 name,value 对的 dbm 文件中查找条目。 Hash 使用 httxt2dbm 实用程序以纯文本文件格式构建。(详情...)
    • INT
      RewriteMap 提供的四个可用内部函数之一:toupper,tolower,escape 或 unescape。(详情...)
    • PRG
      调用外部程序或脚本来处理重写。(详情...)
    • dbd 或 fastdbd
      要执行的 SQL SELECT 语句以查找 rewrite 目标。(详情...)

    更多细节和众多例子可以在RewriteMap HowTo找到

    RewriteOptions 指令

    描述:为 rewrite 引擎设置一些特殊选项
    句法:RewriteOptions Options
    Context:server config,virtual host,directory,.htaccess
    覆盖:FileInfo
    状态:延期
    模块:mod_rewrite

    RewriteOptions指令为当前 per-server 或 per-directory configuration 设置了一些特殊选项。 Option string 目前只能是以下之一:

    • Inherit
      这会强制当前 configuration 继承 parent 的 configuration。在 per-virtual-server context 中,这意味着继承了主服务器的 maps,条件和规则。在 per-directory context 中,这意味着继承了 parent 目录的.htaccess configuration 或<Directory>部分的条件和规则。继承的规则实际上被复制到使用该指令的部分。如果与本地规则结合使用,则继承的规则将复制到本地规则之后。该指令的位置-低于或高于当地规则-对此行为没有影响。如果本地规则强制重写停止,则不会处理继承的规则。从 parent 范围继承的规则将在子范围中指定的规则之后应用。
    • InheritBefore
      与上面的 Inherit 类似,但 parent 范围中的规则在子范围中指定的规则之前应用。可在 Apache HTTP Server 2.3.10 及更高版本中使用。
    • InheritDown
      如果启用此选项,则所有子配置都将继承当前 configuration 的 configuration。它等同于在所有子配置中指定 RewriteOptions Inherit。有关如何处理 parent-child 关系的更多详细信息,请参阅继承选项。可在 Apache HTTP Server 2.4.8 及更高版本中使用。
    • InheritDownBefore
      与上面的 InheritDown 类似,但是当前范围的规则在任何子范围中指定的规则之前应用。可在 Apache HTTP Server 2.4.8 及更高版本中使用。
    • IgnoreInherit
      此选项强制当前配置和子配置忽略将从 parent 继承的所有规则,这些规则指定 InheritDown 或 InheritDownBefore。可在 Apache HTTP Server 2.4.8 及更高版本中使用。
    • AllowNoSlash
      默认情况下,mod_rewrite 将忽略 map 到磁盘上的目录但缺少尾部斜杠的 URL,期望 mod_dir 模块将发出 client,并重定向到带有斜杠的规范 URL。当 DirectorySlash 指令设置为 off 时,可以启用 AllowNoSlash 选项以确保不再忽略 rewrite 规则。如果需要,此选项可以在.htaccess files 中应用 rewrite 规则_ 匹配目录而不使用尾部斜杠。可在 Apache HTTP Server 2.4.0 及更高版本中使用。
    • AllowAnyURI
      当在具有 version 2.2.22 或更高版本的 httpd 的 VirtualHost 或 server context 中使用 RewriteRule 时,如果请求 URI 是 URL-path,则 mod_rewrite 将仅处理 rewrite 规则。这避免了一些安全问题,其中特定规则可能允许“令人惊讶的”pattern 扩展(参见 CVE-2011-3368 和 CVE-2011-4317)。要解除对匹配 URL-path 的限制,可以启用 AllowAnyURI 选项,并且 mod_rewrite 会将规则集应用于任何请求 URI string,无论该 string 是否与 HTTP 规范所需的 URL-path 语法匹配。可在 Apache HTTP Server 2.4.3 及更高版本中使用。安全警告如果与未仔细编写的 rewrite 规则一起使用,启用此选项将使服务器容易受到安全问题的影响。强烈建议不要使用此选项。特别是,请注意包含“@”字符的输入 strings,它可以根据上述 CVE 名称更改已转换 URI 的解释。
    • MergeBase
      使用此选项,RewriteBase 的 value 将从显式定义的位置复制到任何未定义自己的 RewriteBase 的 sub-directory 或 sub-location 中。这是 2.4.0 到 2.4.3 中的默认行为,恢复它的 flag 可用 Apache HTTP Server 2.4.4 及更高版本。
    • IgnoreContextInfo当在目录(htaccess)context 中进行相对替换并且尚未设置 RewriteBase 时,此模块使用一些扩展的 URL 和文件系统 context 信息将相对替换更改回 URL。诸如 mod_userdir 和 mod_alias 之类的模块提供了这个扩展的 context 信息。可在 2.4.16 及更高版本中使用。
    • LegacyPrefixDocRoot
      在 2.4.26 之前,如果替换是与当前虚拟 host 匹配的绝对 URL,则 URL 可能首先缩减为 URL-path,然后再缩减为本地路径。由于 URL 可以缩减为本地路径,因此路径应该以文档根为前缀。这可以防止在使用以下 RewriteRule 对 http://host/file/myfile 发出请求时访问/tmp/myfile 等文件。 RewriteRule /file/(.*)http://localhost/tmp/$1 此选项允许在文档根不以 URL 为基础的本地路径作为前缀的情况下使用旧行为。可在 2.4.26 及更高版本中使用。

    RewriteRule 指令

    描述:定义重写引擎的规则
    句法:RewriteRule Pattern Substitution[flags]
    Context:server config,virtual host,directory,.htaccess
    覆盖:FileInfo
    状态:延期
    模块:mod_rewrite

    RewriteRule指令是真正的重写主力。该指令可以多次出现,每个实例定义一个 rewrite 规则。定义这些规则的 order 很重要-这是在 run-time 中应用它们的 order。

    图案是兼容的 perl 正则表达式。此 pattern 与之比较的内容取决于RewriteRule指令的定义位置。

    匹配什么?

    • 在虚拟主机 context 中,Pattern 最初将匹配主机名和 port 之后以及查询 string(e.g.“/app1/index.html”)之前的 URL 部分。这是(%-decoded)URL-path。
    • 在 per-directory context(目录和.htaccess)中,Pattern 仅与部分路径匹配,例如,“/app1/index.html”的请求可能导致与“app1/index.html”或“index.html”进行比较,具体取决于RewriteRule的定义位置。

    定义规则的目录路径在比较之前从当前映射的文件系统路径中剥离(直到并包括尾部斜杠)。此 per-directory 前缀剥离的最终结果是此 context 中的规则仅匹配定义规则的“下方”当前映射文件系统路径部分。

    诸如DocumentRoot和别号之类的指令,或者甚至是之前RewriteRule替换的结果,确定当前映射的文件系统路径。

    • 如果要对主机名,port 或查询 string 进行匹配,请分别使用RewriteCond和%{HTTP_HOST}%{SERVER_PORT}%{QUERY_STRING}变量。

    Per-directory 重写

    • rewrite 引擎可以在.htaccess files 和<Directory>部分中使用,但有一些额外的复杂性。
    • 要在此 context 中启用 rewrite 引擎,您需要设置“RewriteEngine On并且必须启用Options FollowSymLinks”。如果管理员已禁用用户目录的FollowSymLinks覆盖,则无法使用 rewrite 引擎。出于安全原因,需要此限制。
    • 有关将哪些前缀添加回相对替换的更多信息,请参阅RewriteBase指令。
    • 如果您希望_对 per-directory(htaccess)RewriteRule 中的完整 URL-path 匹配,请在RewriteCond中使用%{REQUEST_URI}变量。
    • 删除的前缀始终_end 以斜杠表示,匹配发生在从不具有前导斜杠的 string 上。因此,带有^/的 Pattern 在 per-directory context 中永远不会匹配。
    • 尽管在<Location>和<Files>部分(包括它们的正则表达式对应部分)在语法上允许 rewrite 规则,但这应该永远不是必需的并且不受支持。在这些情境中,break 的一个可能的特征是相对替换。
    • 如果块遵循目录 context 的规则。
    • 默认情况下,当合并部分属于同一 context 时,mod_rewrite 会覆盖规则。对于使用 Inherit 设置的 example,RewriteOptions指令可以更改此行为。
    • RewriteOptions还规定了在 configuration 的相同嵌套 level 中声明的节的行为。在下面的示例中,默认情况下仅考虑第二个如果块中声明的 RewriteRules,因为第一个被重写。使用RewriteOptions Inherit 强制 mod_rewrite 来合并这两个部分并考虑两组 statements,而不是仅考虑最后一个。
    <If "true">
      # Without RewriteOptions Inherit, this rule is overridden by the next
      # section and no redirect will happen for URIs containing 'foo'
      RewriteRule foo http://example.com/foo [R]
    </If>
    <If "true">
      RewriteRule bar http://example.com/bar [R]
    </If>
    

    有关常用表达的一些提示,请参阅mod_rewrite 简介。

    在mod_rewrite中,NOT 字符('!')也可用作可能的 pattern 前缀。这使你可以否定一个 pattern;例如:```如果当前 URL 确实NOT匹配此 pattern''。这可以用于特殊情况,更容易匹配负 pattern,或作为最后一个默认规则。

    注意

    使用 NOT 字符否定 pattern 时,不能在该 pattern 中包含分组通配符部分。这是因为,当 pattern 不 match(即,否定匹配)时,组没有内容。因此,如果使用了否定模式,则不能在替换 string 中使用$N

    rewrite 规则的代换是 string,它替换了 Pattern 匹配的原始 URL-path。替换可能是:

    • file-system 路径
      指定要传递给 client 的资源的 file-system 上的位置。当在 server(virtualhost)context 中配置规则并且替换中的路径的第一个 component 存在于 file-system 中时,替换仅被视为 file-system 路径
    • URL-path
      要提供的资源的 DocumentRoot-relative 路径。注意 mod_rewrite 试图通过检查路径的第一段是否存在于 file-system 的根目录来猜测是否指定了 file-system 路径或 URL-path。对于 example,如果指定/www/file.html 的 Substitution string,那么这将被视为 URL-path,除非在根目录中存在名为 www 的目录或 file-system(或者,如果在.htaccess 文件中使用重写,则相对于您的文档 root),在这种情况下,它将被视为 file-system 路径。如果您希望将其他 URL-mapping 指令(例如 Alias)应用于生成的 URL-path,请使用[372] flag,如下所述。
    • 绝对网址
      如果指定了绝对 URL,mod_rewrite 将检查主机名是否与当前 host 匹配。如果是,则删除 scheme 和 hostname,并将生成的路径视为 URL-path。否则,将对给定的 URL 执行外部重定向。要强制外部重定向回到当前 host,请参阅下面的[373] flag。
    • -(破折号)
      短划线表示不应执行替换(现有路径未经过触摸传递)。当需要在不改变路径的情况下应用 flag(见下文)时使用。

    除了纯文本,Substitution string 还可以包含

    • back-references($N)到 RewriteRule pattern
    • back-references(%N)到最后一个匹配的 RewriteCond pattern
    • server-variables 在规则条件 test-strings(%{VARNAME})中
    • mapping-function calls(${mapname:key|default})

    Back-references 是$N(N=0..9)形式的标识符,它将被匹配的 Pattern 的N th group 的内容替换。 server-variables 与RewriteCond指令的 TestString 相同。 mapping-functions 来自RewriteMap 指令指令并在那里解释。这三种类型的变量在上面的 order 中展开。

    Rewrite 规则应用于先前 rewrite 规则的结果,在 order 中,在配置文件中定义它们。 URL-path 或 file-system 路径(参见上面的“匹配什么?”)被替换完全替换并且重写 process 继续直到所有规则都已应用,或者由L flag或其他 flag 显式终止,这意味着立即终止,例如ENDF

    修改 Query String

    默认情况下,查询 string 将保持不变。但是,您可以在包含查询 string 部分的替换 string 中创建 URL。只需在 substitution string 中使用问号,即表明以下文本应该 re-injected 到查询 string 中。如果要删除现有查询 string,请仅使用问号结束替换 string。要组合新旧查询 strings,请使用[QSA] flag。

    另外,您可以通过附加**[395]**作为RewriteRule指令的第三个参数来设置要执行的特殊行动。标志是 comma-separated 列表,由方括号括起来,代表以下 table 中的任何标志。中提供了每个 flag 的更多详细信息和示例。

    Flag 和语法功能
    在应用转换之前,在后向引用中转义 non-alphanumeric 个字符。细节...
    backrefnoplus| BNP如果反向引用被转义,则应将空格转义为%20 而不是。当反向引用将用于路径 component 而不是查询 string 时很有用。细节...
    链\C规则遵循以下规则。如果规则失败,将跳过链接到它的 rule(s)。细节...
    COOKIE| CO=NAME:VAL在 client 浏览器中设置 cookie。完整语法是:CO=NAME:VAL:domain[:lifetime[:path[:secure[405]]]]细节...
    discardpath| DPI导致重写的 URI 的 PATH_INFO 部分被丢弃。细节...
    结束立即停止重写 process 并且不再应用任何规则。还可以防止在 per-directory 和.htaccess context 中进一步执行 rewrite 规则。(2.3.9 及以后可用)细节...
    env| E =[412] VAR[413]导致设置环境变量 VAR(如果提供,则为 value VAL)。表单!VAR 导致环境变量 VAR 未设置。细节...
    禁止\F返回对 client 浏览器的 403 FORBIDDEN 响应。细节...
    走了\G返回对 client 浏览器的 410 GONE 响应。细节...
    处理器\H=Content-handler导致生成的 URI 被发送到指定的 Content-handler 进行处理。细节...
    最后\L立即停止重写 process 并且不再应用任何规则。特别注意 per-directory 和.htaccess context 的注意事项(另请参阅 END flag)。细节...
    下一\NRe-run 重写 process,再次使用第一个规则,使用规则集的结果作为起点。细节...
    NOCASE| NC使 pattern 比较 case-insensitive。细节...
    noescape| NE防止 mod_rewrite 在 rewrite 的结果中应用 hexcode 转义特殊字符。细节...
    nosubreq| NS如果当前请求是内部 sub-request,则跳过规则。细节...
    代理\P强制将替换 URL 作为代理请求在内部发送。细节...
    直通\PT强制将生成的 URI 传递回 URL 映射引擎,以处理其他 URI-to-filename 转换器,例如AliasRedirect。细节...
    qsappend| QSA将原始请求 URL 中的任何查询 string 追加到 rewrite 目标中创建的任何查询 string。细节...
    qsdiscard| QSD丢弃附加到传入 URI 的任何查询 string。细节...
    qslast| QSL将最后一个(right-most)问号解释为查询 string 分隔符,而不是通常使用的第一个(left-most)。可在 2.4.19 及更高版本中使用。细节...
    重定向\R[444]强制外部重定向,可选择使用指定的 HTTP 状态 code。细节...
    跳\S=num如果当前规则匹配,则告知重写引擎跳过下一个 num 规则。细节...
    键入\T=MIME-type强制目标文件的MIME-type为指定类型。细节...

    主目录扩展

    当替换 string 以类似“/~user”的 string 开头(通过显式文本或反向引用)时,mod_rewrite执行主目录扩展,而与mod_userdir的存在或 configuration 无关。

    在重写规则指令上使用 PT flag 时不会发生此扩展。

    以下是所有可能的替代组合及其含义:

    在 per-server configuration(httpd.conf)里面请求``GET /somepath/pathinfo'':

    给定规则结果换人
    ^/somepath(.*)otherpath$1无效,不受支持
    ^/somepath(.*)otherpath$1[459]无效,不受支持
    ^/somepath(.*)otherpath$1[460]无效,不受支持
    ^/somepath(.*)/otherpath$1/otherpath/pathinfo
    ^/somepath(.*)/otherpath$1[461]http://thishost/otherpath/pathinfo 通过外部重定向
    ^/somepath(.*)/otherpath$1[462]没有意义,不支持
    ^/somepath(.*)http://thishost/otherpath$1/otherpath/pathinfo
    ^/somepath(.*)http://thishost/otherpath$1[463]http://thishost/otherpath/pathinfo 通过外部重定向
    ^/somepath(.*)http://thishost/otherpath$1[464]没有意义,不支持
    ^/somepath(.*)http://otherhost/otherpath$1http://otherhost/otherpath/pathinfo 通过外部重定向
    ^/somepath(.*)http://otherhost/otherpath$1[465]http://otherhost/otherpath/pathinfo 通过外部重定向([466] flag 是多余的)
    ^/somepath(.*)http://otherhost/otherpath$1[467]http://otherhost/otherpath/pathinfo 通过内部代理

    /somepath 配置/somepath(/physical/path/to/somepath/.htaccess,带有 RewriteBase“/somepath”)请求``GET /somepath/localpath/pathinfo'':

    给定规则结果换人
    ^ localpath(.*)otherpath$1/somepath/otherpath/pathinfo
    ^ localpath(.*)otherpath$1[468]http://thishost/somepath/otherpath/pathinfo 通过外部重定向
    ^ localpath(.*)otherpath$1[469]没有意义,不支持
    ^ localpath(.*)/otherpath$1/otherpath/pathinfo
    ^ localpath(.*)/otherpath$1[470]http://thishost/otherpath/pathinfo 通过外部重定向
    ^ localpath(.*)/otherpath$1[471]没有意义,不支持
    ^ localpath(.*)http://thishost/otherpath$1/otherpath/pathinfo
    ^ localpath(.*)http://thishost/otherpath$1[472]http://thishost/otherpath/pathinfo 通过外部重定向
    ^ localpath(.*)http://thishost/otherpath$1[473]没有意义,不支持
    ^ localpath(.*)http://otherhost/otherpath$1http://otherhost/otherpath/pathinfo 通过外部重定向
    ^ localpath(.*)http://otherhost/otherpath$1[474]http://otherhost/otherpath/pathinfo 通过外部重定向([475] flag 是多余的)
    ^ localpath(.*)http://otherhost/otherpath$1[476]http://otherhost/otherpath/pathinfo 通过内部代理

    上篇:mod_request

    下篇:mod_sed