【问题标题】:Redirect "ugly" URL to new URL using htaccess使用 htaccess 将“丑陋”的 URL 重定向到新的 URL
【发布时间】:2019-10-15 21:25:05
【问题描述】:

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

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]

它正在工作。

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

【问题讨论】:

    标签: regex apache .htaccess mod-rewrite


    【解决方案1】:
    Redirect 301 /oldurl.htm /newurl.htm
    

    根据您的需要更改旧网址和新网址。希望对你有帮助

    【讨论】:

    • 我的代码:RewriteEngine On RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L] Redirect 302 /ppd-brands/generic/?gen_id=Mjky /ppd-brands/generic/gen_id/Mjky
    • RewriteEngine On RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L, R=301]
    • 您提供的代码正在运行,但是当我访问新网址时,它只会在旧网址中重定向。反之亦然无效。
    • RewriteEngine On RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [R=301, L]
    • 您不能使用 mod_alias Redirect 来执行这种类型的重定向。 1) 您不能使用Redirect 来获取查询字符串URL 参数,这在此处是必需的。 2) 由于现有的重写,您可能需要一个 条件 来防止重定向循环。 Redirect 不允许您创建条件 - 您需要为此使用 mod_rewrite。
    【解决方案2】:
    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]
    

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

    旁白: 由于我们更改了上述重写以在重写的 URL 中包含 index.php,这似乎与旧的“​​丑陋” URL 不同,我们或许可以通过简单的重定向来摆脱困境如果您使用的是 Apache 2.4(但 Apache 2.2 会导致冲突,因为 mod_dir 会为 index.php 发出内部子请求之前我们可以使用 mod_rewrite 处理 URL)。

    我们只需要重定向初始请求,而不是我们已经重写的请求。我们可以通过检查REDIRECT_STATUS 环境变量来做到这一点,该变量在初始请求中为empty,并在第一次成功重写后设置为“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 pattern 匹配的 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 中捕获组的反向引用(而不是 $1,它引用 RewriteRule 模式),即。 gen_id URL 参数的值。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-18
      • 2022-06-11
      • 1970-01-01
      相关资源
      最近更新 更多