为什么 Apache2 mod_cache 提供目录索引而不是 index.php?

Why is Apache2 mod_cache serving a directory index instead of index.php?

我在 DigitalOcean Droplet 上安装了多站点 WordPress 运行。我添加了 Apache 的 mod_cache 模块来缓存我网站的内容,但我 运行 遇到了一个非常奇怪的问题。在我设置缓存后的第一页加载中,网站加载正常。但是,在随后的页面加载中,我得到的是目录索引,而不是 index.php 被调用:

如果我清除缓存,下一页就可以正常工作。似乎 mod_cache 正在缓存目录索引 HTML 页面而不是 index.php.

的渲染输出

这是我的站点配置:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName jeremydormitzer.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/jeremydormitzer.com

    ErrorLog /var/log/jeremydormitzer.com/error.log
    CustomLog /var/log/jeremydormitzer.com/access.log combined

    <Directory /var/www/html/jeremydormitzer.com/>
        AllowOverride All
    </Directory>

    RewriteEngine on

    LoadModule cache_module modules/mod_cache.so
    <IfModule mod_cache.c>
        LoadModule cache_disk_module modules/mod_cache_disk.so
        <IfModule mod_cache_disk.c>
            CacheEnable disk /
            CacheDisable /wp-admin
        </IfModule>
        CacheLock on
        CacheLockPath "/tmp/mod_cache-lock"
        CacheLockMaxAge 5
        CacheDisable "http://security.update.server/update-list/"
    </IfModule>

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/qa.getpterotype.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/qa.getpterotype.com/privkey.pem
</VirtualHost>
</IfModule>

这是我的 cache_disk.conf:

<IfModule mod_cache_disk.c>
    CacheRoot /var/cache/apache2/mod_cache_disk
    CacheDirLevels 2
    CacheDirLength 1
</IfModule>

这是我的 apache2.conf:

Mutex file:${APACHE_LOCK_DIR} default    
PidFile ${APACHE_PID_FILE}
Timeout 300    
KeepAlive On    
MaxKeepAliveRequests 100    
KeepAliveTimeout 5   
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}    
HostnameLookups Off    
ErrorLog ${APACHE_LOG_DIR}/error.log    
LogLevel warn

IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf    
Include ports.conf

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/html>
    AllowOverride All
</Directory>

AccessFileName .htaccess

<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

IncludeOptional conf-enabled/*.conf    
IncludeOptional sites-enabled/*.conf

ServerName 104.236.87.208    
UseCanonicalName On

有人知道这是怎么回事吗?


更新

根据要求,这是我网站根路径 .htaccess 的内容:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

不确定,但当我看到这里时 https://httpd.apache.org/docs/2.2/mod/mod_cache.html 该示例有 mod_disk_cache 而您的代码似乎有 mod_cache_disk?

我想通了。有两个:

问题 1

mod_cache 在服务器处理管道中 运行 太早了。这意味着它在调用 PHP 脚本之前缓存内容,导致它缓存目录索引。为了解决这个问题,我在配置文件中关闭了 CacheQuickHandler

CacheQuickHandler off

问题 2

我的 .htaccess 文件(由 WordPress 自动生成)正在将所有 URI 重写为 /index.php:

RewriteRule . /index.php [L]

这导致每个页面都被缓存为 index.php,这意味着无论何时您访问我网站上的一个页面,Apache 都会提供上次访问的页面。

更改它以将 URI 重写为 index.php/<the path> 解决了这个问题:

RewriteRule ^(.*)$ /index.php/ [L]

感谢 this ServerFault answer 为我指明了正确的方向。