如何使用格式化打印在Haskell for CGI中显示UTF-8?
我有密码如何使用格式化打印在Haskell for CGI中显示UTF-8?,haskell,utf-8,cgi,printf,Haskell,Utf 8,Cgi,Printf,我有密码 module Main where import Text.Printf main = printf "%s%s" ("Content-type: text/html; charset=utf-8\n\n" :: String ) ("And немного русского" :: String) 如果我在终端执行它,我就得到了我想要的: Content-type: text/html; charset=utf-8 And немного русского 但当我试图将其作
module Main where
import Text.Printf
main = printf "%s%s" ("Content-type: text/html; charset=utf-8\n\n" :: String ) ("And немного русского" :: String)
如果我在终端执行它,我就得到了我想要的:
Content-type: text/html; charset=utf-8
And немного русского
但当我试图将其作为cgi程序执行时,我只有和
(因为在这个单词之后我有西里尔字母,它们不想显示)
当我使用Data.ByteString.Char8
和Data.ByteString.UTF8
中的putStr$fromString
时,没有问题,所以我认为我的LAMP服务器没有问题。我还在httpd.conf中包含了AddDefaultCharset utf-8
我要做的就是读取带有特殊符号的模板文件,如%s
,%d
等,然后在printf
的帮助下,根据查询字符串和显示,用我需要的符号替换它们(符号)
我这样做只是为了好玩,我只想用纯Haskell解决这个问题。让CGI程序依赖于语言环境可能合适,也可能不合适;e、 g.如果生成的HTML有一个编码头表示它是UTF-8,那么您应该独立于您的系统语言环境生成UTF-8 独立于区域设置的方法是在打印任何内容之前设置标准输出的编码:
import System.IO
main = do
hSetEncoding stdout utf8
printf "%s%s" ("Content-type: text/html; charset=utf-8\n\n" :: String ) ("And немного русского" :: String)
您的代码:
/tmp $ echo $LANG
de_DE.utf8
/tmp $ ./Test2
Content-type: text/html; charset=utf-8
And немного русского
/tmp $ LANG=C ./Test2
Content-type: text/html; charset=utf-8
And Test2: <stdout>: commitBuffer: invalid argument (invalid character)
非常好的解决方案是在httpd.conf、.htaccess或httpd-vhosts.conf(在LAMPP中)中设置环境变量LANG,方法是将字符串
SetEnv LANG en_US.UTF-8
放在其中一个文件中
在httpd.conf中,可以为所有服务器设置此变量
要使用.htaccess文件进行设置,必须在vhosts.conf中启用此opportunity
<Directory "<.htaccess directory>">
AllowOverride All
</Directory>
允许超越所有
然后,您将能够使用SetEnv在set目录中使用.htaccess文件更改变量
在vhosts.conf中,您只需在VirtualHost
块中添加字符串SetEnv LANG en_US.UTF-8
此解决方案允许您使用UTF-8和其他不带库的文件,如Data.ByteString.Char8
再次感谢你,n.m 检查Apache服务器运行的区域设置。我想象deaktop环境有
*.utf-8
。为了快速检查,您可以运行一个CGI脚本,只执行locale
命令。我有以下列表:LANG=LANGUAGE=LC\u CTYPE=“POSIX”LC\u NUMERIC=“POSIX”LC\u TIME=“POSIX”LC\u COLLATE=“POSIX”LC\u MONETARY=“POSIX”LC\u MESSAGES=“POSIX”LC\u PAPER=“POSIX”LC\u NAME=“POSIX”LC_TELEPHONE=“POSIX”LC_MEASUREMENT=“POSIX”LC_IDENTIFICATION=“POSIX”LC_ALL=这是预期的。Haskell IO尝试使用区域设置的编码,在POSIX区域设置的情况下为ASCII。ASCII没有西里尔字符,所以在输出时跳过它们。通过设置LANG环境变量(在Apache中使用mod_env),可以尝试在CGI程序上强制使用UTF8语言环境(如果LAMP服务器上安装了任何语言环境)。或者,您可以将printf
添加到字符串中,并使用例如System.IO.UTF8
输出该字符串,无需进行区域设置操作。我确信,为您自己的问题添加答案的正确方法就是将其作为实际答案添加。你应该接受最能解决问题的答案,而不是将标题改为包含“已解决”一词。然后答案计数变为黄色,这样人们可以看到问题已经解决。这比我的建议更好。我完全忘记了hsetencode
:-(
<Directory "<.htaccess directory>">
AllowOverride All
</Directory>