我有这个文件夹结构:
/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.html
example.com/content/page3/a
example.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(永久)重定向(如果这是意图)。