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

问题描述 投票:0回答:1

我正在尝试制作一个 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 文件或图像文件。

javascript haskell encoding base64 yesod
1个回答
0
投票

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

let base64 = fileReader.result.split(",")[1];
© www.soinside.com 2019 - 2024. All rights reserved.