如何使用 htaccess 从一个子文件夹重定向到另一个子子文件夹

如何使用 htaccess 从一个子文件夹重定向到另一个子子文件夹

我有这个文件夹结构:

/fonts
  /myfont.eot
  /myfont.svg
  /myfont.ttf
  /myfont.woff
  /myfont.woff2
/content
  /page1
    /files
      /logo.png
      /style.css
    /index.html
  /page2
    /files
      /logo.png
      /style.css
    /index.html
  /page3
    /files
      /logo.png
      /style.css
    /a
      /index.html
    /b
      /index.html
  ...

调用的 URL 如下所示:

  • example.com/content/page1
  • example.com/content/page2
  • example.com/content/page3/a
  • example.com/content/page3/b

现在我想要实现的是.htaccess,文件位于,/page3无论谁访问example.com/content/page3都会被正确重定向到example.com/content/page3/a(或者example.com/content/page3/a/index.html,我不介意文件名是否在 URL 中)。

我试过

DirectoryIndex /content/page3/a/index.html

但在这种情况下,当我打开文件时,由于 URL 中缺少目录级别,文件example.com/content/page3中的所有相对引用都已损坏。此外,虽然调用有效,但出现 403 Forbidden。/a/index.htmlexample.com/content/page3/aexample.com/content/page3/b

我试过

Redirect 301 /content/page3 /content/page3/a

但这显然会导致无休止的重定向螺旋,example.com/content/page3/a/a/a/a/a/a/......直到服务器停止尝试。

所以我认为我需要一些RedirectCond配置RedirectRule。不幸的是,我不懂语法,我看过的所有示例都是在顶层执行的,而且还有更复杂的东西,比如重定向文件和子文件夹,有时还会重定向到另一个域等。

我试过这个

RewriteEngine On

RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$
RewriteCond %{REQUEST_URI} ^/content/page3/$
RewriteRule ^/content/page3/?$ /content/page3/a [L]

因为我认为这会将“/content/page3”替换为“/content/page3/a”,但无济于事,它什么也没做。

我现在开始使用

DirectoryIndex /content/page3/a/index.html index.html

并将文档中的相对引用替换为绝对引用。这样就成功了。

但首先我仍然希望引用可以保持相对,这样如果page3文件夹被重命名,文档就不会中断;其次我宁愿/a在 URL 中包含子目录以清楚地显示内容。

我怎样才能实现这个目标?

答案1

我仍然希望引用可以保持相对

在这种情况下,你确实需要一个外部重定向,而不是内部重写或内部子请求(这实际上是您使用指令执行的操作DirectoryIndex)。如果您“更希望/a在 URL 中包含子目录”,那么您肯定需要外部重定向。

调用的 URL 如下所示:

  • example.com/content/page1
  • example.com/content/page2
  • example.com/content/page3/a
  • example.com/content/page3/b

我注意到,您没有在任何映射到物理目录的 URL 上添加尾部斜杠。这些 URL 应该包含尾部斜杠,以表示您要执行的操作,即链接到example.com/content/page1/,而不是example.com/content/page1。原因是 Apache (mod_dir) 会使用 301 重定向“修复”URL 以附加尾部斜杠。如果您确实想省略这些“目录”URL 上的尾部斜杠,那么您还有更多工作要做。

文件.htaccess位于/page3

使用 mod_rewrite 您可以执行以下操作:

RewriteEngine On
RewriteRule ^$ /content/page3/a/ [R,L]

这是一个临时 (302) 重定向。^$匹配一个空的 URL 路径。它是“空的”,因为它相对于当前目录。mod_dir 随后将发出 的子请求DirectoryIndex,即index.html

或者,使用 mod_alias RedirectMatch

RedirectMatch 302 ^/content/page3/?$ /content/page3/a/
RewriteRule ^/content/page3/?$ /content/page3/a [L]

这永远不会起作用,因为在目录上下文中(即.htaccess)匹配的 URL 路径RewriteRule 图案不以斜线开头。

如果你在根.htaccess文件中写了这个,它应该是:

RewriteEngine On
RewriteRule ^content/page3/?$ /content/page3/a/ [R,L]

前面两个条件不是必需的——除非您有多个域?

相应的 mod_alias 指令与上面的相同(无论文件.htaccess位于何处)。


DirectoryIndex简单设置为:

DirectoryIndex index.html

为了提供所index.html请求目录中的文档。


Redirect 301 /content/page3 /content/page3/a

这将创建一个重定向循环,因为 mod_aliasRedirect指令是字首匹配,匹配后的所有内容都附加到目标 URL 之后,即重定向的 URL/content/page3/a与源 URL 匹配/content/page3,并附/a加到目标的末尾 ( /content/page3/a) 成为/content/page3/a/a等等。

请注意,301(永久)重定向会被浏览器永久缓存。您需要清除浏览器缓存。始终使用 302(临时)重定向进行测试,并且只有在确认其正常运行后才更改为 301(永久)重定向(如果这是意图)。

相关内容