gpt4 book ai didi

.htaccess - 为什么这会导致无限请求循环?

转载 作者:行者123 更新时间:2023-12-04 20:21:55 24 4
gpt4 key购买 nike

今天早些时候,我正在帮助一个 .htaccess 的人。用例,以及 came up with a solution这有效,但我自己无法弄清楚!

他希望能够:

  • 浏览到 index.php?id=3&cat=5
  • 查看地址栏阅读 index/3/5/
  • 提供来自 index.php?id=3&cat=5 的内容

  • 最后两步是相当典型的(通常来自用户首先输入 index/3/5),但第一步是必需的,因为他的站点中仍然有一些旧格式的链接,无论出于何种原因,都无法更改他们。所以他需要支持这两种 URL 格式,并且让用户最终总是看到经过美化处理的格式。

    经过一番折腾,我们想出了以下 .htaccess文件:
    RewriteEngine on

    # Prevents browser looping, which does seem
    # to occur in some specific scenarios. Can't
    # explain the mechanics of this problem in
    # detail, but there we go.
    RewriteCond %{ENV:REDIRECT_STATUS} 200
    RewriteRule .* - [L]

    # Hard-rewrite ("[R]") to "friendly" URL.
    # Needs RewriteCond to match original querystring.
    # Uses "?" in target to remove original querystring,
    # and "%n" backrefs to move its components.
    # Target must be a full path as it's a hard-rewrite.
    RewriteCond %{QUERY_STRING} ^id=(\d+)&cat=(\d+)$
    RewriteRule ^index\.php$ http://example.com/index/%1/%2/? [L,R]

    # Soft-rewrite from "friendly" URL to "real" URL.
    # Transparent to browser.
    RewriteRule ^index/(\d+)/(\d+)/$ /index.php?id=$1&cat=$2

    虽然它可能看起来是一个有点奇怪的用例(“为什么不首先使用正确的链接?”,你可能会问),就随它去吧。不管最初的要求是什么,这就是场景,它让我发疯。

    没有第一条规则,客户端进入请求循环,试图 GET /index/X/Y/反复获得 302每一次。支票在 REDIRECT_STATUS使一切顺利进行。但我会认为在最终规则之后,不会再提供更多规则,客户端不会再提出任何请求(注意,没有 [R]),一切都会变得很糟糕。

    那么......为什么当我取出第一条规则时会导致请求循环?

    最佳答案

    无法修改您的设置,我不能肯定地说,但我相信这个问题是由于 mod_rewrite 的以下相对神秘的功能:

    When you manipulate a URL/filename in per-directory context mod_rewrite first rewrites the filename back to its corresponding URL (which is usually impossible, but see the RewriteBase directive below for the trick to achieve this) and then initiates a new internal sub-request with the new URL. This restarts processing of the API phases.



    (来源: mod_rewrite technical documentation,我强烈推荐阅读本文)

    换句话说,当您使用 RewriteRule 时在 .htaccess文件,新的、重写的 URL 可能映射到文件系统上一个完全不同的目录,在这种情况下 .htaccess原始目录中的文件将不再适用。所以每当一个 RewriteRule.htaccess文件匹配请求,Apache 必须使用修改后的 URL 从头开始​​重新开始处理。这意味着,除其他外,每个 RewriteRule再次被检查。

    在您的情况下,发生的情况是您访问 /index/X/Y/从浏览器。您的 .htaccess 中的最后一条规则文件触发器,将其重写为 /index.php?id=X&cat=Y ,因此 Apache 必须使用 URL /index.php?id=X&cat=Y 创建一个新的内部子请求.这与您之前的外部重定向规则匹配,因此 Apache 将 302 响应发送回浏览器以将其重定向到 /index/X/Y/ .但请记住,浏览器从未见过该内部子请求;据它所知,它已经在 /index/X/Y/ .因此,在您看来,您好像是从 /index/X/Y/ 重定向过来的。到同一个 URL,触发无限循环。

    除了性能下降之外,这可能是您应该避免在 .htaccess 中放置重写规则的更好原因之一。可能的文件。如果将这些规则移动到主服务器配置中,则不会出现此问题,因为规则上的匹配不会触发内部子请求。如果您无权访问主服务器配置文件,则可以绕过它的一种方法(编辑:或者我认为,虽然它似乎不起作用 - 请参阅评论)是添加 [NS] (无子请求)标志到您的外部重定向规则,
    RewriteRule ^index\.php$ http://example.com/index/%1/%2/? [L,R,NS]

    一旦你这样做了,你应该不再需要检查 REDIRECT_STATUS 的第一条规则。 .

    关于.htaccess - 为什么这会导致无限请求循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5574442/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com