Apache 使用 Rewrite 模块伪静态语法格式

发布于 2019-04-07 20:31:11 字数 4493 浏览 2394 评论 0

无论是对于搜索引擎还是对于访客而言,很多网站程序生成的 URL 并不友好,所以需要将 URL 以更简短的方式来重写。这种技术可以解决很多常见的问题,如页面伪静态,域名重定向等。URL 重写并非只有 Apache 的rewrite 模块能做到,ISAPI 也可以实现。但 ISAPI 只能用于Wndows,国内很多虚拟空间都只支持 ISAPI2 功能较弱。

rewrite 模块的强大在于,他可以用正则来实时重写 URL 请求,一个规则可以拥有很多子规则、附加条件。

下图是有一条重写条件的重写规则,可以看出 Rewrite 最基本的格式:重写条件(RewriteCond)是字符串在前,正则在后;重写规则(RewriteRule)是正则在前,字符串在后。本文将从几个简单例子出发,说明一些常用的 Rewrite 的语法,并解决具体的问题。

EXAMPLE 1

ewriteEngine on
RewriteCond $1 !(index\.php|images)
RewriteRule ^(.*)$ /index.php?page=$1 [L]
  • RewriteEngine on:开启Rewrite
  • RewriteCond $1 !(index\.php|images):如果文件不为index.php或目录不为images。
  • RewriteRule ^(.*)$ /index.php?page=$1:转给index.php处理。

$1 代表引用 RewriteRule 中的第一个正则 (.*) 代表的字符。RewriteCond 中的正则很普通,所以不做说明。RewriteRule 中的正则,(.*) 代表任意字符,^ 是开始锚,$ 是结束锚。

设置之后,当访问 wenjiangs.com/about 时,实际是访问 wenjiangs.com/index.php?page=about,从 url 中省略掉了 index.php。这一规则经常用于框架开发环境,因为大多数框架都是将所有的请求提交给一个入口文件(通常是index.php)来处理的。

将第三行修改:

RewriteRule ^(.*)\.htm$ /index.php?page=$1

访问 wenjiangs.com/about.htm 时实际访问的仍然是 wenjiangs.com/index.php?page=about,这就实现简单的伪静态了。

EXAMPLE 2

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /404.htm

用这个简单的例子来说明重写条件(RewriteCond)使用的服务器变量和特殊正则。

%{REQUEST_FILENAME} 获得一个服务器变量的值,!-f 是正则,其中感叹号表否定,-f 用来检测当前值所代表的路径是否是一个常规文件。因此例2实现的是:当访问的文件不是一个常规文件时,转到404.htm页面。这就是一个简单的用 Rewrite 实现 404 页面重定向的例子。还可以补充一下,将其修改为:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
#如果当前变量所代表的路径不是一个常规目录
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /404.htm

服务器变量有很多,常用的如下表:

服务器变量用途参考
%{HTTP_USER_AGENT}访客的浏览器类型Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8GTB7.1
%{HTTP_REFERER}访问的链接地址http://dmyz.org/archives/99
%{HTTP_FORWARDED}通过HTTP获得地址,通常是访客的IP地址,但HTTP头可以修改,所以如果要判断访客的IP,推荐使用%{REMOTE_ADDR}192.168.0.1
%{HTTP_HOST}访问的域名http://dmyz.org
%{SERVER_ADDR}服务器的IP地址127.0.0.1
%{REMOTE_ADDR}访客IP地址192.168.0.1
%{REMOTE_USER}只在HTTP验证中有用,保存验证时使用的用户名admin
%{REQUEST_METHOD}提交查询的方式GET或是POST
%{SCRIPT_FILENAME}所访问的文件的绝对路径/var/www/dmyz.org/htdocs/index.php
%{QUERY_STRING}查询字符串,包含查询变量名和参数page=1&name=dmyz
%{TIME_YEAR}/%{TIME_MON}/%{TIME_DAY}获取年/月/日2010/09/30

EXAMPLE 3

RewriteEngine on
RewriteCond %{QUERY_STRING} ^pageid\=(.*)?$ [NC]
RewriteRule ^index(.*)$ http://dmyz.org/thread.php\?fid=%1 [R=301,L]

本例中使用了配置指令,和重写规则对重写条件的引用。

如例2所说,重写条件可以使用服务器变量和特殊正则,但重写规则不可以。所以需要在重写规则中反向引用重写条件的内容。例3中使用 %1 来反向引用 (.*)?。当查询字符串为 pageid=任意字符串 时,跳转到 thread.php?fid=任意字符串。这条正则很适合网站搬家、更换程序后,将原地址转向到新地址。

前两个例子,重写条件和重写规则都只有两个参数——正则和字符串,本例中追加第三个参数,它被称为标识,跟在重写条件和重写规则之后的,作为辅助、补充之用。本例中使用了最简单三个标识:

  1. [NC]:忽略大小写。
  2. [L]:结尾标识。停止重写操作,并不再应用其他重写规则。防止本条规则被后续规则影响。
  3. [R=301]:利用HTTP 301跳转。

附:最近遇到的几个问题,虽然使用了 .htaccess 文件,但并未使用 rewrite,一并写在这里。设置了 Expires headers,关闭了 Etag,开启了 WordPress 的 Gzip 压缩。设置之后本站 Yslow 等级为 A。

# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
 
# BEGIN Gzip
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css image/gif image/jpeg image/png application/x-javascript
# END Gzip
 
# BEGIN Etag
FileETag none
# END Etag
 
# BEGIN Expires headers
Header set Expires "Thu, 15 Oct 2010 20:00:00 GMT"
# END Expires headers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84935 人气
更多

推荐作者

淹不死的鱼

文章 0 评论 0

zhangMack

文章 0 评论 0

爱的故事

文章 0 评论 0

linces

文章 0 评论 0

早乙女

文章 0 评论 0

鸵鸟症

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击“接受”或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。