Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache 如果请求URI以某物开头,则重定向_Apache_.htaccess_Mod Rewrite - Fatal编程技术网

Apache 如果请求URI以某物开头,则重定向

Apache 如果请求URI以某物开头,则重定向,apache,.htaccess,mod-rewrite,Apache,.htaccess,Mod Rewrite,我有两个子域api.example.net和www.example.net。如果请求URI不是以/v1/开头(例如/v1/token,/v1/status/update),我想从api.example.net重定向到www.example.net) 我在/etc/apache2/sites enabled中的配置文件如下所示 <VirtualHost *:443> ServerName api.example.net DocumentRoot /var/www

我有两个子域
api.example.net
www.example.net
。如果
请求URI
不是以
/v1/
开头(例如
/v1/token
/v1/status/update
),我想从
api.example.net
重定向到
www.example.net

我在
/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>
它回来了

<!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>
<!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>
它回来了

<!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>
<!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>

我错过了你的错误,你错过了^/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>

ServerName api.example.net
DocumentRoot/var/www
重新启动发动机
重写cond%{REQUEST_URI}^/v1/:
重写规则(.*)http://www.example.net%{REQUEST_URI}[R=301,L]
选项索引和以下符号链接包括
允许超越所有
命令允许,拒绝
通融

我假设令牌需要由您的框架处理(或者换句话说,
.htaccess
中的规则必须匹配)

我猜测(但不是100%确定),在下一次传递过程中,url会再次与虚拟主机中的规则匹配。因为url是
index.php
而不是
v1/token
,所以virtualhost中的规则是匹配的。要确保规则仅与原始url(请求中的url)匹配,请改用
%{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>

ServerName api.example.net
DocumentRoot/var/www
重新启动发动机
重写cond%{THE_REQUEST}^(获取| POST)\/v1/
重写规则^http://www.example.net%{REQUEST_URI}[R=301,L]
选项索引和以下符号链接包括
允许超越所有
命令允许,拒绝
通融

因为这是在主配置文件中,所以您必须重新启动Apache才能使任何更改生效。

请您尝试一下(我希望我没有遗漏什么):

如果将其放在vhost中,则可能必须重新启动Apache才能使任何更改生效

如果您将它放在.htaccess文件中(您至少可以为测试这样做),那么应该将它放在“RewriteCond%{REQUEST_FILENAME}!-f”之前

编辑:我想我明白了您会说它不起作用(再次),因为您正在使用一个不指向文件或目录(!!!)的URL进行测试,然后当文件/目录不存在时,请求会再次重定向到index.php

我在一个子域+另一个安装了WP的域上进行了测试,如果文件不存在,我会被重定向到主域(安装并配置了WP)。当我使用现有的文件时,重定向就可以正常工作了

如果它不起作用,您是否可以选择在另一台服务器上或在同一台服务器上测试它,但使用另一个文档根,您只需进行上述重写,就可以将它们与其他现有规则分开进行测试


让我知道哪些是结果

您的系统中有.htaccess吗?您的意思是在目录
/var/www
中?是的,我喜欢。让我更新上面的
.htaccess
code。你的.htaccess文件中有
VirtualHost
条目吗?那部分,我真的不明白。我对Apache有点陌生。正如您在
.htaccess
中看到的那样,有
VirtualHost
标记。
VirtualHost
实际上甚至不允许在.htaccess中使用。您的意思是
RewriteCond%{REQUEST\u URI}^/v1/:
?使用此选项时,
https://api.example.net/v1/token
将转到
https://www.example.net/v1/token
而不是
https://www.example.net/index.php
<代码>https://api.example.net/test仍然转到
http://example.net/test
。如果我尝试
api.example.net/v1/test
,它将重定向到
www.example.net/v1/test
,则此操作无效。
<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>
RewriteCond %{HTTP_HOST} ^api\.example\.net$ [NC]
RewriteCond %{REQUEST_URI} !^v1/
RewriteRule (.*) http://www.example.net/$1 [R=301,L]