使用Elm从POST请求下载文件

使用Elm从POST请求下载文件,post,download,elm,Post,Download,Elm,我有一个HTTP POST端点/render,它返回一个PDF文档,并希望向用户提供一个按钮/链接,该按钮/链接将导致该文档下载并保存到文件中,而无需离开我的Elm应用程序 理想情况下,POST将接受带有自定义格式的文本/纯文本正文,但我可以修改端点以接受多部分/表单数据或应用程序/x-www-form-urlencoded 我可以按如下方式成功地将原始数据下载到Elm应用程序,但我不知道如何将文件保存到磁盘 import Http render : String -> Http.Req

我有一个HTTP POST端点
/render
,它返回一个PDF文档,并希望向用户提供一个按钮/链接,该按钮/链接将导致该文档下载并保存到文件中,而无需离开我的Elm应用程序

理想情况下,POST将接受带有自定义格式的
文本/纯文本
正文,但我可以修改端点以接受
多部分/表单数据
应用程序/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
    }

我使用
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)
这并不理想,但很有效


PS:我从Elm Slack Channel获得了帮助

您是否尝试过在服务器端设置,以便将PDF作为附件发送?这将为浏览器提供指示,允许用户保存或显示文件。或者我误解了什么?据我所知,Elm通过XMLHttpRequest发送请求,并且响应不会自动触发正常的浏览器下载行为。但我承认我没有明确尝试过。我会试一试的,谢谢。我认为你是对的,XHR不起作用。所以,我误解了这个问题。HTML5似乎在这方面给我们带来了一些帮助,但不能真正说明如何在Elm中使用。