我有两个子域api.example.net
和www.example.net
。如果api.example.net
不以www.example.net
开头(例如REQUEST_URI
,/v1/
),我想从/v1/token
重定向到/v1/status/update
。
/etc/apache2/sites-enabled
中的配置文件是这样的。
<VirtualHost *:443>
ServerName api.example.net
DocumentRoot /var/www
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/v1/
RewriteRule (.*) http://www.example.net%{REQUEST_URI} [R=301,L]
<Directory /var/www>
Options Indexes FollowSymLinks Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
但是当我尝试
时petra@petra-laptop:~$ curl -XGET -k 'https://api.example.net/test'
它返回了
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.example.net/test">here</a>.</p>
<hr>
<address>Apache/2.2.22 (Ubuntu) Server at api.example.net Port 443</address>
</body></html>
这就是我的预期。
但是当我尝试
时petra@petra-laptop:~$ curl -XGET -k 'https://api.example.net/v1/token'
它返回了
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.example.net/index.php">here</a>.</p>
<hr>
<address>Apache/2.2.22 (Ubuntu) Server at api.example.net Port 443</address>
</body></html>
我预计它会传递给https://api.example.net/v1/token
。
我在这里尝试了代码http://htaccess.madewithlove.be/,它返回了我的预期。
我做错了什么?
更新
该项目正在使用Yii Framework,因此在/var/www
内部有.htaccess
个文件。
RewriteEngine on
RewriteBase /
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
答案 0 :(得分:2)
我假设您的框架需要处理令牌(换句话说:.htaccess
中的规则必须匹配)。
我猜测(但不是100%肯定),在下一次传递期间,网址再次与虚拟主机中的规则匹配。因为网址是index.php
而不是v1/token
,所以虚拟主机中的规则匹配。要确保规则仅匹配原始网址(请求中的网址),请改用%{THE_REQUEST}
。
<VirtualHost *:443>
ServerName api.example.net
DocumentRoot /var/www
RewriteEngine On
RewriteCond %{THE_REQUEST} !^(GET|POST)\ /v1/
RewriteRule ^ http://www.example.net%{REQUEST_URI} [R=301,L]
<Directory /var/www>
Options Indexes FollowSymLinks Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
因为这是在主配置文件中,所以您必须重新启动Apache才能使更改生效。
答案 1 :(得分:1)
请你试试那个(我希望我没有遗漏一些东西):
RewriteCond %{HTTP_HOST} ^api\.example\.net$ [NC]
RewriteCond %{REQUEST_URI} !^v1/
RewriteRule (.*) http://www.example.net/$1 [R=301,L]
如果将其放在vhost中,则可能必须重新启动Apache才能使更改生效。
如果你把它放在.htaccess文件中(你至少可以把它放在测试中),你应该把它放在“RewriteCond%{REQUEST_FILENAME}!-f”之前。
编辑:我想我明白了! 你会说它不起作用(再次),因为你正在测试一个不指向文件或目录的URL(!!!),然后当文件/目录没有如果存在,请求将再次重定向到index.php。
我在一个子域+另一个安装了WP的域上进行了测试,看起来该文件不存在我正被重定向到主域(安装和配置WP的地方)。当我使用现有文件时,重定向工作正常!
如果它不起作用,你有没有选择在另一台服务器或同一台服务器上测试它,但是使用另一个文档根目录,你只需要上面的重写来测试它们与其他服务器分开规则?
让我知道结果是什么!
答案 2 :(得分:-1)
我错过了你的错误,你做错了!^ / v1 /
应该是! ^ / V1 /:
<VirtualHost *:443>
ServerName api.example.net
DocumentRoot /var/www
RewriteEngine On
RewriteCond %{REQUEST_URI} ! ^/v1/:
RewriteRule (.*) http://www.example.net%{REQUEST_URI} [R=301,L]
<Directory /var/www>
Options Indexes FollowSymLinks Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>