(转)Apache Rewrite 详解

(转)Apache Rewrite 详解


Apache Rewrite 详解一 入门
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
就这两行. 而后就完成了URL重写功能了. 

首先服务器是须要支持网站使用 .htaccess 文件模式. 这个须要服务器或者虚拟主机的配置段里给你配置 AllowOverride, 一般设置成 All 容许全部指令在 .htaccess 生效. 再看第一行:
RewriteEngine on 这行告诉apache服务器, 这个目录要使用URL重写功能了.
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php 这行是具体的重写规则, 以上是若是有URL来访问该目录里的文件, 若是URL不是以 .js, .ico, .gif, .jpg, .png, .css 这几种结尾的话. 那么所有调用 目录下的 index.php 文件. 这个提及来比较费劲, 搞个具体的例子. 好比咱们又一个网站, 域名为: www.test.com 该站支持 .htaccess 功能. 咱们把上面两行保存为 .htaccess 放到网站目录下. 若是WINDOW下不容许保存这样的文件名的话不要紧. 随便保存为 x.htaccess, 而后在DOS下 rename x.htaccess .htaccess 就好了.
在www.test.com 网站根目录下放3个文件, 一个是 .htaccess, 一个是 logo.png, 一个是 index.php
测试一: 在浏览器地址栏里输入: http://www.test.com/ 很正常. 页面应该默认显示 index.php 文件的内容.
测试二: 在浏览器地址栏里输入: http://www.test.com/logo.png 也很正常. 网页里应该看到了这个png图片了.
测试三: 在浏览器地址栏里输入: http://www.test.com/test.php 这样通常来讲, 若是没开重写功能的话. 一般你会看到404错误. 这说明你服务器APACHE的rewrite功能没生效. 否则你看到的是和 测试一同样的内容. 由于请求 test.php 被定向到 index.php. 实际上是和访问http://www.test.com/index.php 一个效果. 这就是apache最简单的rewrite功能了.
OK, 另外再说名一下 .htaccess 文件里的一些小事情. 若是你要给指令添加注释, 防止复杂的重写规则时间常了要修改的话还要费劲去看,或者协做开发让别人能很容易看懂. 这样只要在每行的第一个字符写成"#" 就好了. 一般的指令的第一个字符是一个大写英文字母, 后面的是按照驼峰命名法写出, 好比开启重写指令: RewriteEngine, 指令值通常是小写的字符串. 像上面的 RewriteEngine on
再看一下完整的简单的.htaccess文件代码:
#该目录下使用Apache Rewrite 功能. RewriteEngine on   #全部的访问请求, 除了是以 .js, .ico, .gif, .jpg, .png, .css 结尾, 都定向到index.php脚本 RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php 上面的重写规则指令用到了正则表达式. 这方面不太了解的话想去补充一下. 否则后面的部分会看起来比较费劲.
关于 RewriteRule 这个是比较能让人花点时间玩的东西了. 下篇问详细介绍它的用法和参数.
-----------------------------------------------------------------------------------------------------------------
Apache Rewrite 详解二 参数标志[Flag]
上一篇聊了一下最简单的重写模式. 在进入比较好玩的重写模式以前. 先给说名一下重写规则后面的那些中括号里的大写字符是什么意思. 否则会让你看后面的代码晕头转向的. 关于这些参数的说明在 apache.org 的官方文档里有说明, 惋惜没有中文的. 我大概的翻译了一下表面意思. 建议去看原E文文档. E文实在很差的先凑合着看看. 官方关于 Rewrite Flag 文档地址在: http://httpd.apache.org/docs/2.2/rewrite/rewrite_flags.html
 
重写规则的通常模式为下面的语法.
RewriteRule pattern target [Flag1,Flag2,Flag3]
RewriteRule 规则能够在后面添加标志(Flag), 能够又多个 flag, 多个 flag 用逗号"," 链接.
 
先说明一下一个比较特别的 target 值: "-", 若是目标是 "-" 的话, 那么被请求的URL不会被修改掉.
 
下面详细简介一下各个 flag 表明的意思.
 
C|chain
字符 'C' 或者 字符串 'chain' 表示出了该行重写规则外还要有其余的重写规则, 至关于一般程序语言的 与符号 '&' , 若是第一条规则条匹配的话进行下一项条件匹配. 若是第一条或者中间一条匹配不成功. 在其后的都会被跳过.
 
