首页 > 解决方案 > 使用 htaccess 将“丑陋”的 URL 重定向到新的 URL

问题描述

我已经重写了旧的“丑陋”网址:

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]

它正在工作。

现在我的问题是当用户访问旧的“丑陋”网址时,如何将旧的“丑陋”网址重定向到新网址?

标签: regexapache.htaccessmod-rewrite

解决方案


RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]

只是一个前兆......虽然你的旧“丑陋” URL 是 form /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]

现在,您的主要问题......从旧的“丑陋”网址外部重定向到新网址。在这种情况下,您需要小心重定向循环,因为如果我们只是重定向,那么上面的重写将在无限循环中再次重写它。Redirect出于这个原因,您不能使用 mod_alias (正如其他答案所暗示的那样)。(并且 mod_aliasRedirect也无法匹配查询字符串 - 另一个原因。)

另外:由于我们将上述重写更改为包含index.php在重写的 URL 中,这似乎与旧的“​​丑陋”URL 不同,如果您使用的是 Apache 2.4(但 Apache 2.2 会导致冲突,因为 mod_dir 会在我们使用 mod_rewrite 处理 URLindex.php 之前发出内部子请求)。

我们只需要重定向初始请求,而不是我们已经重写的请求。我们可以通过检查REDIRECT_STATUS环境变量来做到这一点,该变量在初始请求中为,并在第一次成功重写后设置为“200”(如200 OKHTTP 状态)。(另一种方法是检查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 路径明显不包括查询字符串。

index.php请求 URL 中的 是可选的,因此它匹配或/ppd-brands/generic/?gen_id=Mjky/ppd-brands/generic/index.php?gen_id=Mjky如果那是实际 URL)。

$1反向引用只是为了节省打字/重复。这将始终包含ppd-brands/generic指令匹配的时间。我们可以对“gen_id”做同样的事情,但这会使替换字符串看起来有点太神秘了。

%1反向引用(注意%前缀)是对最后匹配的CondPattern中捕获的组的反向引用(而不是$1引用RewriteRule 模式),即。gen_idURL 参数的值。

QSD标志(Apache 2.4+)从重定向的 URL 中去除查询字符串。否则gen_id=XYZ将被传递到目标 URL。如果您仍在使用 Apache 2.2,那么您需要将 a 附加?替换字符串的末尾(本质上是一个空查询字符串)。例如。/$1/gen_id/%1?

“魔术”实际上是检查环境变量的第一个条件REDIRECT_STATUS。如上所述,这确保了我们只处理初始请求而不是重写请求,从而避免了重定向循环。

请注意,这目前是 302(临时)重定向。只有在测试后才更改为 301(永久),这可以正常工作。301 由浏览器持久缓存,因此可能会使测试出现问题。

只是为了澄清......只有在您已经更改了应用程序中的所有 URL 后,才应该实施这样的重定向。这个重定向只是简单地重定向搜索引擎、反向链接和任何应该手动输入 URL 的人(不太可能)。


推荐阅读