React-native RNFetchBlob:Axios Post 请求发送字符串而不是二进制数据

问题描述

我最近一直在 React-native 中实现上传文件功能,但遇到了一个错误,我需要将二进制文件数据发布到请求正文中。

首先,我检查了 Postman 的工作原理,并在 postman 中测试了这个 API,我将 Authorizationuid 发送到请求标头和 body将是 Form-Data with document = binary file

见下面的 document 键,我们可以在 Postman 中选择文件对象。

Postman request body representation. Document is of type File.

在这个 Postman 请求以这种方式成功,如果我检查 NodeJs-Axios 的相关代码,它就像在这里添加的一样。

代码来自 Postman,仅用于解释。

var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('document',fs.createReadStream('LOCAL_PATH_TO_FILE/Screenshot 2021-01-28 at 12.26.32 PM.png'));

var config = {
  method: 'post',url: 'API_BASE/addDocument/',headers: { 
    'Authorization': 'Firebase_ID_Token','uid': 'Firebase_User_ID',...data.getHeaders()
  },data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

由于我们无法使用上面为 React-native 添加的相同函数,并且我使用了 react-native-document-picker,因此当我选择任何文件时,我得到的对象就像,

{
 
    "size":1173,"filecopyUri":"file:///Users/Local_File_Path.plist","name":"File_Name.plist","uri":"file:///Users/Local_File_Path.plist"
}

我需要通过 API 调用将此文件(例如 plist)上传/adDocument 端点,该端点期望请求正文为 document: (binary data)

所以,这是我的 addDocument API 调用 的主要函数,需要对其进行更正以将正确的数据发送到 API。

import RNFetchBlob from 'rn-fetch-blob';
var RNFS = require('react-native-fs');

async uploadFileData (fileData) {
  try {
    console.log("***** uploadFileData parameters =>>>>> ",fileData);

    const mainPath = fileData.uri.replace("file://","");
    let readStreamData = await RNFetchBlob.fs.readStream(mainPath,'base64');
    let readFileData = await RNFS.readFile(mainPath);
    let wrapData = RNFetchBlob.wrap(mainPath);
    
    let data = new FormData();
    data.append('document',readStreamData,{'name': fileData.name});
    //data.append('document',new Blob([readFileData]),readFileData,{'name': fileData.name});
    
    const apiHeader = {
        'Authorization': 'Google_ID_Token','uid': 'Google_User_ID','Content-Type': 'multipart/form-data','Cache-Control' : 'no-store'
    };

    const res = await axios({ 
      method: 'POST',headers: apiHeader,data: data,baseURL: 'BASE_URL',url: '/addDocument/'
    });
  
    console.log("document/addDocument =>>>>> ",res);
    return res;
  } catch (e) {
    console.log("xxxxxxx document/addDocument Error =>>>>> ",e);
    return {  error: e  };
  }
}

我总是收到使用上述任何方法 readStreamDatareadFileDatawrapData 执行此函数的失败。原因是,我永远无法将二进制数据传递到 document

我在请求正文中看到的是,

enter image description here

这里,[object Object]一个字符串而不是一个对象,因此,我的 API 调用抛出错误说明,数据丢失。它总是传递我使用'Blob()'的字符串事件。

所以,我想知道我在这里做错了什么,所以我的请求正文没有传递二进制数据。请向我发送有关该主题的任何指示,以便我找到解决方案。

解决方法

这确实是 React-native debugger 的问题,而不是实际的实现问题。正如此处提到的 => https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md,调试器会处理 FormData,并且由于 [object Object] 属性,任何传递到 FormData 的内容都会变成 uri 字符串。

我已关闭调试并在设备和模拟器上进行了尝试,其中以下代码按预期工作。 无需显式将文件转换为 blob。

async simpleFileUpload (fileData) {
  try {
    console.log("***** uploadFileData parameters =>>>>> ",fileData);

    const mainPath = fileData.uri.replace("file://","");
    const file = {
      uri: mainPath,type: fileData.type,name: fileData.name || fileData.uri.substr(fileData.uri.lastIndexOf('/') + 1)
    };

    let formData = new FormData();
    formData.append('document',file);
    
    const res = await axios({ 
      method: 'POST',headers: this.apiHeaderUpload(),data: formData,baseURL: 'http://103.53.72.244:9091/api',url: '/document/addDocument/'
    });

    console.log("document/addDocument =>>>>> ",res);
    //alert('uploadFileData::Upload Successful >>> ' + JSON.stringify(res));
    return res;
  } catch (e) {
    console.log("xxxxxxx document/addDocument Error =>>>>> ",e);
    //alert('uploadFileData::Upload Error >>> ' + JSON.stringify(e));
    return {  error: e  };
  }
}

就这么简单:)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...