CO|cookie
字符 'CO' 或者 字符串 'cookie' 表示当某些特殊的规则被匹配到的时候, 容许设置一个COOKIE, 设置参数包含3个必须字段和2个可选字段.
三个必须的字段是设定COOKIE的名字, 值, 还有这个COOKIE的所属域名, 另外两个可选的字段是COOKIE的生存时间和路径.默认的COOKIE生存时间是浏览器的会话时间. 默认的路径是 '/', 针对整个网站.
实际的使用例子想下面这样
RewriteEngine On
# RewriteRule 匹配模式 - [CO=COOKIE名称:COOKIE值:COOKIE域名:生存时间:路径] 各个参数用冒号:链接
RewriteRule ^/index.html - [CO=mycookie:myCookieValue:.test.com:1440:/]
#RewriteRule ^/index.html - [CO=mycookie:myCookieValue:.test.com] 或者省略后面的参数.
上面的规则的意思是在请求 index.html 文件的时候设置一个COOKIE值. COOKIE名是 mycookie, 值是:myCookieValue, 生效的域名是 .test.com, 生效时间是分钟计算的. 也就是生存时间是1天=24小时=1440分钟.
 
E|env
字符 'E' 或者 字符串 'env' 表示你能够设置一个环境变量. 注意一下变量在这个规则运行后生效.
看一个简单的例子, 就是apache在记录日志的时候不记录图片的读取记录. 那么下面的规则就有用了.
RewriteRule \.(png|gif|jpg) - [E=image:1]
CustomLog logs/access_log combined env=!image
 
F|forbidden
字符 'F' 或者 字符串 'forbidden' 表示禁止访问. Apache服务器会返回403禁止访问状态码给客户端.
下面的规则表示获取或者下载 exe程序文件是被显示禁止访问.
RewriteRule \.exe - [F]
 
G|gone
字符 'G' 或者 字符串 'gone' 表示服务器响应状态码为:410 一般使用该标志的时候 target 目标值设置成 "-" 被请求的资源是有效的.
下面的例子表示旧的资源是有效的. 而且不在意大小写.
RewriteRule oldproduct - [G,NC]
 
H|handler
字符 'H' 或者 字符串 'handler' 表示强制使用某类型处理程序处理被请求的资源. 好比请求一些不带后缀的文件的时候. 下面的列子表示当请求的URL里没有带'.'的时候, 强制使用PHP来处理这类的请求.
RewriteRule !\. - [H=application/x-httpd-php]
 
L|last
字符 'L' 或者 字符串 'last' 表示当前规则是最后一条规则,中止分析之后规则的重写。该标志的使用频率很是高.
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule ^(.*) index.php?req=$1 [L]
必定要注意的地方, 使用[L]标志的时候, 必定要注意你的匹配条件, 不会很是容易让你的重写规则陷入死循环, 好比你要定义页面全部页面请求都重写到一个 index.php 文件, 那么必定要注意在匹配条件时肯定当请求的脚本不是index.php时才执行重写规则. 否则很明显当前页面请求的是 index.php, 固然 这个请求被重写到 index.php 而后index.php又被重写到index.php.. 这样反复执行. 页面会报错. 错误日志会记录报告你超出最大的重定向次数.
 
N|next
字符 'N' 或者 字符串 'next' 表示从新回到规则顶部重复执行. 通常在极端状况下用这个标志. 至关于一个while循环, 知道匹配失败时返回. 下面的例子表示把请求地址中的全部A字符替换成B字符.
RewriteRule (.*)A(.*) $1B$2 [N]
 
NC|nocase
字符 'NC' 或者 字符串 'nocase' 表示请求的规则部分不区分大小写. 相似正则式里的/xxx/i 模式.
RewriteRule (.*\.(jpg|gif|png))$ http://images.test.com$1 [P,NC]
 
NE|noescape
字符 'NE' 或者 字符串 'noescape' 表示不对URL中的特殊字符进行 hexcode 转码.看下面的例子:
RewriteRule ^/share/(.+) /goShare.html#$1 [NE,R]
上面的例子表示全部请求 /share/xxx.xx的请求都会被定向到/goShare.html文件上. 而且后面的部分做为一个#后面的值. 若是不加NE标志的话, #将被转义成 # 这样就形成 404 错误了.
 
