Apache:详解QSA,PT,L,E参数的作用

本文介绍了Apache服务器中mod_rewrite模块的使用方法,重点讲解了[QSA]、[PT]、[L]、[END]及[E]等标志的作用与应用场景,并通过实例演示如何进行URL重写。

 [QSA]


当被替换的URI包含有query string的时候,apache的默认行为是,丢弃原有的query string 并直接使用新产生的query string,如果加上了[QSA]选项,那么旧的query string 将会与新产生的query string组合起来,产生一个新的query string 

Demo:

RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]

当访问:/pages/123?one=two 

会重写成: /page.php?page=123&one=two

如果不用[QSA]

会重写成:/page.php?page=123

[PT]


RewriteRule中的目标串(被替换完的路径)都会被看做是文件路径,使用[PT]选项能够让apache将其看作是URI来对待。这也就是说,使用了[PT]选项,能够使得RewriteRule的结果重新加入到URL的匹配当中去,让那些基于本地匹配的,例如Alias, Redirect, or ScriptAlias,能够有生效的机会。

Demo:

Alias "/icons" "/usr/local/apache/icons"

RewriteRule "/pics/(.+)\.jpg$" "/icons/$1.gif" [PT]

如果你有一个Alias/icons,并且有一个RewriteRule,那么你需要使用[PT]选项来确保Alias会被计算到

如果漏了[PT]选项,那么会导致报出 'File not found' 的错误

[L]


[L]能够使得mod_rewrite 停止处理规则集。在众多contexts中,这意味着,一旦规则匹配了,就没有后续规则会被处理。这相当于Perllast命令,或者Cbreak命令。使用这个flag去指示当前规则应该立即应用,不用管后续的规则!

如果你也使用了RewriteRule .htaccess 或者在 <Directory> 中那么理解规则的处理过程是非常重要的。简单来说,一旦规则被处理,就会发起一个重写请求给URL解析引擎去重新处理这个url(译者注:就是重写的结果)。当这个重写请求被处理的时候,.htaccess  <Directory>就会被重新收集,因此规则集就会重新匹配。通常来说,如果一个规则导致重定向到-,无论是内部重定向还是外部重定向,都会让请求过程重新开始。

也是因为这个原因,如果你使用 RewriteRule 指令在某个context中,那么你要非常注意,防止闭环规则。并且不要单单关注有[L]flag那个结束执行一系列规则的那一条,还要理解整个流程。

有个可选的flag,[END],能够结束不单单是当前这一round的重写过程,还能阻止后续的重写过程。

Demo:

RewriteBase "/"

RewriteCond "%{REQUEST_URI}" "!=/index.php"

RewriteRule "^(.*)" "/index.php?req=$1" [L,PT]

上面的demo会重写所有请求到index.php,将原始请求作为一个query string参数给index.php,利用RewriteCond来确保如果当前请求已经是到index.php的,那么就跳过

 RewriteRule

[E]


通过[E],或者[env] flag,你可以设置环境变量。记住,有一些环境变量会在规则运行之后被设置,因此有可能会覆盖掉你设置的值。查看 the Environment Variables document 这个文档能够知道更多环境变量的运作。

完整的语法如下:

[E=VAR:VAL]

[E=!VAR]

Demo:

RewriteRule "\.(png|gif|jpg)$" "-" [E=image:1]

CustomLog "logs/access_log" combined env=!image

 

 

参考链接:http://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_l

