apache手册中rewrite功能中RewriteRule的疑问[已解决]
本帖最后由 abcfy2 于 2013-04-18 16:26 编辑虚拟用户主机
描述:
如果需要为用户username支持一个www.username.host.domain.com的主页,但不在此机器上建虚拟主机,而是仅用在此机器上增加一个DNS A记录的方法实现。
解决方案:
仅能对包含"Host: "头的HTTP/1.1请求实现。可以使用以下规则集内部地将http://www.username.host.com/anypath重写为/home/username/anypath
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.[^.]+\.host\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1
RewriteRule ^www\.([^.]+)\.host\.com(.*) /home/$1$2
apache的手册中的内容,
RewriteRule ^(.+) %{HTTP_HOST}$1 这句怎么理解呢?
一直不能理解为什么要加这一句,而且测试过如果没有这一句下一句的跳转不成立,没效果。
另外问一下手册中怎么翻查apache的内建变量呢?至今只是自己测试+瞎猜知道有个%{HTTP_HOST}这个变量,用于获取URL中的域名部分,其他变量在哪查?具体的含义呢?
还想知道这些正则表达式的具体用法在apache手册怎么查到呢?翻遍了也没找到一个系统的教程,目前只知道()内的字符正则可以被$1,$2...$N来依序匹配获得 本帖最后由 tzb12qaqa 于 2013-04-17 10:12 编辑
是为了与下一条规则捆绑,当相应的RewriteRule匹配时,则继续下一条RewriteRule ,否则下一条将被忽略。
另外 RewriteRule 第一个正则表达式是不匹配域名的
The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").
RewriteRule ^(.+) %{HTTP_HOST}$1
是为了将域名加入到被匹配字符中去
请参考
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
http://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_c
#变量名列表 (如果不了解变量名的含义,试着从HTTP协议入手)
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond 回复 2# tzb12qaqa
我知道C是代表chain,当前匹配才会继续下一条重写规则,但是不明白为什么RewriteRule ^(.+) %{HTTP_HOST}$1
^代表开始,"."代表任意单个字符,+代表"."至少匹配一次,那么这样写不就是匹配完整的URL请求么?比如http://www.a.com不就完整的匹配了这条规则?后面又重写成了www.a.comhttp://www.a.com??
还是意味着加上^代表匹配Location /以下的请求?这样的话这条重写岂不是没有任何的意义?仅仅是为了检查/下面还有没有附加别的请求? 本帖最后由 abcfy2 于 2013-04-18 13:49 编辑
回复 2# tzb12qaqa
仔细回味了一下,好像是这么个意思,RewriteRule是从/请求下面匹配的,这样就不能匹配到URL了,所以进行了重写,加上了%{HTTP_HOST}来进行下一条规则的重写。
我现在有这样的需求,前端用apache,后端用tomcat,做了一个apache+tomcat的反向代理整合,特殊需求如下:
1,要求用户强制使用https安全协议访问网站,也就是加不加https都强制跳转443端口的https协议
2,要求用户空主机头访问跳转到www主机头,也就是用户访问fy.com的时候跳转到www.fy.com
3,用户的目录在www.fy.com/username下,用户可以用自己的用户名代替主机头访问,如user1.fy.com实际访问的是www.fy.com/user1,用户感觉不到URL的变化,让用户感觉到类似于自己主页的效果。
4,用户自己将自己的域名访问也可以,比如www.user1.com,实际访问www.fy.com/user1
我根据需求写了如下的配置:
#80端口强制跳转443端口
<VirtualHost *:80>
RewriteEngine On
RewriteRule ^(.+)$ https://%{HTTP_HOST}$1
</VirtualHost>
<VirtualHost *:443>
Options +FollowSymLinks
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
#空主机头显式跳转www主机头,如fy.com跳转到https://www.fy.com
RewriteCond %{HTTP_HOST} ^fy.com$
RewriteRule ^/(.*) https://www.fy.com/$1
#对于主机头不是www的,跳转为https://www.fy.com/$1$2
RewriteCond %{HTTP_HOST} !^www.fy.com$
RewriteRule ^(.+)$ %{HTTP_HOST}$1
RewriteRule ^(.+)\.fy\.com(.*)$ https://www.fy.com/$1$2
#对于域名不是*.fy.com的,跳转为https://www.fy.com/$1$2
RewriteCond %{HTTP_HOST} !^.*\.fy\.com$
RewriteRule ^www\.(.*)\.com(.*) https://www.fy.com/$1$2
# ServerName fengyu.com
ProxyRequests Off
SSLEngine On
SSLCertificateFile /etc/ssl/private/apache.pem
# SSLCertificateKeyFile /etc/apache2/server.key
SSLProxyEngine off
ProxyPass / http://127.0.0.1:8080/temp/
ProxyPassReverse / http://127.0.0.1:8080/temp/
</VirtualHost>
现在问题就来了,为什么访问test.fy.com的时候,URL会显示跳转为https://www.fy.com/test呢?这不是我想要的结果,我想要用户访问test.fy.com,实际显示的页面是www.fy.com/test,但是用户的URL依然是test.fy.com,用户感觉不到页面跳转。这个问题在哪呢?应该怎么改?我的RewriteRule明明没有加R啊,应该不会成为重定向才对啊。
而且www.test.com也会跳转为www.fy.com/test 本帖最后由 abcfy2 于 2013-04-19 17:24 编辑
回复 2# tzb12qaqa
多谢指导了,我又仔细研读了一下手册(金步国翻译的中文手册),发现用P代理就可以解决自己的问题,最终修改如下:#80端口强制跳转443端口
<VirtualHost *:80>
RewriteEngine On
RewriteRule ^(.+)$ https://%{HTTP_HOST}$1
</VirtualHost>
<VirtualHost *:443>
Options +FollowSymLinks
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteLogLevel 3 #这里可以去掉了,当时为了看rewrite调试过程的
RewriteLog ${APACHE_LOG_DIR}/rewrite.log #这里可以去掉了,当时为了看rewrite调试过程的
RewriteEngine on
#空主机头显式跳转www主机头,如fy.com跳转到https://www.fy.com
RewriteCond %{HTTP_HOST} ^fy.com$
RewriteRule ^/(.*) https://www.fy.com/$1 #R表示重定向,这样URL是显式的
#对于主机头不是www的进行反向代理,如test.fy.com会根据重写规则反向代理至http://127.0.0.1:8080/test
RewriteCond %{HTTP_HOST} !^www.fy.com$
RewriteRule ^(.+) %{HTTP_HOST}$1
RewriteRule ^(.+)\.fy\.com(.*)$ http://127.0.0.1:8080/temp/$1$2 #用P反向代理,这样URL是不会跳转的
#对于不是*.fy.com这种的访问,如www.test.com,进行反向代理,规则同上,没有加RewriteRule ^(.+) %{HTTP_HOST}$1 因为www.test.com已经匹配了RewriteCond %{HTTP_HOST} !^www.fy.com$这条规则,已经进行了一次RewriteRule ^(.+) %{HTTP_HOST}$1
RewriteCond %{HTTP_HOST} !^.*\.fy\.com$
RewriteRule ^www\.(.*)\.com(.*) http://127.0.0.1:8080/temp/$1$2 #用P反向代理,这样URL是不会跳转的
# ServerName fengyu.com
ProxyRequests Off
SSLEngine On
SSLCertificateFile /etc/ssl/private/apache.pem
# SSLCertificateKeyFile /etc/apache2/server.key
SSLProxyEngine off
ProxyPass / http://127.0.0.1:8080/temp/
ProxyPassReverse / http://127.0.0.1:8080/temp/
</VirtualHost>
本帖最后由 abcfy2 于 2013-04-18 16:20 编辑
还有一事不明 RewriteCond %{HTTP_HOST} !^www.fy.com$
RewriteRule ^(.+) %{HTTP_HOST}$1
RewriteRule ^(.+)\.fy\.com(.*)$ http://127.0.0.1:8080/temp/$1$2 #用P反向代理,这样URL是不会跳转的这段规则中必须加上RewriteRule ^(.+) %{HTTP_HOST}$1 才能正确访问到代理的地址http://127.0.0.1:8080/temp/test/index.jsp
但是这里 RewriteCond %{HTTP_HOST} !^.*\.fy\.com$
RewriteRule ^www\.(.*)\.com(.*) http://127.0.0.1:8080/temp/$1$2 #用P反向代理,这样URL是不会跳不能加上RewriteRule ^(.+) %{HTTP_HOST}$1 ,否则www.test.com返回错误是访问到了/temp/test.comwww.test/
这是为什么呢?
哦明白是咋回事了,www.test.com先匹配了RewriteCond %{HTTP_HOST} !^www.fy.com$这条规则,进行了一次重写RewriteRule ^(.+) %{HTTP_HOST}$1 ,而下面那条规则RewriteRule ^(.+)\.fy\.com(.*)$ http://127.0.0.1:8080/temp/$1$2 没有匹配到,所以跳过,进行下面的匹配,匹配到规则RewriteCond %{HTTP_HOST} !^.*\.fy\.com$,然后直接进行重写了 RewriteRule ^www\.(.*)\.com(.*) http://127.0.0.1:8080/temp/$1$2
页:
[1]