【问题标题】:How can I write an .htaccess file for Apache to append PHP (if not supplied) AND use a well-written 404 page如何为 Apache 编写 .htaccess 文件以附加 PHP(如果未提供)并使用编写良好的 404 页面
【发布时间】:2020-07-08 20:37:23
【问题描述】:

在 Apache 中,我有一个有效的 .htaccess 文件,该文件将 .php 扩展名附加到请求的网站页面,例如: https://{{domain}}/sales -> 提供来自 https:/ 的内容/{{domain}}/sales.php 而对于访问者来说,它看起来像 https://{{domain}}/sales

它运行完美。

但是,我无法解决如何也使用服务器上花哨的 404.php 页面。

这是我当前的 .htaccess 文件内容:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1\.php [NC,L]

证据:如果我关闭我的 .htaccess 文件(重命名它),404 页面根据我的 httpd.conf 设置运行良好。所以,我几乎可以肯定,正是这个不成熟的 .htaccess 文件阻止了我在找不到 sales.php 页面时提供精美的 404 页面。

httpd.conf 中的具体行是什么:

DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"

此外,我已经尝试了以下每个:(并在之后重新加载了 httpd)

ErrorDocument 404 "/var/www/html/{{virtualHostDir}}/404.php"
ErrorDocument 404 "/404.php"
ErrorDocument 404 "404.php"

我什至尝试将 ErrorDocument 直接添加到 virtualHost 设置中,但无济于事。


当您收到 404 并且 .htaccess 文件就位时,实际会发生什么?

我得到一个没有 html 的页面,它只是说“找不到文件”。

【问题讨论】:

  • 您的自定义 404 是如何以及在哪里定义的?
  • 自定义 404 页面位于网站的根目录(与 .htaccess 文件位于同一位置)。如果没有覆盖 .htaccess 文件的内容,Apache 的 httpd.conf ErrorDocument 404 "{{location}}" 会在页面丢失时正确调用 404。感谢您的帮助。
  • "{{location}}" 到底是什么? (“错误”可能仍然在于 ErrorDocument 的定义方式,尽管它在其他情况下似乎工作正常。如果它是完整的文档根相对文件系统路径,那么它不应该与发布的 mod_rewrite 指令冲突。)当你得到一个 404 并且 .htaccess 文件就位时,实际上会发生什么?确切的反应是……?如果尝试提供自定义错误文档时出现错误,默认的 Apache 响应通常会为您提供线索... 404、500 等?
  • DocumentRoot "/var/www/html/" ErrorDocument 404 "/404.php" 这些是我从 httpd.conf 中获取的行当你得到一个 404 并且 .htaccess 文件就位时实际会发生什么 我得到一个没有 html 的页面,它只会显示“找不到文件”。 (OP 更新了这些细节)再次感谢您的详细帮助!
  • "/var/www/html/**{{virtualHostDir}}**/404.php" - 刚刚注意到这一点......为什么你似乎会引入另一个子目录(在 vHost 中)该文件似乎位于/var/www/html/404.php?

标签: php apache .htaccess errordocument


【解决方案1】:
DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"

这看起来是正确的。如果 404 错误文档位于/var/www/html/404.php,那么没有明显的原因(从给定的信息)为什么它不能按预期工作。它似乎不是 .htaccess 文件的内容 - 尽管您可以尝试另一种方法(见下文)。

提供给ErrorDocument 指令的路径应该是相对于文档根目录的 URL 路径 - 以斜杠开头。 (为了触发对相应错误文档的内部子请求。)

我什至尝试将 ErrorDocument 直接添加到 virtualHost 设置中

但是,如果您使用的是 VirtualHost 容器,那么这些设置实际上应该在各自的 vHost(s) 中。 vHost 中的任何内容都将覆盖主服务器配置。

显然,如果您对服务器配置/虚拟主机进行任何更改,那么您将需要重新启动 Apache。

由于您无论如何都在使用.htaccess,您还可以在.htaccess 中设置ErrorDocument - 这将反过来覆盖虚拟主机/服务器配置。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1\.php [NC,L]

这并没有什么特别的问题...您正在匹配一个不包含点的请求的 URL 路径,并且如果它尚未映射到文件或目录,则您正在附加一个 .php 扩展名。

只是一些关于此的注释:

  • 无论“带有.php 扩展名”的文件是否实际存在,您都附加了.php 扩展名。这不一定是错误的,只是在/does-not-exist.php 而不是/does-not-exist 上触发了404。您可以改为检查目标文件是否存在。这将避免必须检查请求是否尚未映射到文件或目录。

  • 检查请求未映射到文件的第一个条件可能是不必要的,除非您的文件没有文件扩展名(我认为这不太可能)。

  • [^\.] - 在正则表达式字符类中不需要反斜杠转义文字点。 (虽然这样做没有害处,除了可读性 IMO。)

  • $1\.php - 在RewriteRule 替换 中,不需要用反斜杠转义文字点。这个参数是一个“普通”字符串(不是正则表达式),点在这里没有特殊含义。 (尽管这样做也没有什么坏处,除了可读性。)

  • 这里不需要RewriteRule 上的NC 标志,因为除了正则表达式中的点之外,您要匹配所有内容,它自然包括大写和小写字母。

  • 如果这就是您使用 mod_rewrite 的全部内容,那么您可以改用 MultiViews 来处理您的无扩展 URL。这就是 MultiViews(mod_negotiation 的一部分)所做的。给定/path/to/foo 的请求,如果存在/path/to/foo.php,mod_negotiation 将提供该文件。您需要删除现有的 mod_rewrite 指令(因为它们实际上会发生冲突并被忽略),然后在 .htaccess 文件的顶部启用 MultiViews:

    Options +MultiViews
    

或者,考虑到我上面提出的观点,尝试以下操作:

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]

注意:我假设您的 .htaccess 文件位于文档根目录中,即。 /var/www/html/.htaccess?

【讨论】:

  • 您的新重写规则有效,谢谢。 .htaccess 和 404 页面都在 VirtualHost 目录中,只是为了完成循环供任何人阅读。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 2014-05-14
  • 1970-01-01
相关资源
最近更新 更多