没有R标志的RewriteRule for root不起作用

我正在试图做一个caching系统的文件。 而我正在考虑使用国防部重写服务caching的文件,如果它存在,或PHP文件(这将创buildHTML静态caching),如果没有。

这是我想出的第一个样本

<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^$ /cache/home.html [L,NC] RewriteCond %{REQUEST_URI} /cache/ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^cache/home.html /index.php [L] RewriteRule ^page/([0-9]*) /cache/page_$1.html [L,NC] RewriteCond %{REQUEST_URI} /cache/ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^cache/page_([0-9]*).html /page.php?&id=$1 [L] </IfModule> 

这适用于内部页面。 如果我打电话给http://www.example.site/page/1或http://www.example.site/page/2它正确地服务caching的文件或php页取决于文件是否存在。

问题是它不适用于主站点http://www.example.site

如果我为家庭添加一个redirect标志,它实际上工作正常

 RewriteRule ^$ /cache/home.html [L,NC,R] 

但是,很显然,在这种情况下,如果我打电话给主站点,并且服务于http://www.example.site/cache/home.html这不是我正在寻找的。

这里有几行日志,其中的问题可能是:

 [Wed Aug 05 11:59:11.751277 2015] [rewrite:trace1] [pid 30670] mod_rewrite.c(468): [client 10.1.1.1:53595] 10.1.1.1 - - [m.site.com/sid#7f7850ecb038][rid#7f7850e480a0/initial] [perdir /home/www/site.com/public/mobile/] internal redirect with /cache/home.html [INTERNAL REDIRECT] [Wed Aug 05 11:59:11.751339 2015] [rewrite:trace3] [pid 30670] mod_rewrite.c(468): [client 10.1.1.1:53595] 10.1.1.1 - - [m.site.com/sid#7f7850ecb038][rid#7f7850e420a0/subreq] [perdir /home/www/site.com/public/mobile/] strip per-dir prefix: /home/www/site.com/public/mobile/index.html -> index.html 

而与R标志

 [Wed Aug 05 12:04:34.333591 2015] [rewrite:trace1] [pid 31746] mod_rewrite.c(468): [client 10.1.1.1:53613] 10.1.1.1 - - [m.site.com/sid#7f7850ec1038][rid#7f7850e440a0/initial] [perdir /home/www/site.com/public/mobile/] redirect to http://m.cmstest.site.com/cache/home.html [REDIRECT/302] [Wed Aug 05 12:04:34.343609 2015] [rewrite:trace3] [pid 31746] mod_rewrite.c(468): [client 10.1.1.1:53613] 10.1.1.1 - - [m.site.com/sid#7f7850ec1038][rid#7f7850e420a0/initial] [perdir /home/www/site.com/public/mobile/] strip per-dir prefix: /home/www/site.com/public/mobile/cache/home.html -> cache/home.html 

看来,第一个没有R标志,做了正确的INTERNAL REDIRECTcaching/ home.html之后,去寻找index.html(这实际上并不存在)

你的第一条规则是:

 RewriteRule ^$ /cache/home.html [L,NC] 

L标志告诉mod_rewrite在那一刻停止处理,这是你所问的问题。 “R”解决方法意味着新的规则被重写为预期的,在第二个请求,但L阻止它的第一个。 此外, NC标志在这里是冗余的,因为不会有path字符受到区分大小写的影响。

虽然不是你的问题的一部分,也重新考虑以下几点。

 RewriteRule ^cache/home.html /index.php [L] 

您可能希望与^cache/page.html$匹配,以便它不接受cache/home.htmlxyz ,实际影响可能是最小的。 也有规则:

 RewriteRule ^page/([0-9]*) /cache/page_$1.html [L,NC] 

旗帜可能不像以前那样。 NC旗实际上在这里做了一些事情,但我认为这是不可取的。 还要考虑在你的正则expression式中的数字序列可以是零长度,我怀疑是不可取的,所以也许你想([0-9]+) ? 你可能也想用'$'来终止,因为目前你会匹配eg /page/foobar ,而且你也不想匹配/page/123foobar 。 所以你会有:

 RewriteRule ^page/([0-9]+)$ /cache/page_$1.html 

编辑:

请参阅以下有关匹配^$可能无法为您工作的注释。 此外,如果修复不起作用,请尝试添加mod_rewrite:trace3到您的LogLevel指令,并确切地找出错误的地方。 输出结果是冗长的,但是你会学到很多东西,如果你仍然感到困惑,那么你会有更多的细节来回馈给我们。

这个问题似乎与子请求,就像在这个答案: https : //stackoverflow.com/questions/9618865/mod-rewrite-mysterious-subreq

从日志中可以看出,在第一次正确的内部redirect之后,第二次调用是尝试在根目录中查找index.html的子请求。

我已经尝试添加选项-MultiViews在我链接的答案,但仍然无法正常工作。 阿帕奇在网站根目录下的请求中仍然很生气。

所以我结束了一个小的“黑客”解决scheme,将检查请求是否是一个子请求,在这种情况下,如果它正在寻找一个index.*文件在根将redirect到/cache/home.html

  RewriteCond %{IS_SUBREQ} t RewriteCond %{REQUEST_URI} ^(/index.\w+|/)?$ RewriteRule ^ /cache/home.html [L] 

这工作得很好,从某种意义上来说,这正是我所要做的。

我会让这个问题开放一段时间,因为这仍然是一个“黑客”解决scheme。 不知道是否有一个更好的应该直接阻止这些subrequests。