我正在使用默认的 Yesod 脚手架项目。
我创建了一个页面,显示一个简单的表单来上传文件。
(该表单可能会使用 Javascript 在客户端上创建。)
为简洁起见,该表单有一个文件输入:
<form method="post" action=@{UploadR}>
<input type="file" name="myfile">
<button type="submit">
我的目标是处理表单数据,然后将文件上传到网络服务。
我处理表单没有遇到任何问题,我关心的是与网络服务的交互。
例如,给定以下 Yesod 处理程序:
postUploadR :: Handler Html
postUploadR = do
mgr <- fmap httpManager getYesod
fi <- runInputPost $ ireq fileField "myfile"
let fSource = fileSource fi
fName = fileName fi
req <- parseUrl "http://webservice/upload"
let areq = req { method = methodPost
, requestBody = requestBodySourceChunked fSource
}
res <- httpLbs areq mgr
defaultLayout $ do
setTitle "file uploaded"
[whamlet|
<h3> Success
<p> You uploaded #{fName}.
|]
Web 服务返回错误:fail post content-length
,但其他一切都按预期进行。也许服务器不支持分块请求正文?
我认为您对分块请求正文的猜测是正确的。你需要做的是:
- 将上传的内容流式传输到临时文件中。
- 获取该文件的大小。
- Use
requestBodySource
并提供文件长度及其内容。
幸运的是,步骤(1)和(2)可以很容易地由接收缓存长度 http://haddocks.fpcomplete.com/fp/7.8/20140916-162/conduit-extra/Data-Conduit-Binary.html#v:sinkCacheLength功能。你最终会得到类似的结果:
(fSize, fSource) <- fileSource fi $$ sinkCacheLength
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)