.htaccess-如果文件不存在,则重定向到父目录

时间:2019-05-06 08:06:30

标签: apache .htaccess

我在网站的某些页面上有amp版本,但对于某些页面-仅是普通版本。一般来说,结构是这样的:

\
\page1.htm
\page2.htm
...
\amp\
\amp\page1.htm

因此page1.htm具有amp版本,但是page2.htm-没有。 当用户检索\amp\page2.htm而不是404时,我想从根目录提供page2.htm

我尝试通过.htaccess进行重定向,但无法正常工作:

RewriteCond %{REQUEST_URI} ^/amp/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/amp/(.*)$ https://www.example.com/$1 [R=301,L]

此代码有什么问题?为什么我仍然得到404?

谢谢!

1 个答案:

答案 0 :(得分:1)

这是一个艰难的过程,突显了mod_rewrite的精妙之处。简短的答案是,有两种方法可以做到这一点:

RewriteCond %{REQUEST_URI} ^/amp/(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . https://www.example.com/%1 [R=301,L]

几个重要的区别:

  1. 我要在RewriteCond中而不是RewriteRule中捕获REQUEST_URI的尾部,然后使用PERCENT 1(%1)而不是DOLLAR 1($1)来引用它
  2. 我正在使用REQUEST_FILENAME来查看文件系统上是否存在文件,而不是DOCUMENT_ROOT / REQUEST_URI,因为REQUEST_URI可以是任何东西,并且可能与文件系统上的内容不符(如您的示例所示)。
  3. RewriteRule匹配所有内容(.而不是/amp/

或者您可以这样做:

RewriteBase /amp
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^amp(.*)$ $1 [R=301,L]

这两种不同方法的工作原理围绕着mod_rewrite官方文档(重点是我的)的引用:

  

请注意,mod_rewrite尝试通过检查路径的第一段是否位于以下位置来猜测您是指定了文件系统路径还是 URL路径文件系统的根目录。例如,如果您指定/www/file.html的替换字符串,那么除非根目录或文件系统中存在名为www的目录(或者使用重写的情况),否则它将被视为URL路径。 .htaccess文件中,相对于您的文档根目录),在这种情况下,它将被视为文件系统路径。

第一种方法将事物视为URL路径,而第二种方法将事物视为文件路径。

我猜第一种方法更符合您的需求,因为放大器解决方案通常是“生成的”(并且不能作为文件系统中的平面文件使用),因此,对于将输入作为URL路径而不是文件路径更感兴趣。

在您想到之前,“哇!人们如何将这些东西保留在他们的大脑中?”。我对mod_rewrite规则只有一个模糊的理解,实际上在撰写本文之前,必须重新阅读文档并运行一些测试以为自己弄清楚事情。

希望这会有所帮助。

一些参考网址:

相关问题