<think>我们正在讨论Apache 2.4.6-98中RewriteRule指令的中括号[]参数,即标志(flags)。这些标志用于修改规则的行为,例如控制重写流程、处理代理请求等。下面将详细说明常见标志及其用法。 ### 一、RewriteRule 标志概述 RewriteRule 的语法为: ```apache RewriteRule Pattern Substitution [flags] ``` 其中 `[flags]` 部分是可选的,用于指定额外的规则行为。多个标志用逗号分隔,例如:`[R=301,L]`。 ### 二、常用标志详解 以下是一些常用标志及其含义: 1. **`B` (Escape backreferences)** 对反向引用中的特殊字符进行转义。例如,将 `&` 转义为 `%26`。 示例:`RewriteRule ^search/(.*)$ /search.php?term=$1 [B]` 2. **`C` (Chain)** 将当前规则与下一条规则链接(Chaining)。如果当前规则不匹配,则跳过链中的后续规则。 示例: ```apache RewriteRule ^category/([^/]+) - [C] RewriteRule ^category/([^/]+)/([^/]+) /shop.php?cat=$1&subcat=$2 ``` 3. **`CO` (Cookie)** 设置 Cookie。语法:`[CO=name:value:domain:lifetime:path:secure:httponly]`。 示例: ```apache RewriteRule ^login$ /auth.php [CO=userid:123:.example.com:300:/:true] ``` 4. **`E` (Environment variable)** 设置环境变量。语法:`[E=VAR:VAL]`。 示例: ```apache RewriteRule .* - [E=MY_VAR:some_value] ``` 5. **`F` (Forbidden)** 返回 403 Forbidden 响应。 示例: ```apache RewriteRule ^private/.* - [F] ``` 6. **`G` (Gone)** 返回 410 Gone 响应(资源永久不存在)。 示例: ```apache RewriteRule ^old-page$ - [G] ``` 7. **`H` (Handler)** 指定处理请求的处理器(如 `mod-php`)。 示例: ```apache RewriteRule \.php$ - [H=application/x-httpd-php] ``` 8. **`L` (Last)** 停止处理后续规则(Last rule)。 示例: ```apache RewriteRule ^user/([^/]+)/profile$ /profile.php?username=$1 [L] ``` 9. **`N` (Next)** 重新从第一条规则开始处理(Next round)。 示例: ```apache RewriteRule ^page/(.*)$ /page.php?name=$1 [N] ``` 10. **`NC` (No Case)** 忽略大小写(Case-insensitive matching)。 示例: ```apache RewriteRule ^apple$ /fruit [NC] ``` 11. **`NE` (No Escape)** 不对输出中的特殊字符进行转义(如 `#`, `&`, `%` 等)。 示例: ```apache RewriteRule ^redirect/(.*)$ /target#$1 [NE,R] ``` 12. **`P` (Proxy)** 将请求代理到另一个服务器(需启用 `mod_proxy`)。 示例: ```apache RewriteRule ^api/(.*)$ http://backend-server:8080/$1 [P] ``` 13. **`PT` (Pass Through)** 将重写结果传递给下一个处理器(如 Alias)。 示例: ```apache RewriteRule ^/images/(.*) /var/images/$1 [PT] ``` 14. **`QSA` (Query String Append)** 将原始请求的查询字符串追加到目标 URL。 示例: ```apache RewriteRule ^/search$ /search.php [QSA] ``` 原始请求 `/search?q=term` 将重写为 `/search.php?q=term`。 15. **`R` (Redirect)** 强制重定向(默认 302,可指定状态码)。 示例: ```apache RewriteRule ^old$ /new [R=301,L] ``` 16. **`S` (Skip)** 跳过后续若干条规则(Skip next N rules)。 示例: ```apache RewriteRule \.jpg$ - [S=2] RewriteRule \.png$ - RewriteRule \.gif$ - # 若请求 .jpg,则跳过接下来的两条规则 ``` 17. **`T` (Type)** 强制设置 MIME 类型。 示例: ```apache RewriteRule \.mp3$ - [T=audio/mpeg] ``` ### 三、标志组合示例 以下示例组合多个标志实现复杂功能: ```apache # 将 /testServlet/abc/123/ 代理到后端服务器,并保留查询字符串 RewriteRule ^testServlet/([^/]+)/([^/]+)/?$ http://0.0.0.0:9019/testServlet?appId=$1&functionId=$2 [P,QSA,L] ``` - `P`:代理转发 - `QSA`:追加原始查询字符串 - `L`:停止处理后续规则 ### 四、注意事项 1. **标志顺序无关** 标志的书写顺序不影响执行顺序(如 `[L,P]` 与 `[P,L]` 效果相同)。 2. **依赖模块** 部分标志(如 `P`)需要额外模块支持(例如 `mod_proxy`)。 3. **上下文限制** 某些标志仅在特定上下文中可用(如 `[CO]` 不能在 `<Directory>` 中使用)。 4. **转义问题** 使用 `NE` 标志可避免输出 URL 中的特殊字符被转义。 --- ### § 相关问题 1. 如何在 RewriteRule 中处理带空格的路径? 2. 如何调试复杂的重写规则? 3. 使用 `[P]` 标志时如何配置代理超时时间? 4. 如何避免重写规则引起的循环重定向? 5. 在虚拟主机配置中重写规则与全局配置有何区别? [^1]: Apache 官方文档中关于 RewriteRule 标志的详细说明[^1]。 [^2]: 代理转发(`[P]`)标志需要加载 `mod_proxy` 模块[^2]。 [^3]: 使用 `[L]` 标志时需注意规则处理顺序[^3]。</think>### Apache 2.4.6-98 RewriteRule 中括号 `[]` 参数详解Apache 的 `RewriteRule` 指令中,中括号 `[]` 内的参数称为**标志(Flags)**,用于控制重写规则的行为。以下是主要标志及其数学表达式和说明: #### 1. 基础控制标志 1. **`L` (Last)** $$ \text{匹配后立即停止处理后续规则} $$ 示例:`[L]` 表示这是当前请求的最后一条规则 2. **`NC` (No Case)** $$ \text{大小写不敏感匹配} $$ 示例:`[NC]` 使 `apple` 和 `ApPlE` 都会被匹配 3. **`OR` (Or next)** $$ \text{逻辑或操作符} $$ 示例:`[OR]` 用于组合多个匹配条件 #### 2. 重定向与代理标志 4. **`R[=code]` (Redirect)** $$ \text{HTTP重定向} \quad \text{默认} \quad 302 \quad \text{可指定状态码} $$ 示例:`[R=301]` 永久重定向 5. **`P` (Proxy)** $$ \text{代理转发请求} \quad \text{(需启用} \quad \text{mod\_proxy)} $$ 示例:`[P]` 将请求转发到后端服务器 #### 3. 查询字符串处理 6. **`QSA` (Query String Append)** $$ \text{保留原始查询参数} \quad \text{并追加新参数} $$ 示例:原始请求 `?a=1` + 重写 `?b=2` → `?a=1&b=2` 7. **`QSD` (Query String Discard)** $$ \text{丢弃原始查询参数} $$ 示例:原始请求 `?a=1` + 重写 `?b=2` → `?b=2` #### 4. 特殊处理标志 8. **`NE` (No Escape)** $$ \text{禁用URL编码转义} $$ 示例:保留 `#` `&` 等特殊字符 9. **`B` (Escape Backreferences)** $$ \text{对反向引用进行URL编码} $$ 示例:`$1` 中的特殊字符会被转义 #### 5. 条件控制标志 10. **`C` (Chain)** $$ \text{规则链控制} \quad \text{下一条规则的条件} $$ 示例:`[C]` 使下一条规则只在当前匹配时执行 #### 6. 综合示例 ```apache <IfModule mod_rewrite.c> RewriteEngine On # 将 /testServlet/abc/123/ 代理到后端,保留原始参数 RewriteRule ^testServlet/([^/]+)/([^/]+)/?$ http://0.0.0.0:9019/testServlet?appId=$1&functionId=$2 [P,QSA,L,NC] </IfModule> ``` - **`[P]`**:代理转发 - **`[QSA]`**:保留原始查询参数 - **`[L]`**:停止后续规则处理 - **`[NC]`**:大小写不敏感 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值