8

我正在尝试使用 Fable-Elmish 和 React Helpers 上传文件。但是,我不知道如何在选择文件时将表单事件转换为可以使用 Fetch 发送到服务器的内容。这是视图:

R.input [
        ClassName "input-control" 
        Type "file"
        OnChange (fun x -> FileUploaded x.target |> dispatch )
    ] []

我的更新功能的相应部分:

 | FileUploaded file ->
    model, Cmd.ofPromise postCsv file FetchSuccess FetchFailure

以及使用 fetch 调用 api 的函数:

let postData input =
    let formData = FormData.Create()
    formData.append("file.csv", input?files)
    let defaultProps =
        [ RequestProperties.Method HttpMethod.POST
        ; RequestProperties.Body (formData |> unbox)]
    promise {
        return! Fable.PowerPack.Fetch.fetch ("/api/data") defaultProps
    }

如何将 React.FormEvent 转换为 fetch 需要的 BodyInit?

4

4 回答 4

4

您将需要创建一个新的 FormData 对象并将文件附加到它。

let formData = FormData.createNew formData.append("file", file.[0])

然后更改您对 postRecord 的调用以传递 formData 而不是文件。您需要 fetch 对其进行编码,但您只是传递文件的原始数组。

至少这是我对上传文件的fetch 示例的理解。另外,发布记录在我看来是错误的,您可以使用“发布”方法吗?postRecord 暗示它需要一个记录类型。

于 2017-04-24T13:44:42.387 回答
1

事实证明我没有正确使用 FileList API。这是 post 方法的工作解决方案:

let postData input =
let formData = FormData.Create()
formData.append("file.csv", input?files?item(0))
let defaultProps =
    [ RequestProperties.Method HttpMethod.POST
    ;RequestProperties.Headers [unbox EncType "multipart/form-data"]
    ; RequestProperties.Body (formData |> unbox)]
promise {
    return! Fable.PowerPack.Fetch.fetch ("/api/data") defaultProps
}
于 2017-04-29T19:30:36.197 回答
1

我认为Fetch.postRecord是您的问题,它将Content-Type标头设置为application/json,什么时候应该是 multipart/form-data

您需要使用 raw fetch API,而不是 powerpack 包装器,就像这样

于 2017-04-24T13:46:51.310 回答
1

在测试您的代码后,检查ev.target?value显示该事件仅获取所选文件的名称。postRecord似乎用于将 json 发送到端点。您将要移植:https://medium.com/ecmastack/uploading-files-with-react-js-and-node-js-e7e6b707f4ef到您想要做的事情。

于 2017-04-24T18:45:10.120 回答