如何在React Native中使用fetch上传文件和文本?

时间:2019-02-12 04:54:18

标签: javascript reactjs react-native file-upload multipartform-data

我正在尝试使用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()。请帮助我找到解决方案。如何将其上传到服务器以及如何在不进行字符串化的情况下发送文本?

1 个答案:

答案 0 :(得分:0)

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'}]
}