Загрузка файла из POST-запроса с помощью Elm - PullRequest
0 голосов
/ 28 августа 2018

Я нахожусь в положении, когда у меня есть конечная точка HTTP POST /render, которая возвращает документ PDF, и хотела бы предоставить пользователю кнопку / ссылку, которая приведет к загрузке и сохранению этого документа в файл без перехода из моего приложения вяза.

В идеале 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
    }

1 Ответ

0 голосов
/ 28 января 2019

Я сделал это, используя 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 https://elmlang.slack.com/

...