我的位置是,我有一个/render
返回 PDF 文档的 HTTP POST 端点,并且希望向用户呈现一个按钮/链接,该按钮/链接将导致该文档被下载并保存到文件中,而无需离开我的 Elm应用程序。
理想情况下,POST 将接受text/plain
具有自定义格式的正文,但我可以重新设计端点以接受multipart/form-data
或application/x-www-form-urlencoded
。
我可以按如下方式将原始数据成功下载到 Elm 应用程序,但我不知道如何将文件保存到磁盘。
import Http
render : String -> Http.Request String
render body =
Http.request
{ method = "POST"
, headers = []
, url = "/render"
, body = Http.stringBody "text/plain" body
, expect = expectString
, timeout = Nothing
, withCredentials = False
}
Run Code Online (Sandbox Code Playgroud)
小智 4
我使用expectBytes
而不是这样做expectString
,所以我的代码是
import Bytes exposing (Bytes)
import File.Download as Download
Msg = .. | FormUploaded (Result Http.Error Bytes)
Http.post
{ url = "/passports"
, body =
Http.multipartBody...
, expect = Http.expectBytesResponse FormUploaded (resolve Ok)
}
downloadPdf : Bytes -> Cmd msg
downloadPdf pdfContent =
Download.bytes "form.pdf" "application/pdf" pdfContent
update : Msg -> Model -> ( Model, Cmd Msg )
update model =
...
FormUploaded (Ok response) ->
( model, downloadPdf response )
FormUploaded (Err err) ->
( model, Cmd.none )
-- this helper function copied from https://github.com/elm/http/blob/2.0.0/src/Http.elm#L514-L521
resolve : (body -> Result String a) -> Http.Response body -> Result Http.Error a
resolve toResult response =
case response of
BadUrl_ url ->
Err (BadUrl url)
Timeout_ ->
Err Timeout
NetworkError_ ->
Err NetworkError
BadStatus_ metadata _ ->
Err (BadStatus metadata.statusCode)
GoodStatus_ _ body ->
Result.mapError BadBody (toResult body)
Run Code Online (Sandbox Code Playgroud)
这并不理想但有效
PS:我从 Elm Slack 频道https://elmlang.slack.com/获得了帮助