Regex 重定向";“丑陋的”;使用htaccess指向新URL的URL

Regex 重定向";“丑陋的”;使用htaccess指向新URL的URL,regex,apache,.htaccess,mod-rewrite,Regex,Apache,.htaccess,Mod Rewrite,我已经重写了我以前的“丑陋”URL: 到 使用下面的代码 RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L] 它正在工作 现在我的问题是,当用户访问旧的“丑陋”URL时,如何将旧的“丑陋”URL重定向到新的URL 根据需要更改新旧URL。希望对你有帮助 只是一个先兆。。。虽然旧的“丑陋”URL的格式是/ppd brands/generic/?gen_id=Mjky,但理想情况下,您

我已经重写了我以前的“丑陋”URL:

使用下面的代码

RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]
它正在工作

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

根据需要更改新旧URL。希望对你有帮助

只是一个先兆。。。虽然旧的“丑陋”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_别名
重定向
(如另一个答案所示)。(mod_别名
重定向
也无法匹配查询字符串-另一个原因。)

旁白:由于我们将上述重写更改为在重写的URL中包含
index.php
,这似乎不同于旧的“丑陋”URL,如果您使用的是Apache2.4,我们可能只需简单重定向即可(但是Apache2.2会导致冲突,因为mod_dir会在使用mod_rewrite处理URL之前发出
index.php
的内部子请求)

我们只需要重定向初始请求,而不是我们已经重写的请求。我们可以通过检查
redirect\u STATUS
环境变量来做到这一点,该变量在初始请求中为空,并在第一次成功重写后设置为“200”(如
200 OK
HTTP STATUS)。(另一种方法是检查_请求的
,而不是动态/可重写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\u 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”执行相同的操作,但这可能会使替代字符串看起来有点太神秘

%1
反向引用(注意
%
前缀)是对最后匹配的CondPattern中捕获的组的反向引用(与
$1
相反,后者指的是
重写规则
模式),即
gen_id
URL参数的值

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

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

请注意,这目前是一个302(临时)重定向。只有在测试完成后才更改为301(永久)重定向。浏览器会永久缓存301s,因此可能会导致测试出现问题


我只是想澄清一下……只有在您已经更改了应用程序中的所有URL后,才应该执行这样的重定向。此重定向只是重定向搜索引擎、反向链接和任何应该手动键入URL的人(不太可能)。

my code:
RewriteRule上的RewriteEngine^ppd brands/generic/gen_id/([^/]*)$/ppd brands/generic/?gen\u id=$1[L]重定向302/ppd brands/generic/?gen\u id=Mjky/ppd brands/generic/gen\u id/Mjky
重写引擎规则^ppd brands/generic/gen\u id/([^/]*)$/ppd brands/generic/?gen\u id=$1[L,R=301]您提供的代码正在工作,但当我访问新url时,它仅在旧url中重定向。反之亦然。RewriteEngine On RewriteRule ^ppd brands/generic/gen_id/([^/]*)$/ppd brands/generic/?gen_id=$1[R=301,L]您不能使用mod_别名
重定向
执行此类重定向。1)您无法使用此处所需的
重定向获取查询字符串URL参数。2)由于存在重写,您可能需要一个条件来防止重定向循环<代码>重定向
不允许您创建条件-您需要为此使用mod_rewrite。
Redirect 301 /oldurl.htm /newurl.htm
RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]
RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/index.php?gen_id=$1 [L]
# 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]