Warning: Reason support is experimental. We are looking for beta-tester and contributors.

How to send a file to the server without stopping the client process?

This requires Eliom ≥ 3.1.

Due to security reasons, browsers have limitations on sending files. But if the file is chosen by the user through an input file element, there is a way to send it to the server. You can't use the server_function or let%rpc syntax for this, but you can use Eliom_client.call_caml_service.

Example:

[%%client
open Js_of_ocaml
open Js_of_ocaml_lwt
open Eliom_content.Html
open Eliom_content.Html.F]

let pic_service =
  Eliom_service.create_ocaml ~name:"upload_pic" ~path:Eliom_service.No_path
    ~meth:(Eliom_service.Post (Eliom_parameter.unit, Eliom_parameter.file "f"))
    ()

let () =
  Eliom_registration.Ocaml.register ~service:pic_service (fun _ _ ->
      (* get the file ... *)
      Lwt.return_unit)

let%client upload_pic_form () =
  let file = D.Raw.input ~a:[a_input_type `File] () in
  let submit_elt = D.Raw.input ~a:[a_input_type `Submit; a_value "Send"] () in
  (let open Lwt_js_events in
  async (fun () ->
      clicks (To_dom.of_input submit_elt) (fun _ _ ->
          Js.Optdef.case
            (To_dom.of_input file)##.files
            Lwt.return
            (fun files ->
              Js.Opt.case
                files ## (item 0)
                Lwt.return
                (fun file ->
                  Eliom_client.call_ocaml_service ~service:~%pic_service ()
                    file)))));
  [txt "Upload a picture:"; file; submit_elt]