我有一个代码
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-program执行时,我只有And
(因为在这个词之后我有西里尔字符并且不想显示它们。)
当我使用putStr $ fromString
和Data.ByteString.Char8
中的Data.ByteString.UTF8
时没有问题,因此我认为我的LAMPP服务器没有问题。我还在httpd.conf中包含了AddDefaultCharset utf-8
。
我想要做的就是阅读包含%s
,%d
等特殊符号的模板文件,然后在printf
的帮助下更换它们(符号)与我所需要的,取决于查询字符串和显示。
我这样做只是为了好玩,我希望这个问题只能用纯Haskell解决。
答案 0 :(得分:7)
让CGI程序依赖于语言环境可能适合也可能不适合;例如如果您生成的HTML有一个编码标题,表示它是UTF-8,那么您应该独立于系统区域设置生成UTF-8。
与语言环境无关的方法是在打印任何内容之前设置stdout的编码:
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)
修改后的代码:
/tmp $ ./Test2
Content-type: text/html; charset=utf-8
And немного русского
/tmp $ LANG=C ./Test2
Content-type: text/html; charset=utf-8
And немного русского
答案 1 :(得分:0)
非常好的解决方案是在httpd.conf,.htaccess或httpd-vhosts.conf(在LAMPP中)中设置环境变量LANG,方法是将字符串SetEnv LANG en_US.UTF-8
放在其中一个文件中。
在httpd.conf中,您可以为所有服务器设置此变量。
要使用.htaccess文件进行设置,必须在vhosts.conf中启用此商机
<Directory "<.htaccess directory>">
AllowOverride All
</Directory>
然后,您将能够使用SetEnv在set目录中使用.htaccess文件更改变量。
在vhosts.conf中,您只需在SetEnv LANG en_US.UTF-8
块中添加字符串VirtualHost
。
此解决方案允许您使用UTF-8和其他没有库的数据,例如Data.ByteString.Char8。
再次谢谢你。!