在ErrorDocument消息中设置charset

时间:2013-11-29 10:13:55

标签: apache .htaccess utf-8 apache2.4

我有一个.htaccess文件,如下所示:

AddDefaultCharset utf-8
AddCharset utf-8 .html
Order Allow,Deny 
ErrorDocument 403 "Error 403 - Esta ubicación no es pública"

文件本身编码为UTF-8。但是,Apache坚持声明ISO-8859-1并且错误信息被破坏了:

HTTP/1.1 403 Forbidden
Date: Fri, 29 Nov 2013 10:06:25 GMT
Server: Apache/2.4.6 (Win32) OpenSSL/1.0.1e PHP/5.5.6
Content-Length: 42
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

如果我在浏览器中手动将编码更改为UTF-8文本看起来是正确的。

网站已获得所有权限:

<VirtualHost *:80>
    ServerName tmp
    DocumentRoot "D:/tmp"

    <Directory "D:/tmp">
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

......并且Apache日志中没有任何相关内容。

我错过了什么?

1 个答案:

答案 0 :(得分:10)

太棒了!我必须说。我不得不挖掘所有资源并阅读大量手册以找出这种行为的原因。

这似乎是一种已知的行为,但官方手册中并未详细介绍。最后,我在this Apache manual中找到了它的一个参考:

  

抑制-错误字符集

     

在2.0.54之后的版本中提供

     

当Apache发出重定向以响应客户端请求时,   响应包括一些在客户端显示的实际文本   不能(或不)自动遵循重定向。阿帕奇   通常根据它的字符集标记该文本   用途,即ISO-8859-1。

     

但是,如果重定向是使用不同的页面   字符集,一些破碎的浏览器版本将尝试使用   重定向文本而不是实际页面的字符集。   例如,这可能导致希腊语被错误地渲染。

     

设置此环境变量会导致Apache省略该字符   为重定向文本设置,然后这些损坏的浏览器将会出现   正确使用目标页面。

这正是您看到charset=iso-8859-1出现在标题中的行为。


如何修复:

让你的.htaccess代码如下:

# set desired env variable to suppress iso-8859-1 charset
SetEnvIf Host ^ suppress-error-charset

# set desired 403 message with desired charset 
ErrorDocument 403 "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head><body>Error 403 - Esta ubicación no es pública</body></html>"

请注意 SetEnvIf Host ^ 是一个始终成立的条件,因此始终会设置 suppress-error-charset 。我已经在.htaccess中测试了这两行,并在浏览器中显示了正确的错误消息。