Apache 使用它自己的 404 处理程序而不是 index.php 处理 .txt 文件

Apache uses it's own 404 handler instead of index.php for .txt files

我想通过 .php

处理对不存在文件的所有请求

.htaccess配置:

ErrorDocument 404 /index.php
DirectoryIndex index.php
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

这似乎大部分都有效,但一些特定的文件扩展名(.txt、.jpg,还有更多?)由 apache 处理,而不是通过 php。
http://localhost:8000/home -> 显示主页
http://localhost:8000/file.zip(不存在)-> 显示由 PHP

提供的自定义样式的 404 页面

http://localhost:8000/exists.txt(现有文件)-> 提供现有文件
http://localhost:8000/doesnotexist.txt(不存在)-> 显示默认的 apache 404 页面(与未安装 PHP 时相同)

是否有针对特定文件扩展名的默认 apache 处理程序?
如何设置所有请求以通过 index.php?

使用docker php 7.4 apache as my base image

我用 Docker 和 php 7.4-apache 映像复制了您的实验。当打开 url http://localhost:8000/doesnotexist.txt 时,我被转移到 index.php 文件,正如我所期望的那样。底部的三个重写规则会将所有内容重写为 index.php.

首先:您还没有 post编辑 docker-compose.ymlDockerfile,所以可以肯定的是:您必须通过 dockerfile 中的命令为 Apache 启用重写或像这样的自定义 Docker 文件:

# Dockerfile
FROM php:7.4-apache
RUN a2enmod rewrite

如果您没有启用重写,应该会出现错误 500,因为重写规则周围没有 if-conditions。

如果你确实启用了重写,行为仍然很奇怪,因为即使 ErrorDocument 404 /index.php 行不存在,底部重写应该使 index.php 无论如何都被服务。换句话说:.htaccess 中的最后三行将确保不提供 404,因为所有内容都被重写到 index.php.

当您说 'the default apache 404 page' 时,您指的是 'Not found' 页面吗?

Not Found (H1 tag)
The requested URL was not found on this server.

Apache/2.4.52 (Debian) Server at localhost Port 8000

尝试删除并重建容器,这样就不会出现奇怪的缓存问题。

那你的 index.php 呢?那里有什么东西可以触发奇怪的东西吗?你能post吗?

在您的 .htaccess 文件中试试这个(没有 ErrorDocument 部分):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php?file=[=10=] [QSA,L]

如果代码没有找到文件,请确保输出 404。

  • 是否有针对特定文件扩展名的默认 apache 处理程序?
    不,默认情况下没有这样的处理程序。

  • 如何设置所有请求都通过 index.php?

  1. ErrorDocument 404 /index.php有效。
  2. DirectoryIndex index.php有效
  3. RewriteEngine on有效
  4. RewriteCond %{REQUEST_FILENAME} !-f有效
  5. RewriteCond %{REQUEST_FILENAME} !-d有效
  6. RewriteRule ^ index.php [L]也有效!

请记住,您不是将它重写到根目录 /index.php,而是在不带斜杠的情况下重写,它会重写到当前目录中的 index.php。因此,如果 index.php 在当前目录中不存在,它可能会进入无限循环。

尝试:

ErrorDocument /index.php

DirectoryIndex index.php

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L] # use '/index.php' if needed to redirect to root index.php

这会将所有存在的内容重定向到 index.php,并避免与 ErrorDocument 冲突。

但是,我认为这实际上是您的意思:

ErrorDocument /index.php

DirectoryIndex index.php

# remove those rewrite rules