apache下的rewrite实例一则

蚊子前几天上线了个页面,程序员做的时候是把动态页面和静态页面分离开的放在了两个目录,同时呢,所用域名下又没有使用二级目录,目录结构是这样的

php文件:/data/webroot/php/cgi
html等静态文件:/data/webroot/html

访问情况是这样的(我用我自己的域名做举例):

d.wenzizone.cn/index.php或者d.wenzizone.cn—>/data/webroot/php/cgi/index.php
d.wenzizone.cn/index.html及所有静态文件 —>/ata/webroot/html
所有php的页面都 —>/data/webroot/php/cgi/

开发人员告诉我了这个结构之后,蚊子认为只能通过apache的url rewrite来实现了,apache的配置如下

<VirtualHost *:80>
    ServerAdmin webmaster@d.wenzizone.cn
    DocumentRoot /data0/webroot           #这里一定要设置到这级目录
    ServerName d.wenzizone.cn
    DirectoryIndex index.php
    ErrorLog logs/d.wenzizone.cn-error_log
    CustomLog logs/d.wenzizone.cn-access_log common
    <directory /data0/webroot>
        DirectoryIndex index.php
        rewriteengine on
        RewriteBase /      #将/data0/webroot设置为基准目录

        #将d.wenzizone.cn和d.wenzizone.cn/的访问转化成d.wenzizone.cn/index.php 

        rewritecond %{REQUEST_URI} ="" [OR]
        rewritecond %{REQUEST_URI} =/
        rewriterule ^(.*)$ index.php

        #将所有php的页面重定向到基准目录下的php/cgi目录下

        rewritecond %{REQUEST_FILENAME} !-f
        rewritecond %{REQUEST_FILENAME} \.php$
        rewriterule ^(.*)$ /php/cgi/$1 [L]

        #将所有非php的静态文件重定向到基准目录下的html目录下

        rewritecond %{REQUEST_FILENAME} !-f
        rewritecond %{REQUEST_URI} !\.php$
        rewriterule ^(.*)$ /html/$1 [L]
    </directory>

    #下面这两项是打开rewrite日志,当时蚊子为了调试打开了,成功之后关闭就好了,不然会增加apache负担
    #rewritelog /var/log/httpd/rewrite.log
    #RewriteLogLevel 3
</VirtualHost>

保存后重启apache就可以了。

另外补充一点的,对于上面这个需求来讲,在nginx下实现起来是非常容易的,下面蚊子也把nginx下的实现方式写出来

server {
    listen       80;
    server_name  d.wenzizone.cn;

    location = / {
        root /data1/webroot/php/cgi;
        index index.php;
    }

    location / {
        root /data1/webroot/html;
        index index.html index.htm;
        expires 30d;
    }

    location ~* \.php$ {
            root /data1/webroot/php/cgi;
            index index.php;
            fastcgi_pass   127.0.0.1:9000;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME          $document_root$uri;
            fastcgi_param  SCRIPT_NAME              $uri;
    }
}

对于蚊子的需求,基于apache如果哪位达人还有更好更简便的方法,还望告知,不胜感激

apache rewrite在per-server和per-dir两种模式下的效率对比[转]

虽说rewrite不 难,但有些细节可能不是每个人都清楚,比如说rewrite在per-server和per-dir两种配置下的效率,下面我们通过开启日志来判断到底哪 个效率好,在实验前请下做好相关配置,并编辑适当的测试文件a.html,b.html,每次测试后通过tail -f /usr/local/apache2/logs/rewrite.log来实时监控发生了什么。

先看per-server配置:

01 <VirtualHost *:80>
02     ServerName _default_
03
04     RewriteEngine on
05
06     RewriteLog /usr/local/apache2/logs/rewrite.log
07     RewriteLogLevel 9
08
09     # RewriteRule ^/a.html$ /usr/local/apache2/htdocs/b.html [L]
10     # RewriteRule ^/a.html$ /b.html
[L]
11 </VirtualHost>

规则:RewriteRule ^/a.html$ /usr/local/apache2/htdocs/b.html

日志:

init rewrite engine with requested uri /a.html
applying pattern ‘^/a.html

to uri ‘/a.html’
rewrite ‘/a.html’ -> ‘/usr/local/apache2/htdocs/b.html’
local path result: /usr/local/apache2/htdocs/b.html
go-ahead with /usr/local/apache2/htdocs/b.html [OK]

规则:RewriteRule ^/a.html$ /b.html

日志:

init rewrite engine with requested uri /a.html
applying pattern ‘^/a.html

to uri ‘/a.html’
rewrite ‘/a.html’ -> ‘/b.html’
local path result: /b.html
prefixed with document_root to /usr/local/apache2/htdocs/b.html
go-ahead with /usr/local/apache2/htdocs/b.html [OK]

