【问题标题】:Mod Rewrite not redirecting as expectedMod Rewrite 未按预期重定向
【发布时间】:2015-01-27 00:47:54
【问题描述】:

我有重定向到 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}/$1 [R=301,L]

RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [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 运行。

【问题讨论】:

  • 首先,您已经将非 www 版本重写为 HTTPS——在这种情况下,您的 RewriteCond for /new-review 来得太晚了。而且 RewriteCond 只会影响其后的 RewriteRule,因此您的最后一条规则不依赖于当前设置中对 !^/new-review?.* 的条件检查。
  • 但是假设他们输入的网址是“http://www example.com/new-review?query=string”,那么第一个条件将失败并且什么都不会发生,第二个条件应该失败只要文件或目录 new-review 不存在,什么都不会发生,并且第三个条件应该总是发生。似乎 index.php 的最后一个 RewriteRule 正在发送外部重定向,而不是仅在内部重写请求。

标签: .htaccess mod-rewrite


【解决方案1】:

重要的技巧是在你的情况下使用THE_REQUEST 变量而不是REQUEST_URI。 THE_REQUEST 变量表示 Apache 从您的浏览器收到的原始请求,在执行某些重写规则后它不会被覆盖。

所以你可以使用:

Options +FollowSymLinks -Indexes
RewriteEngine On

RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{THE_REQUEST} !^\s/new-review [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

【讨论】:

  • 接受这个作为答案,因为它很简单并且不需要对当前代码进行太多更改。乔恩的答案+1,因为他更好地解释了为什么会发生这种情况。谢谢你们!
【解决方案2】:

重写引擎将循环直到 URI 停止更改。当您请求/new-review 时会发生什么,它不匹配任何重定向规则,然后匹配最后一条规则并应用它,因此/new-review 被重写为/index.php。现在,重写引擎循环,并应用新的 URI。这一次,您的第二条规则与 URI (/index.php) 匹配,因此被重定向。如果您不希望 index.php 被重定向,那么您需要阻止所有循环,或者添加一个 passthrough:

Options +FollowSymLinks -Indexes

RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [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}/$1 [R=301,L]

RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

【讨论】:

  • 很好地解释了为什么会发生这种情况。我想我没有完全理解接下来的过程。你的回答对我前进非常有帮助。 +1
猜你喜欢
  • 2011-05-06
  • 2014-11-26
  • 2012-04-18
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 2015-01-14
  • 2020-07-04
相关资源
最近更新 更多