【问题标题】:apache - rewritten URL gets redirected wrongapache - 重写的 URL 被重定向错误
【发布时间】:2013-08-18 14:28:10
【问题描述】:

我遇到了重定向/重写规则的问题。
这是我的 htaccess 文件http://pastebin.com/KJKFGgiH

上下文

我想在我已经在线的网站上使用重写的 url。

我想要的是

当有人请求 /main.php(旧 URL)时,我希望他重定向到 /en/(新 URL),然后 apache 将 main.php?lang=en 的结果发送给他(由于第 7 行的重写规则)。另外,我不希望用户看到/main.php URL,这就是为什么我没有使用重写规则而不是重定向。 (见后)

实际发生的是

  1. 当我要求 /main.php 页面时
  2. apache 将我的浏览器重定向到/en/
  3. 当它收到我的 /en/ 请求时,它会将 URl 重写为 /main.php?lang=en(这是预期的行为)
  4. 那么 apache 可以停止并处理 /main.php?lang=en 请求,但是不,它会将 URL 拆分为 /main.phpargs=lang=en,并尝试重写和重定向它拥有的新 URL(即 /main.php
  5. 当它找到“redirect /main.php /en/”行时,它会应用它,并将/main.php替换为/en/
  6. 然后它再次收集 url,给出/en/?lang=en
  7. 它将我的浏览器重定向到错误的 URL

这里是错误日志,你可以按照我刚刚给出的解释(我建议你下载它并用notepad++或任何没有自动换行符的软件打开它):http://pastebin.com/Z9q2pry6

解决办法是什么

Apache 只需应用一次重定向指令。

我尝试了 1 号解决方案:使用 'if'

我想我可以尝试将 htaccess 修改为:

RewriteRule    ^([a-z]{2})/$     /main.php?lang=$1    [L,E=no_more_redirect:1]

<If "env('no_more_redirect')   != 1">
Redirect 301   /main.php        /en/
</If>

-> 它应该如何工作并解决我的问题:

  1. 当 apache 收到我的 /main.php 请求时,它会应用重定向
  2. 当它收到我的/en/请求时,它会将url重写为/main.php?=lang=en,并将no_more_redirect设置为1
  3. 当它尝试应用所有规则和重定向指令时,它不再应用“Redirect 301 /main.php /en/”。
  4. 它处理/main.php?lang=en 请求。
  5. 耶!但它不起作用。 x(

这是我在尝试使用此解决方案到达/main.php 时收到的错误日志:啊,我不能发布超过 2 个链接,因为我的声誉少于 10 个,但是 这基本上是发生了什么:

  1. 它得到了我的/main.php 请求
  2. 它将我重定向到/en/
  3. 它将/en/ 重写为/main.php?lang=en 并将no_more_redirect 设置为1
  4. 但是当它检查条件时,它应该给出 0 时给出 1,然后第二次应用重定向。 失败。

问题是,我真的不知道&lt;if&gt; 标记的语法,而且文档(参见此处:不能发布超过2 个链接:c)也不是很清楚。另外,我真的不知道环境变量和服务器变量之间的区别,我在互联网上看到过一些像&lt;if %{name_of_variable}&lt;if env('name_of_variable')这样的东西,我不知道哪个是一个,以及如何使用他们等等...

另外,你必须知道我在每次尝试之间都会清除浏览器的缓存,否则它的行为会很奇怪。

我尝试了 2 号解决方案:REQUEST_URL

我尝试使用包含给定 URL 的 %{REQUEST_URI}(请参阅此处:再次我不能发布超过 2 个链接...),例如

<if "%{REQUEST_URI} != '/en/'">
Redirect 301   /main.php        /en/
</If>

但是发生的情况是,当 apache 收到 /en/ 请求并检查 &lt;if&gt; 条件时,它给出 0(这是预期的行为),但是当 apache 将 /en/ 重写为 /main.php?lang=en 并尝试应用时重写规则和重定向指令,%{REQUEST_URI} 发生变化,当 apache 检查条件 &lt;if&gt; 条件时,它给出 1,而 /main.php/en/ 替换,给出 /en/?lang=en再次失败。

我尝试了 number3 的解决方案:IS_SUBREQ

在寻找解决方案时,我在这里读到:(不能发布超过两个链接:c),如果正在处理的请求是子请求(为一个可以正常工作的模块)。我想,当 apache 将 /main.php?lang=en 拆分为 /main.phpargs=lang=en 以尝试应用规则和指令时,我想,这一定是一个子请求。所以我尝试了:

<If "%{IS_SUBREQ} != 'true'">
Redirect 301 /main.php  /en/
</If>

但实际上,即使在 URL 拆分之后,IS_SUBREQ 也永远不会为 false,并且表达式的评估(当它检查 if 条件时)总是给出 1。因此,这个解决方案是 失败强>.

这就是我在这里发布问题的原因。 感谢您阅读这么长的帖子。

【问题讨论】:

    标签: apache redirect url-rewriting conditional-statements


    【解决方案1】:

    事实上,我的问题是隐藏另一个问题,真正的问题是这里的循环问题,但是由于 args 循环在它的第一个(但一个太多)话语中停止。我不得不搜索“重写规则重定向循环”,在这里我很快找到了答案:.htaccess redirect loop when Redirect and RewriteRule together。 要将此解决方案应用于我的问题,我必须使用 rewrite_mod 进行 301 重定向,并在其上设置 RewriteCond %{ENV:REDIRECT_STATUS} !200。问题是,我仍然不知道这是如何工作的。确实如此,但我不知道为什么。当 /en/ URL 被重写时,为什么 REDIRECT_STATUS 会变为 200?但我想这里不是问这个问题的地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2017-01-26
      • 1970-01-01
      • 2011-01-26
      • 2014-04-16
      相关资源
      最近更新 更多