现在我们了解一下 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我们这篇日志专门讲解: RewriteBaseRewriteBase 的作用域为: 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 报错.
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 报错.