我已经重写了我的旧"丑陋"网址:
http://example.com/ppd-brands/generic/?gen_id=Mjky
自
http://example.com/ppd-brands/generic/gen_id/Mjky
使用以下代码
RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]
它正在起作用。
现在我的问题是,当用户访问旧的"丑陋"URL时,如何将旧的"丑陋"URL重定向到新URL?
RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]
只是一个前兆...虽然您旧的"丑陋"URL的形式是/ppd-brands/generic/?gen_id=Mjky
,但理想情况下,您应该重写为处理请求的实际文件,例如。index.php
,而不是允许mod_dir向目录索引发出额外的内部子请求 - 这就是我假设这里正在发生的事情。
例如:
RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/index.php?gen_id=$1 [L]
现在,您的主要问题...从外部从旧的"丑陋"URL重定向到新URL。在这种情况下,您需要小心重定向循环,因为如果我们只是重定向,那么上面的重写将在无限循环中再次重写它。出于这个原因,您不能使用mod_aliasRedirect
(如另一个答案所暗示的那样)。(mod_aliasRedirect
也无法匹配查询字符串 - 另一个原因。
旁白:由于我们更改了上述重写以在重写的URL中包含index.php
,这似乎与旧的"丑陋"URL不同,如果您使用的是Apache 2.4,我们也许可以通过简单的重定向(但是Apache 2.2会导致冲突,因为mod_dir会在我们处理mod_rewrite URL之前发出内部子请求index.php
)。
我们只需要重定向初始请求,而不是我们已经重写的请求。我们可以通过检查REDIRECT_STATUS
环境变量来做到这一点,该变量在初始请求中为空,并在第一次成功重写后设置为"200"(如200 OK
HTTP 状态)。(另一种方法是检查THE_REQUEST
,而不是动态/可重写的URL路径。
例如,在现有重写之前尝试以下操作:
# Redirect "old" to "new"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^gen_id=([^/&]*)
RewriteRule ^(ppd-brands/generic)/(?:index.php)?$ /$1/gen_id/%1 [QSD,R=302,L]
请注意,为了匹配查询字符串,我们需要一个条件(RewriteCond
指令)来检查QUERY_STRING
服务器变量。与RewriteRule
模式匹配的 URL 路径明显排除了查询字符串。
请求 URL 中的index.php
是可选的,因此它与/ppd-brands/generic/?gen_id=Mjky
或/ppd-brands/generic/index.php?gen_id=Mjky
匹配(如果这是实际 URL)。
$1
反向引用只是为了节省键入/重复。当指令匹配时,这将始终包含ppd-brands/generic
。我们本可以用"gen_id"做同样的事情,但这会使susbstitution字符串看起来有点太神秘了。
%1
反向引用(注意%
前缀)是对最后一个匹配的CondPattern中捕获的组的反向引用(与引用RewriteRule
模式的$1
相反),即gen_id
URL 参数的值。
QSD
标志 (Apache 2.4+) 从重定向的 URL 中删除查询字符串。否则,gen_id=XYZ
将传递到目标 URL。如果您仍在使用 Apache 2.2,则需要将?
附加到替换字符串的末尾(本质上是一个空查询字符串)。例如。/$1/gen_id/%1?
"魔术"实际上是检查REDIRECT_STATUS
环境变量的第一个条件。如上所述,这确保了我们只处理初始请求,而不处理重写的请求,从而避免重定向循环。
请注意,这目前是 302(临时)重定向。只有在测试后才更改为 301(永久),这工作正常。 301 由浏览器永久缓存,因此可能会使测试出现问题。
只是为了澄清...只有在更改了应用程序中的所有 URL 后,才应实现这样的重定向。此重定向只是简单地重定向搜索引擎,反向链接和任何应该手动输入URL的人(不太可能)。
Redirect 301 /oldurl.htm /newurl.htm
根据需要更改新旧URL。希望对您有所帮助