NS|nosubreq
字符 'NS' 或者 字符串 'nosubreq' 表示只用于不是内部子请求.好比,在mod_include试图搜索可能的目录默认文件(index.xxx)时, Apache会内部地产生子请求。对子请求,它不必定有用的,并且若是整个规则集都起做用,它甚至可能会引起错误。因此,能够用这个标记来排除某些规则。根据你的须要遵循如下原则: 若是你使用了有CGI脚本的URL前缀,以强制它们由CGI脚本处理,而对子请求处理的出错率(或者开销)很高,在这种状况下,可使用这个标记。
 
P|proxy
字符 'P' 或者 字符串 'proxy' 标志须要模块 mod_proxy 支持, 相似一个分发器网关的做用.好比网站的全部图片想用单独的一台服务器来运行. 那么先前的代码里的图片请求的时候, 直接定向到图片服务器去.
RewriteRule (.*)\.(jpg|gif|png) http://images.example.com$1.$2 [P]
使用[P]标志, 意味着使用了[L]标志, 由于使用该标志后立刻就重定向到新地址了. 后面的重写规则会被忽略掉.
 
PT|passthrough
字符 'PT' 或者 字符串 'passthrough' 表示替换URL请问部分的地址.看例子
Alias /icons /usr/local/apache/icons
RewriteRule /pics/(.+)\.jpg /icons/$1.gif [PT]
当请求/pics/下的图片文件时, 实际是返回的是 /icons/目录下的同名文件. 须要注意的是必定要设置 [PT] 标志. 不然Alias设置无效.
 
QSA|qsappend
字符 'QSA' 或者 字符串 'qsappend' 不怎么好表示. 看例子:
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
若是又标志: [QSA] 那么重写后的URL是: /page.php?page=123&one=two
若是没有[QSA]标志, 那么结果是: /page.php?page=123
此标记强制重写引擎在已有的替换串中追加一个请求串,而不是简单的替换。 若是须要经过重写规则在请求串中增长信息,就可使用这个标记。
 
R|redirect
字符 'R' 或者 字符串 'redirect' 表示进行重定向, 状态码在300-399里随机出, 默认是 302 重定向.一般和标志L一块儿使用. 使用模式: [R[=302]]
 
S|skip
字符 'S' 或者 字符串 'skip' 表示跳过执行下面的几个重写规则. 又点相似goto. 看下面的例子, 若是URL请求的文件不存在的话就跳过下面的两行重写规则.
# 请求的文件是否存在
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 不存在的状况
RewriteRule .? - [S=2]
RewriteRule (.*\.gif) images.php?$1
RewriteRule (.*\.html) docs.php?$1
 
T|type
字符 'T' 或者 字符串 'type' 表示为apache设置特定请求的响应类型. 也就是常说的 MIME type,好比一个perl脚本. 但愿给客户端显示文本源码, 那么能够这样作:
RewriteRule \.pl$ - [T=text/plain]
或者你的服务器上的文件没有设置扩展名. 那么能够通知重写添加该文件的类型. 方便客户端显示.
RewriteRule IMG - [T=image/jpg]
 
以上就是Apache 官方文档提到的所有标志值及其相关的意思了. 接下来咱们将介绍他们用到具体的实际例子中去. 上面代码的例子看不懂不要紧. 接下来我会很详细的解释它的. :)   这篇就先到这里吧.
------------------------------------------------------------------------------------------------------------------ Apache Rewrite 详解三 服务器变量
上一篇日志大概了解了重写规则的标志量的意思, 这篇先把Apache 能提供给rewrite模块的服务器变量信息了解一下. 否则会在之后的重写规则中对变量的大概内容都不了解. 理解起来就比较费劲了.
须要注意的一点是在 .htaccess 文件中使用服务器参数是的写法是: %{参数名}, 好比HOST名称: %{HTTP_HOST}
Apache提供给rewirte模块的环境变量大概分红5个类型. 下面一一说明.
 
