首页 > 解决方案 > 如何使用 fetch 在 React Native 中上传文件和文本?

问题描述

我正在尝试使用react-native-document-picker. 我面临的问题是我不知道如何将文件与文本一起上传。在我的应用程序中有一部分用于文件上传,也有一个区域用于编写一些文本。然后它将被上传到服务器.所以我做了以下事情。但是在提交到服务器后我收到了这个错误

unhandled promise rejection unsupported BodyInit type

更新部分代码

 filepick = () => {
    DocumentPicker.show({
        filetype: [DocumentPickerUtil.images()],
    }, (error, res) => {
        if (error == null) {
            console.log(
                res.uri,
                res.type, // mime type
                res.fileName,
                res.fileSize
            );
            this.setState({
                img_uri: res.uri,
                img_type: res.type,
                img_name: res.fileName

            })
        } else {
            Alert.alert('Message', 'File uploaded failed');
        }
    });
};


 onPressSubmit() {

        const data = new FormData();
        data.append('file', { uri: this.state.img_uri, type: 
       this.state.img_type, name: this.state.img_name })
        data.append('comment', { text: this.state.text });
        AsyncStorage.getItem("userdetail").then(value => {
            fetch(GLOBAL.ASSN_URL +`${this.props.id}`, {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'multipart/form-data',
                    'Authorization': value
                },
                body: data
            }).then((response) => {
                return response.text()
            }).then((responseJson) => {
                var result = responseJson;

                console.log(result);

            });
        })
    }

从您的设备中选择文件后调用该函数filepick()。请帮助我找到解决方案。如何将其上传到服务器以及如何在不对其进行字符串化的情况下发送文本?

标签: javascriptreactjsreact-nativefile-uploadmultipartform-data

解决方案


body: ({
    file: this.state.file,
    comment: this.state.text
})

你为什么用括号包裹身体?删除它们可能会解决它。

另请参阅https://github.com/facebook/react-native/issues/6025您可能想要对正文对象进行字符串化,因为您的内容类型不是application/json

body: JSON.stringify({
        file: this.state.file,
        comment: this.state.text
})

编辑

从评论中,我们现在知道以下内容

1)您正在单独上传文件。

2)上传响应包含有关文件的信息

3)您将实体保存在单独的服务器调用中

4)您需要使用该实体保存文件

下面的解决方案假设您可以完全控制服务器,并且您还可以处理文件上传端点。这是解决方案

您基本上不需要使用实体再次上传整个文件,因为它已经上传到服务器上,您需要做的就是使用实体保存文件的引用。它们是保存参考的两种方法

1)只需将 fileName 或 fileUrl 保存在您的实体表中,然后将名称或 url 与实体一起存储,这样它就会如下所示

{
  id: 1,
  name: 'Cat',
  picture: // url or name of picture
}

2)将上传的文件保存在不同的表中,然后将文件的ID与您的实体一起保存,并在您获取实体时获取相关文件。但是,如果实体和文件之间的关系是一对多的,因为一个实体可以有很多文件,那么您首先需要保存实体,然后参考实体上传文件。这样您的实体将如下所示

{
  id: 1,
  name: 'Cat',
  pictures: [{fileName: 'cat1'}, {fileName: 'cat2'}]
}

推荐阅读