1

writeBS writeText从 Snap 和renderTemplateheist 中使用过,但它们似乎都不支持 unicode。

site :: Snap ()
site = do
    ifTop (writeBS "你好世界") <|>
    route [("test", testSnap)]

testSnap :: Snap ()
testSnap = do
     fromJust $ C.renderTemplate hs "test"

-- test.tpl

你好世界

我原以为它会为/or/test路由输出“你好世界”,但实际上它的输出只是一些乱七八糟的代码。

4

1 回答 1

1

这里的问题不在于 writeBS 或 writeText。它与 OverloadedStrings 扩展使用的转换有关。理解 ByteString 和 Text 之间的区别也很重要。ByteString 用于原始字节。没有字符或编码的概念。这就是 Text 的用武之地。Data.Text.Encoding模块有一堆函数可以使用不同的编码在 Text 和 ByteString 之间进行转换。对我来说,以下两个生成相同的输出:

writeBS $ encodeUtf8 "你好世界"
writeText "你好世界"

您的代码不起作用的原因是您的字符串文字被 OverloadedStrings 扩展转换为 ByteString,它没有给您想要的行为。解决方案是将其视为正确的类型...文本。

在抢劫方面,以下对我来说很好:

route [("test", cRender "test")]

事实上,这个在我的浏览器中正确呈现,而前两个没有。不同之处在于cRender设置了适当的内容类型。我发现使用以下代码段观察差异很有启发性。

site = route [ ("/test1", writeBS "你好世界")
             , ("/test2", writeBS $ encodeUtf8 "你好世界")
             , ("/test3", writeText "你好世界")
             , ("/test4", modifyResponse (setContentType "text/html;charset=utf-8") >> writeText "你好世界")
             , ("/testHeist", cRender "test")
             ]

在我的浏览器中 test4 和 testHeist 工作正常。测试 2 和 3 为您提供了正确的行为,但由于缺少内容类型,浏览器可能无法正确呈现。

于 2013-09-23T17:55:47.623 回答