第一部分: HTTP headers 部分参数
参数名称: HTTP_USER_AGENT
样例参考值: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8
说明: 至关于PHP中的服务器参数: $_SERVER["HTTP_USER_AGENT"]
参数名称: HTTP_REFERER
样例参考值: http://www.test.cn/test.php
说明: 至关于PHP中的服务器参数: _SERVER["HTTP_REFERER"]
参数名称: HTTP_COOKIE
样例参考值: ZDEDebuggerPresent=php,phtml,php3
说明: 至关于PHP中的服务器参数: $_SERVER["HTTP_COOKIE"]
参数名称: HTTP_FORWARDED
样例参考值: 若是使用代理服务器的话会是代理服务器的IP地址, 本地不容易搭环境测试出值来.
说明: 至关于PHP中的服务器参数: $_SERVER["HTTP_FORWARDED"]
参数名称: HTTP_HOST
样例参考值: www.test.com
说明: 至关于PHP中的服务器参数: $_SERVER["HTTP_HOST"]
参数名称: HTTP_PROXY_CONNECTION
样例参考值: 网络链接代理方面的信息. 和HTTP_FORWARDED参数同样. 本地不容易搭环境测试出值来.
说明: PHP中貌似未提供这样的服务器信息值. 若是又的话可能等值于: $_SERVER["HTTP_PROXY_CONNECTION"]
参数名称: HTTP_ACCEPT
样例参考值: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
说明: 至关于PHP中的服务器参数: $_SERVER["HTTP_ACCEPT"]
 
第二部分: server internals 部分参数
参数名称: DOCUMENT_ROOT
样例参考值: C:/webRoot/t
说明: 至关于PHP中的服务器参数: $_SERVER["DOCUMENT_ROOT"]
参数名称: SERVER_ADMIN
样例参考值: youemailaddress@gmail.com
说明: 至关于PHP中的服务器参数: $_SERVER["SERVER_ADMIN"]
参数名称: SERVER_NAME
样例参考值: www.test.com
说明: 至关于PHP中的服务器参数: $_SERVER["SERVER_NAME"]
参数名称: SERVER_ADDR
样例参考值: 127.0.0.1
说明: 至关于PHP中的服务器参数: $_SERVER["SERVER_ADDR"]
参数名称: SERVER_PORT
样例参考值: 80
说明: 至关于PHP中的服务器参数: $_SERVER["SERVER_PORT"]
参数名称: SERVER_PROTOCOL
样例参考值: HTTP/1.1
说明: 至关于PHP中的服务器参数: $_SERVER["SERVER_PROTOCOL"]
参数名称: SERVER_SOFTWARE
样例参考值: Apache/2.2.11 (Win32) PHP/5.2.9-1
说明: 至关于PHP中的服务器参数: $_SERVER["SERVER_SOFTWARE"]
 
第三部分: connection & request 部分参数
参数名称: REMOTE_ADDR
样例参考值: 127.0.0.1 正在浏览当前页面用户的 IP 地址。
说明: 至关于PHP中的服务器参数: $_SERVER["REMOTE_ADDR"]
参数名称: REMOTE_HOST
样例参考值: 127.0.0.1 正在浏览当前页面用户的主机名。反向域名解析基于该用户的 REMOTE_ADDR
说明: 至关于PHP中的服务器参数: $_SERVER["REMOTE_HOST"]
参数名称: REMOTE_PORT
样例参考值: 2574 (变化的值)用户链接到服务器时所使用的端口
说明: 至关于PHP中的服务器参数: $_SERVER["REMOTE_PORT"]
参数名称: REMOTE_USER
样例参考值: 空
说明: PHP 好像未提供相关的$_SERVER值.
参数名称: REMOTE_IDENT
样例参考值: 空
说明: PHP 好像未提供相关的$_SERVER值.
参数名称: REQUEST_METHOD
样例参考值: GET
说明: 至关于PHP中的服务器参数: $_SERVER["REQUEST_METHOD"]
参数名称: SCRIPT_FILENAME
样例参考值: C:/webRoot/t/share77.html
说明: 至关于PHP中的服务器参数: $_SERVER["SCRIPT_FILENAME"]
参数名称: PATH_INFO
样例参考值: 空
说明: 至关于PHP中的服务器参数: $_REQUEST["PATH_INFO"]
参数名称: QUERY_STRING
样例参考值: a=b&c=d&e=f
说明: 至关于PHP中的服务器参数: $_SERVER["QUERY_STRING"]
参数名称: AUTH_TYPE
样例参考值: 空 当 PHP 运行在 Apache 模块方式下,而且正在使用 HTTP 认证功能,这个是认证的类型
说明: 至关于PHP中的服务器参数: $_SERVER["AUTH_TYPE"]
 
