在httpd.conf中,对某个主机进行以下操作:
<VirtualHost ip:80>
??????? rewriteengine on
??????? rewritecond %{HTTP_HOST} [^.]+\.域名\.com$
??????? rewriterule ^(.+) %{HTTP_HOST}$1 [C]
??????? rewriterule ([^.]+)\.域名\.com(.*) /$1$2
??????? 其他配置文件
</VirtualHost>
接着在DNS中开设一个泛解析到对应的IP地址。
就可以实现下面的方案。
域名:domain.com
绝对路径:/home/domain.com/
www.domain.com 自动解析到 /home/domain.com/www/
abc.domain.com 自动解析到 /home/domain.com/abc/
等等子域名都可以自动解析到 /home/domains.com/对应子域名名称的文件夹
直接建立子域名名称的文件夹即可使用。不需重启apache。
泛域名解析就是将客户的域名全部解析到同一个IP地址。
例如客户的域名a.com,之下所设的*.a.com全部解析到同一个IP地址上去。
比如客户设b.a.com就会自已自动解析到与a.com同一个IP地址上去。
泛域名是指 * IN A?? 123.123.123.123 或 *?? IN CNAME www.aaa.com
泛域名解析的用途:
1.可以让域名支持无限的子域名(这也是泛域名解析最大的用途)。
2.防止用户错误输入导致的网站不能访问的问题。
在DNS服务器里面设置泛域名解析有2种方式
1. 在域名解析里面设置 *.a.com的A记录或者CName 记录指向某一个IP/服务器名(这种方式 虚拟主机用户是不支持的)
2. 在域名转发里面设置 *.a.com 转发到 http://www.a.com( 虚拟主机可以支持这种转发方式,用户在自己的程序中可以判断访问者要访问的域名),我们会在程序技术文档里面讲解
例子二:
http://www.chhua.com/klein/blog/article_321.html
实现动态二级域名解析的一个关键就是,把特有的名字怎么能够提出来,因为RewriteRule中的匹配,是不包括域名的匹配的,其实这其中就是一层窗户 纸,把域名先重写放到“路径”中,再对“路径”重写一次就可以了,也就是说加一步过渡。这样说大概还一头雾水,给个实例。
首先按我上次写的文章的那个需求写一个,假设动态解析*.iecn.cn。
注意要先做一个所谓的范域名解析,就是说把所有*.iecn.cn解析到某个IP上去,这不是本文章讨论范围就不细说了。
Apache中相关配置如下:
<VirtualHost _default_:80>
ServerAdmin yourmail@domain.com
DocumentRoot /YourWwwRoot/.default
ServerName all-sites
ErrorLog logs/all-sites-error_log
CustomLog logs/all-sites-access_log common
# 下面三行实现动态解析
RewriteCond %{HTTP_HOST} ^[a-z0-9\-]+\.iecn\.cn$
RewriteRule ^/(.*)$ /%{SERVER_NAME}/$1 ##注##
RewriteRule ^/([a-z0-9\-]+)\.iecn\.cn/(.*)$ /YourWwwRoot/$1/$2 [L]
# 没有解析到的情况下扔到自己的一个PHP中做一下处理
RewriteRule ^.*$ /index.php [L]
</VirtualHost>
注意我标注的地方,那一步就是一个过渡,说一下过程吧,假设现在访问:
http://zhong.chhua.com/xxx
经第一步重写,变成 /zhong.chhua.com/xxx
经第二步重写就是 /YourWwwRoot/zhong/xxx 了,其他的操作与我行前说的基本就差不多了。
再举一个可能更常见的实例,假设一个博客系统,要求把
http://xxx.chhua.com隐式的重写成
http://blog.iecn.cn/blog.php?u=xxx
这里面的xxx可以看做是一个用户名,想必类似这样的需求大家一定都见过很多了,不过多解释了。
同意先做范域名解析这里不多说。在Apache中做如下重写(只写Rewrite部分了):
RewriteCond %{HTTP_HOST} ^[a-z0-9\-]+\.iecn\.cn$
RewriteRule ^/?$ /%{HTTP_HOST}
RewriteRule ^/([a-z0-9\-]+)\.iecn\.cn/?$ /blog.php?u=$1 [L]
zz from http://blog.chhua.com/blog.php?do=showone&tid=1013
Apache下用rewrite实现任意域名的动态解析
Apache的mod_rewrite模块功能非常强大,我以后会写更多的实例出来。
关于mod_rewrite的使用,不想多说,提供两个相关文档的地址:
http://w.yi.org/ftp/FAPM/apache/Apache2/zh/mod/mod_rewrite.html
http://man.chhua.com/newsoft/Apache2.2_chinese_manual/mod/mod_rewrite.html
如果你只是想用一个现成的你可以直接把我的copy过去改改,如果想从技术上搞清楚,那么首先要掌握两方面的技术:
Apache下mod_rewrite的使用(可参照我上面提供的两个地址)
正则表达式(这是一门在很多地方都非常有用的技术)
废话不多说,说一下我在IECN.NET服务器的实际配置。
我习惯使用NameVirtualHost,如果你的服务器中只想用这种动态的解析,直接在配置文件中做是一样的,如果想保留自己一些特殊站点的配置,还是用NameVirtualHost吧。
在Apache中,如果启用了NameVirtualHost,在没有匹配到的解析的情况下,会默认到第一组VirtualHost中,所以我们的动态解析自然是放到第一组VirtualHost(有关apache的一些配置这里就不多说,自己查阅相关文档。),如下:
<VirtualHost _default_:80>
??? ServerAdmin yourmail@domain.com
??? DocumentRoot /YourWwwRoot/.default
??? ServerName all-sites
??? ErrorLog logs/all-sites-error_log
??? CustomLog logs/all-sites-access_log common
??? # 下面两行实现动态解析
??? RewriteCond /YourWwwRoot/%{SERVER_NAME} -d
??? RewriteRule ^/(.*)$ /YourWwwRoot/%{SERVER_NAME}/$1 [L]
??? # 没有解析到的情况下扔到自己的一个PHP中做一下处理
??? RewriteRule ^.*$ /index.php [L]
</VirtualHost>
把YourWwwRoot换成你自己的路径,注意这里的ServerName没有让它起作用,关建看这两行:
RewriteCond /YourWwwRoot/%{SERVER_NAME} -d
RewriteRule ^/(.*)$ /YourWwwRoot/%{SERVER_NAME}/$1 [L]
第一行是一个rewrite条件,这里的条件是:如果存在路径/YourWwwRoot/%{SERVER_NAME},%{SERVER_NAME}就是你访问站点的域名,-d就表示存在这个路径的意思(如果是文件则是-f);
第二行是一个rewrite规则,这个规则执行的前提是:符合规则的正则表达式匹配;符合它前面(也就是刚才说的第一行)rewrite条件。这里面是的 匹配的是.*,也就是所有了,也就是说只要第一行的条件成立,它就会被重写到/YourWwwRoot/%{SERVER_NAME}/$1,% {SERVER_NAME}是站点的域名,$1则是匹配到的.*。
OK,现在就很清楚了,假设现在有www.domain.com指向到这个服务器,当你访问它时(这里假设没有在其他VirtualHost解析这个域名),看看它是如何工作的:
首先它在没有找到匹配的解析时,就来到了这组默认的VirtualHost;
判断 /YourWwwRoot/www.domain.com 是否存在;
如果存在,重定向到 /YourWwwRoot/www.domain.com。
假设你访问 http://www.domain.com/test.html,就会重定向到系统的 /YourWwwRoot/www.domain.com/test.html。
那也就是说你在 YourWwwRoot 下建一个与域名同名的目录(并具备apache访问的权限),就实现了这个域名的解析。
说起来似乎有点难懂,其实很简单的。
这是一个对任意域名的动态解析,哪天有空再写一下对同一域名下二级域名的解析,其实对这个略做改动就可以了。
评论