从.htaccess恢复缓存的文件


Recover a cached file from .htaccess

我在一个简单的缓存系统中工作,该系统由php生成,并由apache .htaccess响应(在实际服务器中由nginx响应)。

PHP使用public/cache/post/35/my-first-post.html 等文件将缓存文件创建到public/cache/

VirtualHost对所有项目来说都是通用的,在开发过程中,我们没有为每个项目提供VirtualHost:

<VirtualHost *:80>
    DocumentRoot /var/www
    <Directory /var/www>
        Options -Indexes
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

位于/var/www/projects/current-project/public/.htaccess中的.htaccess应该检测到该缓存文件并将其返回。

DirectoryIndex index.php
<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    RewriteCond cache/$1.html -f
    RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Url为http://localhost/projects/current-project/public/post/35/my-first-post但是生产服务器http://domain.com/post/35/my-first-post

并重写日志:

[Sun May 08 13:55:11.236124 2016] [rewrite:trace4] [pid 3189] mod_rewrite.c(476): [client 127.0.0.1:43494] 127.0.0.1 - - [localhost/sid#7f2d26745ae0][rid#7f2d2668e0a0/initial] [perdir /var/www/projects/current-project/public/] RewriteCond: input='cache/post/1/my-first-post.html' pattern='-f' => not-matched

文件perdir /var/www/projects/current-project/public/+input='cache/post/1/my-first-post.html'=/var/www/projects/current-project/public/cache/post/1/my-first-post.html存在。

我不想设置RewriteBase,因为它对每个开发环境都是动态的。

如何从当前.htaccess文件夹中检测缓存文件?

工作nginx版本

set $cachefile "";
if ($uri ~ ^[a-z0-9/-]+$) {
    set $cachefile "/cache/$uri.html";
}
if ($uri = "/") {
    set $cachefile "/cache/index.html";
}
location / {
    try_files $cachefile $uri $uri/ /index.php?$query_string;
}

工作解决方案感谢@Sumurai8:

DirectoryIndex index.php
<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]
    # No request: index cache
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond $1#%{REQUEST_FILENAME} ^/?#(.*/public)/
    RewriteCond %1/cache/index.html -f
    RewriteRule ^$ cache/index.html [L,NC]
    # Request: page
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond $1#%{REQUEST_FILENAME} ^([a-z0-9/-]+)#(.*/public)/
    RewriteCond %2/cache/%1.html -f
    RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L,NC]
    # Catch all script and cache generator
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

谢谢。

-f和其他类似的检查适用于文件名,而不是URL。您应该首先在%{REQUEST_FILENAME}上进行匹配,然后构造自己的文件名。

RewriteCond $1#%{REQUEST_FILENAME} ^([a-z0-9/-]+)#(.*/public)/
RewriteCond %2/cache/%1.html -f
RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L]

$1是规则的第一个捕获组,它包含缓存文件的后一部分。在第二个条件中,%2是前一个条件的第二个捕获组。它包含文档根+当前前缀。)

或者,您可以盲目地重写缓存,如果缓存不存在,则再次重写:

RewriteCond %{REQUEST_URI} !^/cache/
RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

在您的情况下,index.php需要识别缓存url,这可能会很麻烦。