1

私はwriteBS writeTextSnap とrenderTemplatefrom heist を使用しましたが、どれも 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 は raw バイト用です。文字やエンコーディングの概念はありません。ここで Text の出番です。Data.Text.Encodingモジュールには、さまざまなエンコーディングを使用して Text と ByteString の間で変換を行うための関数が多数用意されています。私にとっては、次の両方が同じ出力を生成します。

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

コードが機能しなかった理由は、文字列リテラルが OverloadedStrings 拡張機能によって ByteString に変換されており、必要な動作が得られないためです。解決策は、それを適切なタイプ...テキストとして扱うことです。

物事の強盗側では、次のことがうまくいきます:

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

実際、これは私のブラウザで正しく表示されますが、前の 2 つは正しく表示されません。違いはcRender、適切な content-type を設定することです。次のスニペットを使用して違いを観察することは啓発的であることがわかりました.

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 に答える