3

我有一个代码

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 程序执行时,我只是And(因为在这个词之后我有西里尔字符并且它们不想被显示)。

putStr $ fromString当我使用from Data.ByteString.Char8and时没有问题,Data.ByteString.UTF8所以我不认为我的 LAMPP 服务器有问题。而且我还包含AddDefaultCharset utf-8在 httpd.conf 中。

而我真正想要做的是读取带有特殊符号(例如等)的模板文件%s%d然后在 的帮助下printf,将它们(符号)替换为我需要的,具体取决于查询字符串和显示。

我这样做只是为了好玩,我希望这个问题只能用纯 Haskell 来解决。

4

2 回答 2

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 немного русского
于 2012-07-24T09:15:39.360 回答
0

非常好的解决方案是通过将字符串SetEnv LANG en_US.UTF-8放入其中一个文件中,在 httpd.conf、.htaccess 或 httpd-vhosts.conf(在 LAMPP 中)中设置环境变量 LANG。

在 httpd.conf 中,您可以为所有服务器设置此变量。

要使用 .htaccess 文件进行设置,您必须在 vhosts.conf 中启用此机会

<Directory "<.htaccess directory>">
    AllowOverride All
</Directory>

然后,您将能够使用 SetEnv 使用 set 目录中的 .htaccess 文件更改变量。

在 vhosts.conf 中,您可以SetEnv LANG en_US.UTF-8VirtualHost块中添加字符串。

此解决方案允许您使用 UTF-8 和其他没有库(如 Data.ByteString.Char8)的库。

再次感谢纳米!

于 2016-08-15T07:10:39.650 回答