第四部分: date and time 部分参数
参数名称: TIME_YEAR
样例参考值: 2009
说明: 服务器获取当前的年份值
参数名称: TIME_MON
样例参考值: 04
说明: 服务器获取当前的月份值
参数名称: TIME_DAY
样例参考值: 22
说明: 服务器获取当前的日值
参数名称: TIME_HOUR
样例参考值: 16
说明: 服务器获取当前时间的小时
参数名称: TIME_MIN
样例参考值: 26
说明: 服务器获取当前时间的分钟
参数名称: TIME_SEC
样例参考值: 34
说明: 服务器获取当前时间的秒
参数名称: TIME_WDAY
样例参考值: 3
说明: 服务器获取当天是星期几, 从星期日-星期六, 数字从 0-6
参数名称: TIME
样例参考值: 20090422162634
说明: 服务器获取当前的时间, 格式为: 年月日时分秒
 
第四部分: specials 部分参数
参数名称: API_VERSION
样例参考值: 20051115:21
说明: apache 的 API 版本信息.
参数名称: THE_REQUEST
样例参考值: GET /share77.html HTTP/1.1
说明: 浏览器发给服务器的请求值. 不包括其余的头信息.
参数名称: REQUEST_URI
样例参考值: /share77.html
说明: 浏览器请求的资源信息.
参数名称: REQUEST_FILENAME
样例参考值: C:/webRoot/t/share77.html
说明: 被请求的资源的在磁盘的物理地址.
参数名称: IS_SUBREQ
样例参考值: false
说明: 若是是 sub-request 则显示为 true, 不然为 false.
参数名称: HTTPS
样例参考值: off
说明: 若是链接使用 SSL/TLS 模式, 则值为on , 不然值为off, 这个参数比较安全, 即便未载入 mod_ssl 模块时.
OK, 以上就是Apache手册里提到的所有的服务器变量信息了. 这篇先到这里了. 

Apache Rewrite 详解四 杂项 
前篇介绍了Apache Rewrite 的服务器变量信息. 在进入重写实战以前. 有些小细节了解一下是很又必要的.
首先一点. 若是在重写规则的正则里要使用特殊字符的时候须要在该特殊字符前带一个转义字符: 反斜杠, 好比匹配一个百分号:%, 那么正确的写法就该是: \%, 其余的特殊字符均按此写法.
正反斜模杠
(转)Apache <wbr>Rewrite <wbr>详解
(转)Apache <wbr>Rewrite <wbr>详解


另外还有官方手册里提到的四个比较重要的服务器变量. SCRIPT_NAME, SCRIPT_FILENAME, SCRIPT_URL, SCRIPT_URI
其中 SCRIPT_NAME 和 SCRIPT_FILENAME 是apache会跟踪的两个标准CGI/SSI变量, 他们包含的是物理系统视图.
官方文档的示例值:
SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
另外还会跟踪两个非标准的变量 SCRIPT_URL 和 SCRIPT_URI. 他们包含的是逻辑网络视图.
官方文档的示例值:
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/
实际上按照上面的说法看起来
SCRIPT_NAME 的值是资源请求文件在服务器的实际地址.
SCRIPT_FILENAME 资源相对于站点根目录的实际地址.
SCRIPT_URL 则是URL的相对路径.
SCRIPT_URI 则是网络请求的绝度路径.
不过在实际测试中并未发现是上面的状况. 服务器配置环境为WINXP+APACHE2.2.11+PHP-5.2.9, module模式. 和 Linux+Apache2.2.6+PHP-5.2.5, module 模式. 四个变量中 SCRIPT_FILENAME 在没有 Alians 指令下未脚本在服务器端的实际地址. SCRIPT_NAME为请求的脚本相对应网站根目录的地址, 例如:/test.php 另外两个非标准变量为空. 若是在 重写规则中使用上面的四个变量须要注意一下.
另外正则部分又个"!"表示否的意思, 其余的正则和perl的正则相似. 这方面没信息的先看看正则方面的资料. 本系列完结后分享一个重写很系统的图表. 到时候做为一个查询工具. 很是方便.

