If you are not afraid by old school hacks, the pre-AJAX āhidden iframe form uploadā trick seems to be the only way to send binary files directly (no base64 encoding) and get a ādecodableā (kind of) answer from the server in pure elm without ports:
Example for elm 0.19:
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes exposing (action, enctype, id, method, name, src, style, target, title, type_)
import Html.Events exposing (on)
import Http
import Json.Decode as Decode exposing (Decoder)
type Msg
= UploadCompleted String
type alias Model =
String
view : Model -> Html Msg
view model =
div []
[ form
[ action "/upload"
, target "iframe"
, enctype "multipart/form-data"
, method "POST"
]
[ input
[ name "fileInput"
, type_ "file"
]
[]
, iframe
[ name "iframe"
, id "iframe"
, style "display" "none"
, on "load" resultDecoder
]
[]
, button []
[ text "Submit" ]
]
, div []
[ text model
]
]
resultDecoder : Decoder Msg
resultDecoder =
Decode.at [ "target", "contentDocument", "body", "textContent" ] Decode.string
|> Decode.andThen (Decode.succeed << UploadCompleted)
update : Msg -> Model -> Model
update msg model =
case msg of
UploadCompleted result ->
result
main : Program () Model Msg
main =
Browser.sandbox
{ init = ""
, update = update
, view = view
}
It works (not for S3 though) but itās weak because the server response HTTP headers cannot be decoded.
Donāt try this at home 