重写规则的条件(RewriteCond)
重写规则的条件 RewriteCond
Syntax: RewriteCond TestString CondPattern [flags]
RewriteCond指令定义一条规则条件。在一条RewriteRule指令前面可能会有一条或多条RewriteCond指令,只有当自身的模板(pattern)匹配成功且这些条件也满足时规则才被应用于当前URL处理。
TestString是一个字符串,除了包含普通的字符外,还可以包括下列的可扩展结构:
$N,RewriteRule后向引用,其中(0 <= N <= 9)
$N引用紧跟在RewriteCond后面的RewriteRule中模板中的括号中的模板在当前URL中匹配的数据。
%N,RewriteCond后向引用,其中(0 <= N <= 9)
%N引用最后一个RewriteCond的模板中的括号中的模板在当前URL中匹配的数据。
${mapname:key|default},RewriteMap扩展.
具体参见RewriteMap
%{ NAME_OF_VARIABLE } ,服务器变量。
变量的名字如下表(分类显示)
HTTP headers: connection & request: server internals: system stuff: HTTP_USER_AGENTREMOTE_ADDRDOCUMENT_ROOTTIME_YEARHTTP_REFERERREMOTE_HOSTSERVER_ADMINTIME_MONHTTP_COOKIEREMOTE_USERSERVER_NAMETIME_DAYHTTP_FORWARDEDREMOTE_IDENTSERVER_ADDRTIME_HOURHTTP_HOSTREQUEST_METHODSERVER_PORTTIME_MINHTTP_PROXY_CONNECTIONSCRIPT_FILENAMESERVER_PROTOCOLTIME_SECHTTP_ACCEPTPATH_INFOSERVER_SOFTWARETIME_WDAYQUERY_STRINGTIMEAUTH_TYPE
specials: 说明API_VERSIONApache与模块间的接口的版本号THE_REQUEST客户端发送到来的HTTP请求行的整行信息,不含其它的头字段信息,如("GET /index.html HTTP/1.1")REQUEST_URIHTTP请求行中请求的资源REQUEST_FILENAME请求中对应的服务器本地文件系统中全路径文件名IS_SUBREQ根据是否为SubRequest,分别值为”true”或”false”
特别说明:
SCRIPT_FILENAME和REQUEST_FILENAME变量含有相同的值,也就是Apache服务器内部数据结构request_rec的filename字段的值。第一个变量是一个CGI变量,而第二个则与REQUEST_URI(含有request_rec数据结构中uri字段的值)保持一致。
%{ENV:variable}中的variable可以是任何环境变量的名字。对其值的查找,先通过Apache内部的数据结构,(如找不到)再在Apache服务器进程中通过getenv()查找。
%{HTTP:header}中的header可以是任何HTTP MIME-header的名字,其值通过查找HTTP请求信息而得。
%{LA-U:variable} 用来引用后续API阶段中定义的、当前还不知道的值,具体实现是通过执行一个基于URL的内部的sub-request来决定的variable的最终的值。例如,假如你想在服务器范围内利用REMOTE_USER的值来完成重写,但这个值是在验证阶段设置的,而验证阶段是在URL转换阶段的后面。从另一方面讲,由于mod_rewrite在修补(fixup)API阶段进行目录范围的重写,而修补阶段在验证阶段的后面,所以此时只要用%{REMOTE_USER}就可以取得该值了。
%{LA-F:variable},执行一个基于文件名字(filename)的内部sub-request来决定variable的最终的值。大多数时间内,这和LA-U相同。
CondPattern是一个条件模板,也就是说,是一个扩展正则式(extended regular expression),用与跟TestString进行匹配。作为一个标准的扩展正则式,CondPattern有以下补充:
可以在模板串前增加一个!前缀,以用表示不匹配模板。但并不是所有的test都可以加!前缀。
CondPattern中可以使用以下特殊变量:
' 将condPattern当作一个普通字符串,将它和TestString进行比较,当TestString 的字符小于CondPattern为真.
'>CondPattern' (大于)
将condPattern当作一个普通字符串,将它和TestString进行比较,当TestString 的字符大于CondPattern为真.
'=CondPattern' (等于)
将condPattern当作一个普通字符串,将它和TestString进行比较,当TestString 与CondPattern完全相同时为真.如果CondPattern只是 "" (两个引号紧挨在一起) 此时需TestString 为空字符串方为真.
'-d' (是否为目录)
将testString当作一个目录名,检查它是否存在以及是否是一个目录.
'-f' (是否是regular file)
将testString当作一个文件名,检查它是否存在以及是否是一个regular文件.
'-s' (是否为长度不为0的regular文件)
将testString当作一个文件名,检查它是否存在以及是否是一个长度大于0的regular文件
'-l' (是否为symbolic link)
将testString当作一个文件名,检查它是否存在以及是否是一个 symbolic link.
'-F' (通过subrequest来检查某文件是否可访问)
检查TestString是否是一个合法的文件,而且通过服务器范围内的当前设置的访问控制进行访问。这个检查是通过一个内部subrequest完成的, 因此需要小心使用这个功能以降低服务器的性能。
'-U' (通过subrequest来检查某个URL是否存在)
检查TestString是否是一个合法的URL,而且通过服务器范围内的当前设置的访问控制进行访问。这个检查是通过一个内部subrequest完成的, 因此需要小心使用这个功能以降低服务器的性能。
[flags]是第三个参数,多个标志之间用逗号分隔。
'nocase|NC' (不区分大小写)
在扩展后的TestString和CondPattern中,比较时不区分文本的大小写。注意,这个标志对文件系统和subrequest检查没有影响.
'ornext|OR' (建立与下一个条件的或的关系)
默认的情况下,二个条件之间是AND的关系,用这个标志将关系改为OR。例如:
RewriteCond %{REMOTE_HOST} ^host1.* [OR]
RewriteCond %{REMOTE_HOST} ^host2.* [OR]
RewriteCond %{REMOTE_HOST} ^host3.*
RewriteRule ...
如果没有[OR]标志,需要写三个条件/规则.
例子:根据客户端浏览器的不同,返回不同的首页面。
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
RewriteRule ^/$ /homepage.max.html [L]
RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
RewriteRule ^/$ /homepage.min.html [L]
RewriteRule ^/$ /homepage.std.html [L]
重写影射、目录(RewriteMap RewriteBase)
重写影射 RewriteMap
Syntax: RewriteMap MapName MapType:MapSource
RewriteMap指令定义一个重写影射(Rewriting Map),在规则的substitution串中,通过影射函数(mapping-functions)来查找关键字(key),并用关键字对应的值来进行来行插入或替换操作。这个查找的对象,可以是各种各样的。
MapName是影射的名字,将用来通过下列的某种结构来为substitution定义影射函数:
${ MapName : LookupKey }
${ MapName : LookupKey | DefaultValue }
当这些结构之一出现substitution串中时,重写引擎会到mapname影射中查找lookupkey关键字,如果找到了就用返回的值(substvalue)来替换该结构,如果找不到就用defaultvalue来替换该结构,如果没有defaultvalue,就用空串来替换。
MapType 和mapSource组合有以下几种:
标准的普通文本(Standard Plain Text)
MapType: txt, MapSource: Unix文件系统中合法的带有路径的regular file名
此种情况下,MapSource文件是一个普通的ASCII文本文件,可以含有空行、注释行(以#打头),及以下结构的键值对行(每个键值对一行)。
MatchingKey SubstValue
例如:Mapsource文件叫/path/to/file/map.txt,其内容为
##
## map.txt -- rewriting map
##
Ralf.S.Engelschall rse # Bastard Operator From Hell
Mr.Joe.Average joe # Mr. Average
在配置文件中则可以这样定义重写映射:
RewriteMap real-to-user txt:/path/to/file/map.txt
随机的普通文本(Randomized Plain Text)
MapType: rnd, MapSource: Unix文件系统中合法的带有路径的regular file名
这种情况与标准普通文本情况很相似,差别只是在SubstValue的格式上:此时的SubstValue由一些用”|”分隔的值组成的串,这个“|”是“或者”的意思。当根据键值找到对应的SubstValue后,mod_rewrite借助“|”将此串分解为一些候选项,然后随机选择一项作为最终的SubstValue的值返回。这听起来有点疯狂或毫无用处,其实这是设计用来在反向代理(reverse proxy)的情况下做负载均衡,用来查找服务器的名字。
例如:MapSource文件的名字为/path/to/file/map.txt,内容如下:
##
## map.txt -- rewriting map
##
static www1|www2|www3|www4
dynamic www5|www6
在配置文件中定义的重写影射为:
RewriteMap servers rnd:/path/to/file/map.txt
Hash File
MapType: dbm, MapSource: Unix文件系统中合法的带有路径的regular file名
这儿的Mapsource文件是一个二进制的NDBM格式的文件,含有与普通文本格式文件时相同的内容,为了实现快速查找进行了优化处理后以一种特殊的格式来表达。 可以用任何NDBM工具或者用下面的Perl脚本txt2dbm.pl来创建这种格式的文件:
#!/path/to/bin/perl
##
## txt2dbm -- convert txt map to dbm format
##
use NDBM_File;
use Fcntl;
($txtmap, $dbmmap) = @ARGV;
open(TXT, "<$txtmap") or die "Couldn't open $txtmap!\n";
tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644) or die "Couldn't create $dbmmap!\n";
while () {
next if (/^\s*#/ or /^\s*$/);
$DB{$1} = $2 if (/^\s*(\S+)\s+(\S+)/);
}
untie %DB;
close(TXT);
此脚本的使用方法如下:
$ perl txt2dbm.pl map.txt map.db
Apache内部函数(Internal Function)
MapType: int, MapSource: Apache内部函数
这时,MapSource是一个Apache内置函数,目前还不能创建自己的内部函数,只能使用Apache已经定义好的:
toupper
将键值转换为大写
tolower
将键值转换为小写
escape
将键值中的特殊字符转换为以16进制表示。
unescape
将键值中16进制表示的特殊字符转换为原来的样子。
外部重写程序(External Rewriting Program)
MapType: prg, MapSource: Unix文件系统中合法的带有路径的regular file名
这儿的MapSource是一个程序而不是一个影射文件。你可以使用任何语言创建这个程序,但这个程序必须是可执行的(也就是说,要么是二进制码,要么是首行带有”#!/path/to/interpreter”格式的解释器的可执行脚本)。
这个程序在Apache启动时被运行,然后它就用它的标准输入与标准输出的文件句柄与重写引擎通信(暗指程序能无限时等待标准输入,见下列)。对每个影射函数的查找要求,它把其标准输入中得到的字符串(newline-terminated string?)作为键值,然后通过标准输出返回查找到的值,如果找不到相应的值,则返回以四字符的字符串”NULL“。下面一个简单的例子,实现将键值作为查找结果返回:
#!/usr/bin/perl
$| = 1;
while () {
# ...put here any transformations or lookups...
print $_;
}
注意:
``Keep it simple, stupid'' (KISS),因为当规则执行时,一量这个外部程序挂起,整个Apache服务器就挂起了
避免下述常见错误:缓存了标准输出的I/O。这会导致死循环。这也是为什么上例中有``$|=1''这么一行的原因
用RewriteLock指令定义一个lockfile,以同步与外部程序的通信。默认情况下并没有这样的同步
RewriteMap可以出现不只一次。每个影射函数用RewriteMap来声明它的影射文件. While you cannot declare a map in per-directory context it is of course possible to use this map in per-directory context.(?)对普通文本和DBM格式的文件,其键值被缓存在Apache内核中,直到影射文件的mtime 变化了或Apache重启动了。此时,可以将规则中的影射函数用于每个请求。
RewriteBase
Syntax: RewriteBase URL-path
RewriteBase明确地指出目录范围内的重写结果的baseURL.RewriteRule指令可以用在目录范围内的配置文件里(.htaccess)。在目录范围的重写实施时,由本地路径信息构成的前缀已经被去掉,重写规则只对剩余的部分进行处理。处理结束后,被去掉的路径信息要自动加上,因为当对一个URL进行替换后,重新引擎需要将它重新插入到服务器的处理流程中去。如果服务器端的URL与文件的物理路径有直接有关系,则每当在.htacess文中定义重写规则时都需要用RewriteBase指URL-path。
杂项Environment Variables
mod_rewrite还维护着两个非标准的CGI/SSI环境变量,名为SCRIPT_URL和 SCRIPT_URI,存放着当前资源的逻辑web视图(logical Web-view)。标准的CGI/SSI变量SCRIPT_NAME 和 SCRIPT_FILENAME中存放着当前资源的物理系统视图(physical System-view)。请看例子:
SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/
分享到:
相关推荐
4. **RewriteCond**: 这是重写规则的条件,可以设置多个条件来决定何时执行`RewriteRule`。`RewriteCond test-pattern [flags]`,`test-pattern` 可以是服务器变量、环境变量或自定义条件。 - `%1-9`: 引用前一个`...
### Apache 重写规则的常见应用 #### 一、引言 在互联网世界中,网站维护与优化是一项持续性的工作,而URL重写是其中一项关键的技术手段。它不仅可以帮助我们美化URL,提升用户体验,还能在网站结构变化时避免链接...
以下是对Apache URL重写规则中一些常用标志的详细说明: 1. **R[=code]**: 强制外部重定向。此标志会在替代字符串前添加主机名和端口号,形成完整的外部URL,并使用指定的HTTP状态码进行重定向。默认情况下,状态码...
通过对上述`.htaccess`配置文件的解析,我们了解了如何通过重写引擎、重写条件及重写规则来实现对特定URL的重定向。这对于网站管理者来说是非常有用的技术,可以帮助改善网站结构、提高SEO效果等。同时,掌握这些...
这是Apache服务器中的一个配置文件,用于控制网站的目录级配置,如重写规则、访问权限、错误页面设置等。将重写规则写入.htaccess文件,可以让我们无需直接修改服务器主配置,就能实现URL的重定向或重写。 正则...
`RewriteRule`则定义了重写规则,`^products/(\d+)$`匹配以`/products/`开头,后面跟着一个或多个数字的URL,`$1`是捕获的数字组,最后的[L]标志表示这是最后一条规则,防止进一步的重写。 标签`urlrewriter`可能指...
在实际应用中,RewriteCond可以使用各种正则表达式和条件逻辑来实现复杂的URL重写规则。合理使用RewriteCond和RewriteRule可以帮助网站管理者优化URL结构、实现URL规范化、简化动态URL,从而提高网站的可维护性和...
此外,对于大型或复杂的网站,可能需要使用多个规则,甚至借助RewriteCond(重写条件)进行更复杂的逻辑控制。总的来说,Apache Rewrite规则是Web开发者的重要工具,对于优化网站架构和提升用户体验起着关键作用。
-f`:这两个条件判断请求的资源是否是目录或文件,如果不是,则执行后面的重写规则。 - `RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]`:将所有请求重定向到`index.php`,并在URL参数中附加原路径信息。 4. **设置...
总结一下,PHP的URL重写技巧主要包括使用`.htaccess`文件设置重写规则,理解`RewriteRule`和`RewriteCond`的工作原理,以及在PHP代码中处理重写后的URL。通过熟练掌握这些技巧,你可以构建出更加优雅、易于管理和...
- 注意性能影响,大量的Url重写规则可能会增加服务器负担,需权衡优化效果和性能损失。 7. **总结** Url重写和伪静态技术是现代Web开发中不可或缺的一部分,它不仅提升了网站的美观度,也对SEO和用户体验起到了...
这段代码首先开启URL重写引擎,然后设定两个条件规则。第一条规则检查请求的文件名是否有一个对应的.html文件存在,如果存在,则重写URL为.html格式。第二条规则则是当请求的HTML文件不存在,但对应的.php文件存在时...
该规则中,`RewriteCond`用于条件判断,如果当前请求的主机名是`snxian.com`,则执行后续的重写规则,将所有请求重定向至`www.snxian.com`。 #### ISAPI_Rewrite 2.x 版本 ```plaintext [ISAPI_Rewrite] ...
3. **URL重写规则**:这部分包含一系列的RewriteCond和RewriteRule,用于指定URL重写的条件和处理方式: ``` RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ ...
在这个例子中,我们定义了两个条件(RewriteCond)来确保只有当请求的URL不是一个实际存在的文件或目录时才执行重写规则。接着,我们使用`RewriteRule`设置了一个规则,将`^article/([0-9]+)/?$`模式匹配到的URL...
RewriteRule是mod_rewrite的核心指令,用于定义URL重写规则。其基本语法如下: ``` RewriteRule pattern replacement [flags] ``` 其中,pattern表示要匹配的URL模式,replacement表示重写后的URL,flags表示规则...
配置Rewrite规则时,我们需要理解一些基本的正则表达式和Rewrite指令,如 `RewriteEngine On` 开启重写引擎,`RewriteRule` 定义具体的重写规则,以及 `RewriteCond` 设置条件判断。在实际应用中,还需要注意避免...
`Rewrite.dll`是IIS中的一个URL重写模块,由Microsoft开发,它是IIS URL Rewrite Module的一部分,支持多种URL重写规则和条件。 **配置Rewrite.dll:httpd.ini文件** 在IIS虚拟机中使用`Rewrite.dll`进行URL重写时...
2. **RewriteCond条件**:定义匹配URL的条件,可以是基于请求的路径、查询字符串等。例如,`RewriteCond %{REQUEST_FILENAME} !-f`表示如果请求的文件不存在于服务器上,则继续执行下一个规则。 3. **RewriteRule...