我如何使用react-router-dom包中的加载器和操作函数将文件发布到我的服务器?

问题描述 投票:0回答:1

这是我的第一个问题。如果我做错了什么请原谅。

设置: 我有一个create-react-app,它使用react-router-dom进行路由。主要思想是某种简单的文件服务器。因此用户可以在网页上上传/删除文件。这将被上传到服务器,然后应在页面上列出。为此,服务器提供了一个 api 端点,其中列出了所有已上传的文件。

因为我想使用某种 dropzone,它直接为我提供 File 对象。我最终不会有表格。所以我认为对于这种情况我必须选择

useFetcher()
然后运行
fetcher.submit(...)

问题: 我的问题是,该文件没有发送到服务器。然后我试图寻找它的来源。 我认为它发生在带有注释的两行之间(9 和 27)。因此,包装在 FormData 中的文件在传递给其他函数时会被字符串化为仅名称。

我尝试过的 正如已经提到的,我检查了问题发生在哪一步。所以在我看来,它发生在库内部的某个地方,即将 formData“提交”到

action
函数。所以我查看了库内部,在节点模块(react-router-dom:^6.10.0)的文件
dist/index.js
中,在第709行中我找到了一个can转换表单数据的函数:
getFormSubmissionInfo
。但我认为因为我的输入是 FormData 类型,所以它不会以与赋予函数相同的方式被触摸和返回。 (参见第 161 行,
dist/index.js
)。

问题

useFetcher
是“在后台”向服务器提交文件的正确方法吗,因此无需提交表单? 如果是这样,我如何将文件提供给我的操作函数?

代码片段: 为了将问题与我的项目分开,我创建了问题的 github 存储库 (https://github.com/fabalexsie/StackOverflow_SendFileWithReactRouterDomAction)。

加载器和操作函数在路由对象中引用。

export async function loader() {
    return fetch('http://localhost:8080/fileList').then(r => r.json())
}

export async function action({request}) {
    const formData = await request.formData();
    console.log("Formdata in action", formData) // here the file is only the name
    await fetch('http://localhost:8080/upload', {
        method: 'POST',
        body: formData
    });
    return {success: true};
}

export function Details() {
    const fileList = useLoaderData();
    const fetcher = useFetcher();

    const handleUpload = (ev) => {
        const file =  ev.target.files[0];
        console.log("File from handle upload", file);
        const formData = new FormData();
        formData.append('file', file);
        formData.append('pw', "InRealityComesFromSomeOtherInput");
        console.log("Formdata in handle upload", formData); // here the file is the file object
        fetcher.submit(formData, {method: 'POST', action: '/details'})
    }

    return (
        <>
        <ul>
            {fileList.map(f => 
                <li key={f}>
                    <a href={`http://localhost:8080/files/${f}`}>{f}</a>
                </li>
            )}
        </ul>
        <input type="file" id="file" name="file" onChange={handleUpload} />
        </>
    );
}
javascript reactjs file-upload react-router-dom form-data
1个回答
0
投票

休息了一会,我又查看了一下,发现了错误。

提交时,必须指定编码类型“multipart/form-data”,以便以 POST 请求发送文件:

fetcher.submit(formData, {method: 'POST', action: '/details', encType: 'multipart/form-data'})

PS:我也在repo中发布了解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.