再看per-dir配置:

01 <Directory “/usr/local/apache2/htdocs”>
02     RewriteEngine on
03
04     RewriteLog
/usr/local/apache2/logs/rewrite.log
05     RewriteLogLevel 9
06
07     # RewriteRule ^a.html$ /usr/local/apache2/htdocs/b.html
[L]
08     # RewriteRule ^a.html$ /b.html [L]
09     # RewriteRule ^a.html$ b.html [L]
10 </Directory>

规则:RewriteRule ^a.html$ /usr/local/apache2/htdocs/b.html

日志:

strip per-dir prefix: /usr/local/apache2/htdocs/a.html -> a.html
applying pattern ‘^a.html

to uri ‘a.html’
rewrite ‘a.html’ -> ‘/usr/local/apache2/htdocs/b.html’
strip document_root prefix: /usr/local/apache2/htdocs/b.html -> /b.html
internal redirect with /b.html [INTERNAL REDIRECT]
strip per-dir prefix: /usr/local/apache2/htdocs/b.html -> b.html
applying pattern ‘^a.html

to uri ‘b.html’
pass through /usr/local/apache2/htdocs/b.html

规则:RewriteRule ^a.html$ /b.html

日志:

strip per-dir prefix: /usr/local/apache2/htdocs/a.html -> a.html
applying pattern ‘^a.html

to uri ‘a.html’
rewrite ‘a.html’ -> ‘/b.html’
internal redirect with /b.html [INTERNAL REDIRECT]
strip per-dir prefix: /usr/local/apache2/htdocs/b.html -> b.html
applying pattern ‘^a.html

to uri ‘b.html’
pass through /usr/local/apache2/htdocs/b.html

规则:RewriteRule ^a.html$ b.html

日志:

strip per-dir prefix: /usr/local/apache2/htdocs/a.html -> a.html
applying pattern ‘^a.html

to uri ‘a.html’
rewrite ‘a.html’ -> ‘b.html’
add per-dir prefix: b.html -> /usr/local/apache2/htdocs/b.html
strip document_root prefix: /usr/local/apache2/htdocs/b.html -> /b.html
internal redirect with /b.html [INTERNAL REDIRECT]
strip per-dir prefix: /usr/local/apache2/htdocs/b.html -> b.html
applying pattern ‘^a.html

to uri ‘b.html’
pass through /usr/local/apache2/htdocs/b.html

即便简单通过日志的行数,我们也能看到per-server的效率高于per-dir,仔细查看日志,会发现当在per-dir配置下使用rewrite 时,系统会发生一次“INTERNAL REDIRECT”,所以以后写rewrite时,除非必要,否则不要使用pre-dir配置,而应尽可能使用per-server配置,至于是使用 file路径,还是url路径,差别不大,不过url路径的看上去更短些,也更好维护一些。

原文出自:http://hi.baidu.com/thinkinginlamp/blog/item/ff49972b9d267bf1e6cd4019.html

nginx学习–在url最后补全/符号[原创]

今天自己在nginx环境下配置了一个wordpress,用来在实际的应用中学习nginx,不料,却遇到了个小问题,先把文件解决办法总结如下。

我设置了一个域名:http://www.wenzi.cn/
我的wordpress地址是:http://www.wenzi.cn/wordpress/

现在的问题就是如果我访问http://www.wenzi.cn/wordpress/就可以显示出我的blog的地址,但如果我访问http://www.wenzi.cn/wordpress结果却提示说找不到所需要的页面。群里问了一下,说是,nginx不会自动在请求的最后加上一个/的,原因是nginx不会自动判断请求的是一个文件还是一个目录,google上可以搜到解决办法,于是乎我就去google了一下,确实找到了

在配置文件中location里加入如下代码

if (-d $request_filename){
    rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}

这样再对http://www.wenzi.cn/wordpress请求,nginx就会进行判断了,如果请求的是一个文件夹,会自动在最后加上/符号,如果请求的是一个文件,则不会改变原有url

接下来对这段代码进行一个解释

1,if (-d $request_filename),如果请求的是一个文件夹,则为真,进到if语句中执行
2,rewrite是执行url重写操作
3,^/(.*)([^/])$表示以/符号开始并紧跟着任何字符,同时不是以/为结束的字符串,在我的url中,(.*)表示的wordpres,([^/])表示的s
4,http://$host/$1$2/ 表示的重写后的地址,$host是请求的域名,$1是前面第一个括号里的内容,在我的url里就是wordpres $2是前面第二个括号里的内容,在我的url里是s
5,permanent表示,返回值是301