自定义错误响应

Apache可以让网站管理员自己自定义对一些错误和问题的响应。

自定义的响应可以定义为当服务器检测到错误或问题时才被激活。

如果一个脚本崩溃并产生"500 Server Error"响应,那么这个响应可以被更友好的提示替换或者干脆用重定向语句跳到其他的URL(本地的或外部的)。

行为

老式的行为

Apache1.3 会响应一些对于用户没有任何意义的错误或问题信息,而且不会将产生这些错误的原因写入日志。

新式的行为

服务器可以被要求作出如下应答:

  1. 显示一些其他的文字以代替硬编码的信息
  2. 重定向到本地URL
  3. 重定向到一个外部的URL

当一些信息可以被传递的时候,重定向到另外一个URL就变得很有用。这些信息用于更清楚的解释和/或记录一些错误或问题产生的原因。

为了达到这个目的,Apache将定义一些新的类似于CGI环境变量的环境变量:

        REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, image/jpeg

        REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 9000/712)

        REDIRECT_PATH=.:/bin:/usr/local/bin:/etc

        REDIRECT_QUERY_STRING=

        REDIRECT_REMOTE_ADDR=121.345.78.123

        REDIRECT_REMOTE_HOST=ooh.ahhh.com

        REDIRECT_SERVER_NAME=crash.bang.edu

        REDIRECT_SERVER_PORT=80

        REDIRECT_SERVER_SOFTWARE=Apache/0.8.15

        REDIRECT_URL=/cgi-bin/buggy.pl

请注意"REDIRECT_"这个前缀。

至少会有REDIRECT_URLREDIRECT_QUERY_STRING两个变量会被传递到新的URL(假定这个URL是cgi脚本或者是cgi包含页面)。其他变量将仅在发生错误或问题之前存在的情况下才存在。如果你的ErrorDocument使用了外部重定向(任何类似于http: 开头的形式,哪怕它仍指向同一个服务器),将没有任何变量被指定。

配置

当对ErrorDocument进行了相应的设置后,将可以在.htaccess文件中使用AllowOverride指令。

以下是一些示例...

      ErrorDocument 500 /cgi-bin/crash-recover 

      ErrorDocument 500 "Sorry, our script crashed. Oh dear" 

      ErrorDocument 500 http://xxx/ 

      ErrorDocument 404 /Lame_excuses/not_found.html 

      ErrorDocument 401 /Subscription/how_to_subscribe.html

语法如下:

ErrorDocument <3位错误代码> <action>

<action>可以代表:

  1. 用于显示的用双引号(")界定的文字。双引号之间的所有文字都将被显示,但双引号本身不会被显示
  2. 作为重定向目的外部URL
  3. 作为重定向目的本地URL

自定义错误响应与重定向

Apache重定向到URL的行为已经进行了修改,以便可以在脚本/服务器端包含页面加入额外的环境变量。

老式的行为

标准CGI变量对于重定向的目的脚本来说是可见的。但没有说明重定向的来源。

新式的行为

一批新的环境变量将被初始化并提供给重定向的目标脚本。每个新变量都有一个"REDIRECT_"前缀。REDIRECT_* 环境变量由重定向之前的CGI环境变量创建而来,并被加上了"REDIRECT_"前缀。比如说,HTTP_USER_AGENT变成了REDIRECT_HTTP_USER_AGENT 。在这些新变量之外,Apache还将定义REDIRECT_URLREDIRECT_STATUS来帮助脚本确定重定向的来源。重定向的源URL和目的URL都能被记录到访问日志中。

如果ErrorDocument指定了一个到本地CGI脚本的重定向,该脚本应当在它的输出中包含一个"Status:"头字段以确保将导致调用它的错误条件始终返回客户端。举例来说,一个Perl ErrorDocument脚本可能包含如下内容:

        ... 

        print  "Content-type: text/html\n"; 

        printf "Status: %s <中断条件>\n", $ENV{"REDIRECT_STATUS"}; 

        ...

如果该脚本专门用于处理一个特定的错误条件,比如:404 Not Found ,它就可以使用特定的代码和错误文本进行替代。

需要注意的是如果应答包含一个"Location:"头(为了进行一个客户端重定向),脚本必须发出一个适当的"Status:"头(比如:302 Found)。否则"Location:"头可能无效。