React-native RNFetchBlob: Axios Post 请求发送字符串而不是二进制数据
React-native RNFetchBlob: Axios Post request sends string instead of binary data
我最近一直在将上传文件功能实现到 React-native 中,但遇到一个错误,我需要将二进制文件数据 post 到请求 body.
首先,我检查了 Postman 是如何工作的,我测试了这个 API 到 postman 我发送 Authorization
和uid
到请求 headers 和 body
将是 Form-Data 和 document
= binary file
.
下面是 document
键,我们可以在 Postman 中 select 文件 object。
现在这个 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
,当我选择任何文件时,我得到的 object 就像,
{
"size":1173,
"fileCopyUri":"file:///Users/Local_File_Path.plist",
"name":"File_Name.plist",
"uri":"file:///Users/Local_File_Path.plist"
}
我需要通过 API 调用 /adDocument
端点上传此文件(例如 plist),该端点期望请求 body 作为 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]), {'name': fileData.name});
//data.append('document', 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 };
}
}
使用上述任何方法 readStreamData
、readFileData
或 wrapData
,此功能总是失败。原因是,我永远无法将二进制数据传递到 document
.
我在请求中看到的body是这样的,
在这里,[object Object]
是一个字符串而不是 object,因此,我的 API 调用抛出错误说明,数据丢失。它总是传递我使用 'Blob()'.
的字符串事件
所以,我想知道我在这里做错了什么,所以我的请求 body 没有传递二进制数据。请将有关该主题的任何指示发送给我,以便我找到解决方案。
那是 React-native debugger
的真正问题,而不是实际的实施问题。正如此处提到的 => https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md,调试器会乱用 FormData,并且由于 uri
属性.
,传递给 FormData 的任何内容都会变成 [object Object]
字符串
我已关闭调试并在设备和模拟器上进行了尝试,以下代码按预期工作。 无需显式将文件转换为 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 };
}
}
就这么简单:)。
我最近一直在将上传文件功能实现到 React-native 中,但遇到一个错误,我需要将二进制文件数据 post 到请求 body.
首先,我检查了 Postman 是如何工作的,我测试了这个 API 到 postman 我发送 Authorization
和uid
到请求 headers 和 body
将是 Form-Data 和 document
= binary file
.
下面是 document
键,我们可以在 Postman 中 select 文件 object。
现在这个 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
,当我选择任何文件时,我得到的 object 就像,
{
"size":1173,
"fileCopyUri":"file:///Users/Local_File_Path.plist",
"name":"File_Name.plist",
"uri":"file:///Users/Local_File_Path.plist"
}
我需要通过 API 调用 /adDocument
端点上传此文件(例如 plist),该端点期望请求 body 作为 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]), {'name': fileData.name});
//data.append('document', 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 };
}
}
使用上述任何方法 readStreamData
、readFileData
或 wrapData
,此功能总是失败。原因是,我永远无法将二进制数据传递到 document
.
我在请求中看到的body是这样的,
在这里,[object Object]
是一个字符串而不是 object,因此,我的 API 调用抛出错误说明,数据丢失。它总是传递我使用 'Blob()'.
所以,我想知道我在这里做错了什么,所以我的请求 body 没有传递二进制数据。请将有关该主题的任何指示发送给我,以便我找到解决方案。
那是 React-native debugger
的真正问题,而不是实际的实施问题。正如此处提到的 => https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md,调试器会乱用 FormData,并且由于 uri
属性.
[object Object]
字符串
我已关闭调试并在设备和模拟器上进行了尝试,以下代码按预期工作。 无需显式将文件转换为 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 };
}
}
就这么简单:)。