使用Apache的模块:rewrite模块语法格式

Preface

不管是对于搜索引擎仍是对于访客而言,不少网站程序生成的URL并不友好,因此须要将URL以更简短的方式来重写。这种技术能够解决不少常见的问题,如:页面伪静态域名重定向等。URL重写并不是只有Apache的rewrite模块能作到,ISAPI也能够实现。但ISAPI只能用于Wndows,国内不少虚拟空间都只支持ISAPI2,功能较弱。rewrite模块的强大在于,他能够用正则来实时重写URL请求,一个规则能够拥有不少子规则、附加条件。javascript

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

php

EXAMPLE 1

RewriteEngine on
RewriteCond $1 !(index\.php|images)
RewriteRule ^(.*)$ /index.php?page=$1 [L]

  • RewriteEngine on:开启Rewritecss

  • RewriteCond $1 !(index\.php|images):若是文件不为index.php或目录不为images。html

  • RewriteRule ^(.*)$ /index.php?page=$1:转给index.php处理。java

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

    设置以后,当访问dmyz.org/about时,实际是访问dmyz.org/index.php?page=about,从url中省略掉了index.php。这一规则常常用于框架开发环境,由于大多数框架都是将全部的请求提交给一个入口文件(一般是index.php)来处理的。浏览器

    将第三行修改:bash

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

  • 访问dmyz.org/about.htm时实际访问的仍然是dmyz.org/index.php?page=about,这就实现简单的伪静态了。服务器

    EXAMPLE 2

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

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

    %{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跳转。

    还有其余颇有用的标识,能够参考Apache手册


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

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

  • Related Posts

相关文章
相关标签/搜索