我有这个问题我还没弄明白,也许你可以帮我一把。
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot "/var/www/example.com/current/web/"
RewriteEngine On
RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 3
RewriteCond %{REQUEST_URI} !^/api/special/url/token
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
RewriteCond %{REQUEST_URI} !^/api/special/url/token
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
</VirtualHost>
这是我的VirtualHost配置,我需要将所有内容重定向到HTTPS协议,但一个特定的URL除外。
此VirtualHost规则正常运行。问题是,当进入带有.htaccess文件(来自Symfony2标准版)的DocumentRoot时,会产生一种奇怪的行为。这是.htaccess文件:
DirectoryIndex app.php
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
这是RewriteLog日志:
[example.com/sid#b740c280][rid#b62df058/initial] (2) init rewrite engine with requested uri /api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) applying pattern '(.*)' to uri '/api/special/url/token'
[example.com/sid#b740c280][rid#b62df058/initial] (3) applying pattern '(.*)' to uri '/api/special/url/token'
[example.com/sid#b740c280][rid#b62df058/initial] (1) pass through /api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] add path info postfix: /var/www/example.com/current/web/api -> /var/www/example.com/current/web/api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] strip per-dir prefix: /var/www/example.com/current/web/api/special/url/token -> api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] applying pattern '^(.*)' to uri 'api/special/url/token'
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] add path info postfix: /var/www/example.com/current/web/api -> /var/www/example.com/current/web/api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] strip per-dir prefix: /var/www/example.com/current/web/api/special/url/token -> api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] applying pattern '.?' to uri 'api/special/url/token'
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] add path info postfix: /var/www/example.com/current/web/api -> /var/www/example.com/current/web/api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] strip per-dir prefix: /var/www/example.com/current/web/api/special/url/token -> api/special/url/token
[example.com/sid#b740c280][rid#b62df058/initial] (3) [perdir /var/www/example.com/current/web/] applying pattern '.?' to uri 'api/special/url/token'
[example.com/sid#b740c280][rid#b62df058/initial] (2) [perdir /var/www/example.com/current/web/] rewrite 'api/special/url/token' -> '/app.php'
[example.com/sid#b740c280][rid#b62df058/initial] (1) [perdir /var/www/example.com/current/web/] internal redirect with /app.php [INTERNAL REDIRECT]
[example.com/sid#b740c280][rid#b6291310/initial/redir#1] (2) init rewrite engine with requested uri /app.php
[example.com/sid#b740c280][rid#b6291310/initial/redir#1] (3) applying pattern '(.*)' to uri '/app.php'
[example.com/sid#b740c280][rid#b6291310/initial/redir#1] (2) rewrite '/app.php' -> 'https://www.example.com/app.php'
[example.com/sid#b740c280][rid#b6291310/initial/redir#1] (2) explicitly forcing redirect with https://www.example.com/app.php
[example.com/sid#b740c280][rid#b6291310/initial/redir#1] (1) escaping https://www.example.com/app.php for redirect
[example.com/sid#b740c280][rid#b6291310/initial/redir#1] (1) redirect to https://www.example.com/app.php [REDIRECT/301]
预期的行为是,当匹配此特定URL时,它不会重定向到HTTPS URL,并且Symfony2前端控制器也会将请求作为正常URL处理。
提前致谢。
答案 0 :(得分:2)
我认为问题是第一个配置是在虚拟主机中,第二个是在文件夹中的.htaccess中,htaccess有优先级,让我们考虑一下这个结构
├──folder1
│ ├── .htaccess1
│ ├── folder2
│ │ ├── .htaccess2
│ │ ├── folder3
│ │ │ ├──.htaccess 3
.htaccess1
内的规则将被.htaccess2
覆盖,并且.htaccess3
内的选项都会覆盖这两个规则,最后一个优先级是virtualhost
内的选项自
所以我假设只有2个选项,要么将重写从virtualhost
级别移动到symfony .htaccess
文件中,要么尝试通过.htaccess
中的条件转义它们。等待他们冒泡回到virtualhost
以在那里应用规则。
我认为这样的组合.htaccess
可以解决问题
DirectoryIndex app.php
RewriteEngine On
# https redirections
RewriteCond %{REQUEST_URI} !^/api/special/url/token
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
RewriteCond %{REQUEST_URI} !^/api/special/url/token
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
# symfony2 rewriting
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
虽然我收到了评论,但我真的不明白你要做什么,你在www和非www之间来回重定向?
答案 1 :(得分:1)
问题是Symhony的前端控制器/app.php
也被重定向到HTTPS
,因为RewriteCond %{REQUEST_URI} !^/api/special/url/token
仍然成立。将VirtualHost
规则替换为:
RewriteCond %{REQUEST_URI} !^/(api/special/url/token|app\.php)
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
RewriteCond %{REQUEST_URI} !^/(api/special/url/token|app\.php)
RewriteCond %{HTTP_HOST} ^www\..+$ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
进行此更改后,请不要忘记重新启动Apache服务器。完成后,将停止对HTTPS的不需要的重定向。