haskell 使用Yesod应用程序将文件上传到临时文件夹:编码问题

yx2lnoni  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(71)

我正在尝试做一个Yesod Web应用程序允许上传文件并将其保存在临时文件夹中。我使用Base64编码/解码。当我上传包含此内容的文本文件时:

copie carte d'identité
téléphone
autocertfication fiscale
signature

字符串
然后我在临时文件夹中得到的文件的内容是:

u«Zµìmþ™ZŠvÚ±î¸copie carte d'identité
téléphone
autocertfication fiscale
signature


输入文件是UTF8编码的。
下面是我如何使用JavaScript处理文件上传:

$("#file").on("change", function() {
    let file = this.files[0];
    let fileReader = new FileReader(); 
    fileReader.readAsDataURL(file);
    fileReader.onload = function() {
        let base64 = fileReader.result;
        $.ajax({
            contentType: "application/json",
            processData: false,
            url: "@{FileR}",
            type: "PUT",
            data: JSON.stringify({
                _filename: file.name, 
                _base64: base64
            }),
            success: function(result) {
                // not important
            },
            dataType: "text"
        });
    }; 
    fileReader.onerror = function() {
        alert(fileReader.error);
    }; 
});


在Haskell中,我有:

import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Char8 as BC
import System.IO.Temp ( getCanonicalTemporaryDirectory )

base64ToFile :: String -> FilePath -> IO FilePath
base64ToFile b64string fileName = do
    let bstring = B64.decodeLenient (BC.pack b64string)
    tmpDir <- getCanonicalTemporaryDirectory
    let filePath = tmpDir ++ "/" ++ fileName
    B.writeFile filePath bstring 
    return filePath

data File = File {
    _filename :: String,
    _base64   :: String
} deriving (Show, Generic)

instance FromJSON File

b64FileToFile :: File -> IO FilePath
b64FileToFile file = base64ToFile (_base64 file) (_filename file)

putFileR :: Handler String
putFileR = do
    file <- requireCheckJsonBody :: Handler File
    liftIO $ b64FileToFile file


我不知道问题的根源在哪里,是在JavaScript步骤还是在Haskell步骤。我希望能够上传文本文件、CSV文件、XLSX文件或图像文件。

bakd9h0s

bakd9h0s1#

必须从Base64字符串中删除MIME类型,也就是说,只取逗号后面的部分:

let base64 = fileReader.result.split(",")[1];

字符串

相关问题