Apache Rewrite 详解五 RewriteBase
如今咱们了解一下 Apache Rewrite 的重写规则的具体指令吧.
重写规则具体有 RewriteBase, RewriteCond, RewriteEngine, RewriteLock, RewriteLog, RewriteLogLevel, RewriteMap, RewriteOptions, RewriteRule 九个指令. 一般最经常使用的是 RewriteEngine, RewriteBase, RewriteCond, RewriteRule 四个指令. 这个咱们要重点讲解的. 若是这四个指令运用的比较熟练的话, 不是特别的网站. 基本上你想出什么样的URL 均可以知足你的须要了. 其余的指令就不在讲解了. 若是对前面说的4个指令比较熟悉的话. 剩下的去看看 apache 的手册. 相信掌握这些不会费你不少脑筋.
RewriteEngine 这个指令就不用说了. 就是是否使用 Rewrite 模式的开关, 使用就设置成 on, 不然设置成 off 做用域在: server config, virtual host, directory, .htaccess
咱们这篇日志专门讲解: RewriteBase
RewriteBase 的做用域为: directory, .htaccess
一般默认的虚拟主机的网站在使用.htaccess 进行重写规则时不须要执行设置该指令. 由于 RewriteBase 默认值是该 .htaccess 文件所在的目录地址.
可是若是使用目录别名的话就须要设置这个指令了. 先看官方手册的例子. 假设一个网站目录使用了别名操做: Alias /xyz /abc/def 那么当客户端访问/xyz/xxx.html 文件时是至关于访问 /abc/def/xxx.html的. 而后看看在使用了别名的状况下重写效果. 固然这个 .htaccess 文件在 /abc/def/.htaccess 位置. 内容以下:
RewriteEngine On
RewriteBase /xyz
RewriteRule ^oldstuff\.html$ newstuff.html
假设访问服务器的: /xyz/oldstuff.html (好比: http://www.test.com/xyz/oldstuff.html 这样).
服务器处理流程大概是下面的样子.
第一步, 把alias别名还原成真实的路径:
/xyz/oldstuff.html -> /abc/def/oldstuff.html   (per-server Alias)
第二步, rewrite前会去掉前缀(也就是.htaccess文件所在的目录部分这里是/abc/def/), 而后执行重写规则, 处理完以后再把前缀添加上去:
/abc/def/oldstuff.html -> /abc/def/newstuff.html   (per-dir     RewriteRule)
第三步, 因为设定了RewriteBase值,因此路径最后仍是被还原回去:
/abc/def/newstuff.html -> /xyz/newstuff.html       (per-dir     RewriteBase)
第四步, 重写规则完成, 别名再次使用. 最后获得的结果:
/xyz/newstuff.html     -> /abc/def/newstuff.html   (per-server Alias)
实际上至关于请求: /abc/def/newstuff.html, 关于 alias 的用法和意思, 请另行参考 apache 手册.
这里要注意的是即便RewriteBase /xyz 这行被注释掉. 服务器仍是会执行上面的 第一步, 第二步, 后面的不会被执行, 服务器执行完第二步之后就发出一个内部重定向. 按照上面的例子也就是 GET /abc/def/newstuff.html, 因为GET 模式获取到第一个是/开头的, 至关于请求DocumentRoot目录下的/abc/def/newstuff.html, 换成客户端请求的模式也就是 http://www.test.com/xyz/oldstuff.html 变成了 http://www.test.com/abc/def/newstuff.html 若是 /xyz 只是目录的别名, DocumentRoot 目录下根本没有实际的物理目录 abc/def 这样最终会致使一个 404 报错.
另外有一点就是在进行重写规则的时候. apache 会去掉目录前缀. 注意这个时候剩下的文件名或者相对目录第一个字符不是 / 开头的. 而直接是文件名或者目录这样的模式. 关于访问 http://www.test.com 和 访问 http://www.test.com/ 又什么不一样(最后加斜杠和不加斜杠). 服务器已经强制进行过了一次重定向(外部定向)了. 若是服务器未处理这类的事情的话. 就须要手动处理. 否则错误日志漫天飞. 那会是很痛苦的事情呢!
OK, 说完了. 收工先! 下篇说一下 RewriteCond.
Apache Rewrite 详解六 RewriteCond
RewriteCond 重写规则执行条件
语法: RewriteCond TestString CondPattern
生效域: server config, virtual host, directory, .htaccess
特别的上面的 TestString, 可提供反向引用. 引用模式为: %N 其中N为(0 <= N <=9), 引用当前若干RewriteCond条件中最后符合的条件中的分组成分, 也就是括号里的内容.不过用到的很少. 反向应用多在RewriteRule里经常使用.
RewriteCond 语法中的 TestStrng 为要被检查的内容, CondPattern 是进行匹配的规则, 它是一个兼容Perl风格的正则表达式和一些其余的特有字符属性. 这里介绍一下.
第一个: ! (感叹号) 表示否的意思. 好比一个条件: 判断访问此页面的上一页URL是否包含 sex 字符的话能够用这样: RewriteCond %{HTTP_REFERER} !(sex)
第二个: < 就是小于的意思, TestString < CondPattern.
第三个: > 就是大于于的意思, TestString < CondPattern.
第四个: = 相等的意思. <, >, = 三个和一般程序语言使用的 <, >, = 功能相似.
第五个: -d 是不是一个目录. 判断TestString是否不是一个目录能够这样: !-d
第六个: -f 是不是一个文件. 判断TestString是否不是一个文件能够这样: !-f
第七个: -s 是不是一个正常的有大小的文件. 判断TestString是否不是一个正常的有大小的文件能够这样: !-s
第八个: -l 是不是一个快捷方式文件. 判断TestString是否不是一个快捷方式文件能够这样: !-l
第九个: -x 是不是一个文件而且又执行权限. 判断TestString是否不是一个文件而且又执行权限能够这样: !-x
第十个: -F 检查TestString是不是一个合法的文件,并且经过服务器范围内的当前设置的访问控制进行访问。这个检查是经过一个内部subrequest完成的, 所以须要当心使用这个功能以下降服务器的性能。
第十一个: -U 检查TestString是不是一个合法的URL,并且经过服务器范围内的当前设置的访问控制进行访问。这个检查是经过一个内部subrequest完成的, 所以须要当心使用这个功能以下降服务器的性能.
另外: RewriteCond 指令后面可带 Flag, 如今只要2个可用, 一个是 NC|nocase, 不区分大小写的意思. 一个是 OR|ornext 表示链接下一个条件的意思.
RewriteCond 实际须要使用状况好比要判断一个条件成真的时候才执行相关的重写操做. 紧接着它下面的 RewriteRule 老是在RewriteCond 条件判断为真的时候才被执行.
看下面的一个例子:
#开启服务器重写模式
RewriteEngine on
#来自 www.test.cn 的链接访问本站时都只能访问 test.php 这页.
RewriteCond %{HTTP_REFERER} (www.test.cn)
RewriteRule (.*)$ test.php
#来自 www.test.com 的链接访问本站时都只能访问 newTest.php 这页.
RewriteCond %{HTTP_REFERER} (www.test.com)
RewriteRule (.*)$ newTest.php
OK, RewriteCond 就介绍到这里了. 其实很简单. 就想程序里的 if() 这样的效果. 下篇聊一下   RewriteRule
Apache Rewrite 详解六 RewriteRul
这两天回家了一趟. 又匆忙的赶回公司上班. 坐车那个累啊. 继续把 Apache 重写规则部分讲完.
前面的几篇关于重写的日志若是都看了的话. 这里就很容易了. 值得注意的地方是网站使用URL重写的话须要服务器配置 RewriteEngine On 和 Options FollowSymLinks, 否则重写规则不生效.
重写规则语法很简单: RewriteRule Pattern Substitution [Flag] 做用域为: server config, virtual host, directory, .htaccess
指令说明: 匹配部分(Pattern) 是正则匹配URL的正则表达式(注意特殊字符须要转义处理), 能够在替换部分(Substitution)使用反向引用匹配部分的内容. 引用模式为: $N (N为1-9的整数).
在URL重写的匹配部分中, 服务器会把请求的URL的一部分删除掉再传递给Pattern部分进行匹配. 重写结束后再添加上去. 全部日常咱们看到的匹配规则老是不带网址前面的那些域名的什么东西的. 也不带什么目录什么的. 这些 apache已经给删掉了. 处理完后再加到前面. 可是有个例外就是若是 Substitution 部分是带 http:// 开头的话, 那就直接重定向了. 服务器不会把先前删除的再给加上了. 否则就出错了.
给出个形象的流程图. 见下图:

官方的例子: 重写规则写在 httpd.conf 文件里. 请求地址为: http://www.test.com/somepath/pathinfo, 看下面几种结果.
Given Rule => Resulting Substitution
-------------------------------------------------------------------------------
^/somepath(.*) otherpath$1 => 不支持, 无效的重写语句
^/somepath(.*) otherpath$1 [R] => 不支持, 无效的重写语句
^/somepath(.*) otherpath$1 [P] => 不支持, 无效的重写语句
-------------------------------------------------------------------------------
^/somepath(.*) /otherpath$1 => /otherpath/pathinfo
^/somepath(.*) /otherpath$1 [R] =>   http://www.test.com/otherpath/pathinfo   外部重定向
^/somepath(.*) /otherpath$1 [P] =>   不支持, 很傻.
-------------------------------------------------------------------------------
^/somepath(.*) http://www.test.com/otherpath$1 => /otherpath/pathinfo
^/somepath(.*) http://www.test.com/otherpath$1 [R] => http://www.test.com/otherpath/pathinfo   外部重定向
^/somepath(.*) http://www.test.com/otherpath$1 [P] => 不支持, 很傻.
----------------------------------------------   ----------------------------------
^/somepath(.*) http://www.xxx.com/otherpath$1 => http://www.xxx.com/otherpath/pathinfo   外部重定向
^/somepath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo   外部重定向 [R] 多余.
^/somepath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 内部网关重定向
一样的请求上面的地址, 若是在 .htaccess 文件里的写法. 注意和 httpd.conf 写法的区别.
好比 .htaccess 文件在目录一个虚拟主机的根目录下. 而后请求 http://www.test.com/localpath/pathinfo 看下面的几种结果.
Given Rule => Resulting Substitution
-------------------------------------------------------------------------------
^localpath(.*) otherpath$1=> /otherpath/pathinfo
^localpath(.*) otherpath$1   [R] =>   http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) otherpath$1   [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) /otherpath$1 => /otherpath/pathinfo 注意 /otherpath$1 和 otherpath$1 的区别
^localpath(.*) /otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) /otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) http://www.test.com/otherpath$1       /otherpath/pathinfo
^localpath(.*) http://www.test.com/otherpath$1 [R]   http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) http://thishost/otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) http://www.test.com/otherpath$1 => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo 外部重定向 [R] 可省略
^localpath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 内部网关重定向
细细的看上面的例子. 重写规则仍是比较简单的. 下面放出一些经常使用的例子. 咱们使用 .htaccess 来定义重写规则. 假设域名为: www.test.com
.htaccess 放在网站根目录下. 好比: /.htaccess
例子1: 全部请求都定向到 index.php 脚本, 注意要排除 index.php 自己. 好比就进入死循环了.
RewriteRule !^index\.php$ index.php [L]
例子2: 当请求不存在的资源时, 统必定义到根目录下的 404.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /404.html [L]
例子3: 限制访问. 好比来自一些不友好的网站链接过来的请求. 不容许访问. 下例中若是 HTTP_REFERER 中包含 sex 字符, 则不容许访问.
RewriteCond %{HTTP_REFERER} sex
RewriteRule ^.*$ - [F]
例子4: 按照时间显示不一样的页面, 好比访问 hello.html 页面时. 若是 在 8:00-19:00 的时候访问. 显示 hello.day.html 其余时间访问显示: hello.night.html
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900
RewriteRule ^hello\.html$ hello.day.html
RewriteRule ^hello\.html$ hello.night.html
例子5: 伪静态化, 好比访问 /user20.html 则调用viewUser.php 显示用户ID为20的用户资料
RewriteRule ^user([0-9]*)\.html$ viewUser.php?userid=$1
例子6: 喜欢用二级域名的比较实用了. 好比网站目录下有 user, upload 等几个目录, 能够经过 http://www.test.com/user 这样的模式访问. 可是若是想作成统一用二级域名模式访问: http://user.test.com , 可是不容许 http://www.test.com/user 这样访问. 那么就像下面这样来限制.
RewriteCond %{REQUEST_URI} ^/user
RewriteRule ^.*$ http://user.test.net" [L]
关于重写条件的设置, 能够任意由你本身来定义. 其余的例子就很少举了. URL能够由你任意摆布.
重写还又不少高级功能, 这个须要本身慢慢的研究了. 特别关于负载均衡, 反向代理等其余不少有意思的高级功能能够慢慢去玩了. 本篇就到此为止了.
相关文章
相关标签/搜索