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 映像复制了您的实验。当打开 url http://localhost:8000/doesnotexist.txt
时,我被转移到 index.php 文件,正如我所期望的那样。底部的三个重写规则会将所有内容重写为 index.php.
首先:您还没有 post编辑 docker-compose.yml
或 Dockerfile
,所以可以肯定的是:您必须通过 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?
ErrorDocument 404 /index.php
有效。
DirectoryIndex index.php
有效
RewriteEngine on
有效
RewriteCond %{REQUEST_FILENAME} !-f
有效
RewriteCond %{REQUEST_FILENAME} !-d
有效
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
我想通过 .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
http://localhost:8000/exists.txt(现有文件)-> 提供现有文件
http://localhost:8000/doesnotexist.txt(不存在)-> 显示默认的 apache 404 页面(与未安装 PHP 时相同)
是否有针对特定文件扩展名的默认 apache 处理程序?
如何设置所有请求以通过 index.php?
我用 Docker 和 php 7.4-apache 映像复制了您的实验。当打开 url http://localhost:8000/doesnotexist.txt
时,我被转移到 index.php 文件,正如我所期望的那样。底部的三个重写规则会将所有内容重写为 index.php.
首先:您还没有 post编辑 docker-compose.yml
或 Dockerfile
,所以可以肯定的是:您必须通过 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?
ErrorDocument 404 /index.php
有效。DirectoryIndex index.php
有效RewriteEngine on
有效RewriteCond %{REQUEST_FILENAME} !-f
有效RewriteCond %{REQUEST_FILENAME} !-d
有效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