带变量的简单 301 重定向不起作用,为什么?

发布于 2024-12-10 14:53:17 字数 264 浏览 1 评论 0原文

这是我到目前为止所得到的。第一部分有效,但重定向本身无效。

我需要做什么才能让它发挥作用?

RewriteEngine On
RewriteRule ^([^/\.]+)/?$ page.php?name=$1 [L]

RewriteRule ^page.php?name=([^/\.]+)/?$ /$1  [R=301,L] 

另外,如果我有多个这些规则,我是否只将 [L] 保留在最后一个规则上?

Here's what I got so far. The first part works but not the redirect itself.

What do I need to do to make it work?

RewriteEngine On
RewriteRule ^([^/\.]+)/?$ page.php?name=$1 [L]

RewriteRule ^page.php?name=([^/\.]+)/?$ /$1  [R=301,L] 

Also if I have multiple of these rules do I leave the [L] only on the last one?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不气馁 2024-12-17 14:53:17

除了第一个规则覆盖第二个规则之外,第二个规则也不起作用,因为您试图匹配 RewriteRule 中的查询字符串。尝试这样的事情:(

RewriteEngine On
RewriteBase /

RewriteCond %{QUERY_STRING} ^name=([^/.&]+)/?$
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^page\.php$ /%1?  [NS,R=301,L]

RewriteRule ^([^/.]+)/?$ page.php?name=$1 [NS,QSA,E=LOOP:1]

我包括了 QSA 标志,这样像 /foobar?foo=bar 这样的 URL 将被重写为 /page.php?name=foobar&foo=bar 而不仅仅是/page.php?name=foobar。如果您不想这样做,请将其忽略。)


注意: 第二个 RewriteCond 就在那里。防止第一个规则在第二个规则匹配后再次匹配。问题是,在 .htaccess 上下文中,mod_rewrite 的行为或多或少就像所有规则都具有 PT 标志,导致规则集在每次重写后从头开始重新运行,甚至是内部重写。或者,引用文档

“如果您在 .htaccess 文件或部分中使用 RewriteRule,那么了解规则的处理方式非常重要。其简化形式是,一旦处理了规则,重写的请求被传回 URL 解析引擎以执行其可能的操作,在处理重写的请求时,可能会再次遇到 .htaccess 文件或部分。因此,如果其中一个规则导致重定向(无论是内部还是外部),则规则集可能会从头开始再次运行,从而导致请求过程重新开始。”

我使用的解决方法是在内部重写触发时使用 E=LOOP:1 设置自定义环境变量,并在执行外部重写之前检查它。请注意,当请求处理在内部重写后重新启动时,Apache 会将 REDIRECT_ 添加到上一次传递期间设置的所有环境变量的名称中,因此即使我们设置的变量仅命名为 LOOP,我们需要检查的是REDIRECT_LOOP

Besides the first rule overriding the second one, your second rule also won't work because you're trying to match the query string in a RewriteRule. Try something like this instead:

RewriteEngine On
RewriteBase /

RewriteCond %{QUERY_STRING} ^name=([^/.&]+)/?$
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^page\.php$ /%1?  [NS,R=301,L]

RewriteRule ^([^/.]+)/?$ page.php?name=$1 [NS,QSA,E=LOOP:1]

(I included the QSA flag so that an URL like /foobar?foo=bar will be rewritten to /page.php?name=foobar&foo=bar instead of just /page.php?name=foobar. If you don't want that, leave it out.)


Note: The second RewriteCond is there to keep the first rule from matching again after the second one has matched. The problem is that, in .htaccess context, mod_rewrite acts more or less as if all rules had the PT flag, causing the ruleset to be rerun from the start after every rewrite, even internal ones. Or, to quote the documentation:

"If you are using RewriteRule in either .htaccess files or in <Directory> sections, it is important to have some understanding of how the rules are processed. The simplified form of this is that once the rules have been processed, the rewritten request is handed back to the URL parsing engine to do what it may with it. It is possible that as the rewritten request is handled, the .htaccess file or <Directory> section may be encountered again, and thus the ruleset may be run again from the start. Most commonly this will happen if one of the rules causes a redirect - either internal or external - causing the request process to start over."

The workaround I'm using is to set a custom environment variable with E=LOOP:1 when the internal rewrite triggers, and check for it before doing the external rewrite. Note that, when the request processing restarts after the internal rewrite, Apache prepends REDIRECT_ to the names of all environment variables set during the previous pass, so even though the variable we set is named just LOOP, the one we need to check for is REDIRECT_LOOP.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文