Mod 重写未按预期重定向
Mod Rewrite not redirecting as expected
我有重写规则重定向到 www 和重写规则重定向到 ssl。这是我想要的设置,一切正常,除非我添加了这个新条件:
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
如果该条件为真,我不希望 ssl 重定向发生。我看到的问题是,当我这样做时,整个 url 重定向到 https://www.example.com/index.php?query=string
即使对于其他所有页面,正常行为也能正常工作。 URI 保持不变,但 index.php 为 运行。下面是我的 htaccess 文件:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
我预期的行为是有人在 url http://www.example.com/new-review?query=string 中键入并且此页面 运行 是 index.php 上的代码,而没有将用户 uri 切换到 index.php.我只是想不通为什么最后一个重写规则:
RewriteRule . index.php
除一种情况外,其他所有情况均符合预期行为。我想要的只是让这一页作为非 ssl 页面工作,但仍然通过 index.php.
运行
重写引擎将循环直到 URI 停止更改。当你请求 /new-review
时会发生什么,它不匹配任何重定向规则,然后它匹配最后一个规则并被应用,因此 /new-review
被重写为 /index.php
。现在,重写引擎循环,并应用新的 URI。这次,您的第二条规则与 URI (/index.php
) 匹配,因此被重定向。如果您不希望 index.php 被重定向,那么您需要阻止所有循环,或者添加一个直通:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
或
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteRule ^(index\.php)?$ - [L]
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
重要的技巧是在您的条件下使用 THE_REQUEST
变量而不是 REQUEST_URI
。 THE_REQUEST
变量表示 Apache 从您的浏览器收到的原始请求,在执行一些重写规则后它不会被覆盖。
所以你可以使用:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{THE_REQUEST} !^\s/new-review [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
我有重写规则重定向到 www 和重写规则重定向到 ssl。这是我想要的设置,一切正常,除非我添加了这个新条件:
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
如果该条件为真,我不希望 ssl 重定向发生。我看到的问题是,当我这样做时,整个 url 重定向到 https://www.example.com/index.php?query=string
即使对于其他所有页面,正常行为也能正常工作。 URI 保持不变,但 index.php 为 运行。下面是我的 htaccess 文件:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
我预期的行为是有人在 url http://www.example.com/new-review?query=string 中键入并且此页面 运行 是 index.php 上的代码,而没有将用户 uri 切换到 index.php.我只是想不通为什么最后一个重写规则:
RewriteRule . index.php
除一种情况外,其他所有情况均符合预期行为。我想要的只是让这一页作为非 ssl 页面工作,但仍然通过 index.php.
运行重写引擎将循环直到 URI 停止更改。当你请求 /new-review
时会发生什么,它不匹配任何重定向规则,然后它匹配最后一个规则并被应用,因此 /new-review
被重写为 /index.php
。现在,重写引擎循环,并应用新的 URI。这次,您的第二条规则与 URI (/index.php
) 匹配,因此被重定向。如果您不希望 index.php 被重定向,那么您需要阻止所有循环,或者添加一个直通:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
或
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteRule ^(index\.php)?$ - [L]
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
重要的技巧是在您的条件下使用 THE_REQUEST
变量而不是 REQUEST_URI
。 THE_REQUEST
变量表示 Apache 从您的浏览器收到的原始请求,在执行一些重写规则后它不会被覆盖。
所以你可以使用:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
RewriteCond %{THE_REQUEST} !^\s/new-review [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]