根据条件自定义错误文档,可能与否?

问题描述 投票:0回答:1

好吧 - 我的大脑逻辑与 .htaccess 文件中的代码如何处理的逻辑相去甚远……很糟糕,因为有时当你试图实现一些“逻辑”的东西时,它会变得令人沮丧。

我想在设置变量 MAINTENANCE_MODE 时设置自定义 ErrorDocument,但它根本不会加载正确的文件。这是因为 If 指令比 RewriteRules 更早被查看吗?

SetEnv MAINTENANCE_MODE 1

ErrorDocument 503 /msg/503_default.html

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    RewriteCond %{ENV:MAINTENANCE_MODE} 1
    RewriteRule ^ - [E=MAINTENANCE_503:1]
</IfModule>

<If "%{ENV:MAINTENANCE_503} == '1'">
    ErrorDocument 503 /msg/503_maintenance.php
    
    RewriteRule !^503 - [R=503]
</If>

当完全不可能时,哪种替代路线会产生最佳结果?

是否会创建一个可以接收值的 503_default.php 以便它知道要显示哪个自定义消息?如果是这样,我如何设置/传递该值到默认 503 页面?


顺便说一句 - 这只是它必须成为的一个简化的基本版本。我还有其他场景想要提供自定义 503 消息。但如果没有基础,编写扩展代码就没有意义:)

.htaccess if-statement apache2.4 errordocument
1个回答
0
投票

503(服务不可用)基本上是“维护模式”。通常,触发 503 的唯一时间是当站点“正在维护”时,因此很少需要有条件地拥有两个不同的 503 文档。 (除非您在同一文件空间中有不同的子站点?)

如果您特别想在设置

MAINTENANCE_MODE
环境变量时提供不同的响应,那么我只需在
503.php
文件本身(使用 PHP)中检查这一点并采取相应措施。


但是,为了解决您的具体问题...

RewriteCond %{ENV:MAINTENANCE_MODE} 1
RewriteRule ^ - [E=MAINTENANCE_503:1]

这里的问题是您正在使用

MAINTENANCE_MODE
(mod_setenv) 设置
SetEnv
环境变量。
SetEnv
处理得太晚,mod_rewrite 无法接收它。由于 mod_rewrite 是提前处理的,因此在处理此规则时,永远不会设置
MAINTENANCE_MODE
,因此也永远不会设置
MAINTENANCE_503

正如我之前的回答中简要提到的,您需要使用SetEnvIf

(mod_setenvif)来设置环境变量,因为这是在mod_rewrite之前(以及在计算<If>表达式之前)提前处理的。 )。但请注意不同的语法(因为 SetEnvIf
 主要用于有条件地设置环境变量,因此是 
If
)。
虽然我不确定这里的意图是什么,因为当一个环境变量已经设置时,设置另一个环境变量似乎没有多大意义?

旁白:

您不需要

<IfModule> 包装器 - 除非这是为了在未启用 mod_rewrite 的系统上工作。尽管并非所有 mod_rewrite 指令都包含在 <IfModule mod_rewrite.c>

 包装器中,但这有点违背了要点。请参阅
我对网站管理员堆栈上以下问题的回答
https://webmasters.stackexchange.com/questions/112600/is-checking-for-mod-write-really-necessary 所以,你可以这样做:

SetEnvIf ^ ^ MAINTENANCE_MODE=1 ErrorDocument 503 /msg/503_default.html <If "%{ENV:MAINTENANCE_MODE} == '1'"> ErrorDocument 503 /msg/503_maintenance.php RewriteEngine On RewriteCond %{ENV:REDIRECT_STATUS} !=503 RewriteRule ^ - [R=503] </If>

请注意,
<If>
表达式直接测试

MAINTENANCE_MODE

,而不是
MAINTENANCE_503
这将为每个 URL 触发 503,包括对 
/msg/503_maintenance.php

本身的直接请求。检查

REDIRECT_STATUS

 环境变量的 
condition 避免了这种情况下的重写循环。
但是,正如前面提到的,在 Apache 中定义多个 503 ErrorDocuments 真的有必要吗?如果没有,那么您将检查 mod_rewrite 规则本身中的环境变量。例如:

SetEnvIf ^ ^ MAINTENANCE_MODE=1 ErrorDocument 503 /msg/503_maintenance.php RewriteEngine On RewriteCond %{ENV:MAINTENANCE_MODE} =1 RewriteCond %{ENV:REDIRECT_STATUS} !=503 RewriteRule ^ - [R=503]

(尽管如此,触发“维护模式”的一种常用方法就是存在任意文件,例如“.maintenance-mode-ENABLED”,这样就无需编辑
.htaccess
- 它本身携带一定的“风险”。)

而且,如果您启用“维护模式”并发送 503,您实际上还应该发送 
Retry-After

HTTP 响应标头。再次,请参阅网站管理员堆栈上的以下问题(以及

我的答案

):
https://webmasters.stackexchange.com/questions/55635/website-is-under-maintenance-how-to-restrict-access

© www.soinside.com 2019 - 2024. All rights reserved.