Servant Haskell框架下如何将服务器已接收的图片重新上传?
解决方案
问题根因为构造多部分上传请求时未传递正确的文件元信息,和本地临时文件的.buf后缀无关,无需转存文件即可解决。
Servant返回的FileData结构体本身包含客户端上传时的原始文件名fdFileName、原始MIME类型fdFileContentType,你之前仅传递了临时文件路径fdPayload,丢失了这些元信息,导致Req构造请求时默认读取本地临时文件的.buf后缀作为文件名,第三方服务因此无法识别文件类型。
修改后的核心实现代码如下:
createRequest file = do let uploadPart = (partFileSource "files[]" (fdPayload file)) { partFileName = Just (fdFileName file) -- 复用客户端上传的原始文件名 , partContentType = Just (fdFileContentType file) -- 复用原始文件的MIME类型 } multiPartBody <- reqBodyMultipart [uploadPart] res <- req Network.HTTP.Req.POST (https "tmp.ninja" /: "upload.php") multiPartBody jsonResponse mempty return (responseBody res:: UploadResponse)
调用代码修改为直接传入完整的FileData对象即可:
runReq defaultHttpConfig $ createRequest file
可选优化
如果需要规避客户端传入错误MIME类型的问题,可引入mime-types类库,通过原始文件名的后缀推断标准MIME类型,替换上述代码中fdFileContentType的取值即可。
内容的提问来源于stack exchange,提问作者vijaicv
相关产品推荐
相关产品推荐

