Upload image to a nodeJs server using react-native - node.js

I want to upload an image from react-native (cli without expo) to a node server, i tried using axios with formData filed is not recognised by multer, then i tried with fetch that worked image was stored in server but i get promise rejection on front:
const postDocument = (doc) => {
//i used react-native-document-picker to pick document(doc) i logged it and it works
const url =`${api}/sendImage`;
const formData = new FormData();
const id = uuid.v4()
formData.append('id',id)
formData.append('image', doc);
const options = {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
};
fetch(url, options).then((res)=>{
//getting promise rejection even without code but image is stored in backend
}).catch(error=>{})
}
getting this error : [TypeError: Network request failed]

using rn-fetch-blob (react-native-cli not expo-cli) instead of fetch or axios solved this for me

Related

How to send a file to backend in react-native using node.js

I tried
const myData = uri; // this looks like file:///data/expo/...
const myDataResponse = await API.SendFile({
myData: myData
});
But file is not being recieved in the backend. Is there any other way to do this?
IN the backend I get
console.log(req.body)
// I get a string same as uri of file
console.log(req.file)
// undefined
Backend is setup perfectly. I am getting successful response when using postman.
Any help is appreciated. I am a begginer.
You should use FormData.
const data = new FormData();
// first argument is the key name received on you API
// second argument is your file path
data.append('file', filePath)
// then your request should look like this :
await fetch(url, {
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
body: data,
})

Image upload in Nuxt.js using axios

I've tried almost every answer in relative questions, and couldn't find any solution to my case.
I'm new to Nuxt.JS, and I'm moving my project from Vue/CLI to Nuxt.js, now I'm stuck in sending POST request which contains images and data (FormData).
The FormData is appearing empty on the server side (Node.js)
The current working version of my code in Vue CLI:
const requestOptions = {
method: 'POST',
body: formData
};
return fetch(`/create`, requestOptions).then(handleResponse);
What I'm trying to achieve in Nuxt.JS (which is not working properly) by using nuxt/axios module:
methods: {
async sendRequest(){
let formData = new FormData();
formData.append('image',this.myFile);
formData.append('name',this.anyName);
var res = await this.$axios.$post('/create', formData);
}
}
EDIT: I tried to log the content before making the request like:
for (var pair of formData.entries()) {
console.log(pair[0]+ ' - ' + pair[1]);
}
And I can see the fields and values clearly as intended.
I've tried adding headers to the request:
this.$axios.$post('/create', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
But still getting: {} in Node.js while printing the request body.
What I'm doing wrong?

How can I send post request with base64 image?

I am making an image upload component in vue js with custom cropping option. The cropped version is being saved in my state as a base64 string. This is it:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAYAAAB91L6VAAAgAElEQVR4Xu2dCdh+1dT/v3+UDA1KMiQhlCEylDGZSqbI0Jy8JMmYUEloRFIpVJK5EpL0ilJmr6IQKiXzrCKESP2v72vfb8/z/O7hnH2fc/be53z2df2uoj1+9vrd6+y1117r/4kCAQhAAAIQgEDnBP5f5yMyIAQgAAEIQAACQgEjBBCAAAQgAIEEBFDACaAzJAQgAAEIQAAFjAxAAAIQgAAEEhBAASeAzpAQgAAEIAABFDAyAAEIQAACEEhAAAWcADpDQgACEIAABFDAyAAEIAABCEAgAQEUcALoDAkBCEAAAhBAASMDEIAABCAAgQQEUMAJoDMkBCAAAQhAAAWMDEAAAhCAAAQSEEABJ4DOkBCAAAQgAAEUMDIAAQhAAAIQSEAABZwAOkNCAAIQgAAEUMDIAAQgAAEIQCABARRwAugMCQEIQAACEEABIwMQgAAEIACBBARQwAmgMyQEIAABCEAABYwMQAACEIAABBIQQAEngM6QEIAABCAAARQwMgABCEAAAhBIQAAFnAA6Q0IAAhCAAARQwMgABCAAAQhAIAEBFHAC6AwJAQhAAAIQQAEjAxCAAAQgAIEEBFDACaAzJAQgAAEIQAAFjAxAAAIQgAAEEhBAASeAzpAQgAAEIAABFDAyAAEIQAACEEhAAAWcADpDQgACEIAABFDAyAAEIAABCEAgAQEUcALoDAkBCEAAAhBAASMDEIAABCAAgQQEUMAJoDMkBCAAAQhAAA....
now I am trying to send this image to my node js server using post request API. In Postman, I am writing the body selecting "raw" and "json" in this the body in this way:
{
"image" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAYAAAB91L6VAAAgAElEQVR4Xu2dCdh+1dT/v3+UDA1KMiQhlCEylDGZSqbI0Jy8JMmYUEloRFIpVJK5EpL0ilJmr6IQKiXzrCKESP2v72vfb8/z/O7hnH2fc/be53z2df2uoj1+9vrd6+y1117r/4kCAQhAAAIQgEDnBP5f5yMyIAQgAAEIQAACQgEjBBCAAAQgAIEEBFDACaAzJAQgAAEIQAAFjAxAAAIQgAAEEhBAASeAzpAQgAAEIAABFDAyAAEIQAACEEhAAAWcADpDQgACEIAABFDAyAAEIAABCEAgAQEUcALoDAkBCEAAAhBAASMDEIAABCAAgQQEUMAJoDMkBCAAAQhAAAWMDEAAAhCAAAQSEEABJ4DOkBCAAAQgAAEUMDIAAQhAAAIQSEAABZwAOkNCAAIQgAAEUMDIAAQgAAEIQCABARRwAugMCQEIQAACEEABIwMQgAAEIACBBARQwAmgMyQEIAABCEAABYwMQAACEIAABBIQQAEngM6QEIAABCAAARQwMgABCEAAAhBIQAAFnAA6Q0IAAhCAAARQwMgABCAAAQhAIAEBFHAC6AwJAQhAAAIQQAEjAxCAAAQgAIEEBFDACaAzJAQgAAEIQAAFjAxAAAIQgAAEEhBAASeAzpAQgAAEIAABFDAyAAEIQAACEEhAAAWcADpDQgACEIAABFDAyAAEIAABCEAgAQEUcALoDAkBCEAAAhBAASMDEIAABCAAgQQEUMAJoDMkBCAAAQhAAAWMDEAAAhCAAAQSEEABJ4DOkBCAAAQgAAEUMDIAAQhAAAIQSEAABZwAOkNCAAIQgAAEUMDIAAQgAAEIQCABARRwAugMCQEIQAACEEABIwMQgAAEIACBBARQwAmgMyQEIAABCEAABYwMQAACEIAABBIQQAEngM6QEIAABCAAARQwMgABCEAAAhBIQAAFnAA6Q0IAAhCAAARQwMgABCAAAQhAIAEBFHAC6AwJAQhAAAIQQAEjAxCA.....
}
The request not detecting this json data in the body and returning error:
{
"image": "\"image\" is required"
}
Also tried the form_data sending method in this way:
var axios = require('axios');
var FormData = require('form-data');
// var fs = require('fs');
var data = new FormData();
data.append('image', formdata.logoFinalImage);
var config = {
method: 'post',
url: myurl,
headers: {
'Authorization': this.state.token,
'Content-Type': 'application/json'
},
data: data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Same issue.
How can I send the final cropped version to the node api endpoint?
Solved the issue. There were two ways of doing it. One is required changes in the backend to configure the code in a way that can receive base64 and convert it to image. Reference: https://medium.com/js-dojo/how-to-upload-base64-images-in-vue-nodejs-4e89635daebc
Other is to make the base64 image file, and then send it to the backend as form-data. Used this one for my case. Reference of this solution: https://gist.github.com/ibreathebsb/a104a9297d5df4c8ae944a4ed149bcf1
if its working in postman then you can create the code from postman itself , select code and search for axios
v8<
if using v8

Get image from Axios and send as Form Data to Wordpress API in a Cloud Function

What I'm trying to accomplish is using a Firebase Cloud Function (Node.js) to:
First download an image from an url (f.eg. from unsplash.com) using an axios.get() request
Secondly take that image and upload it to a Wordpress site using the Wordpress Rest API
The problem seems (to me) to be that the formData doesnt actually append any data, but the axios.get() request actually does indeed retrieve a buffered image it seems. Maybe its something wrong I'm doing with the Node.js library form-data or maybe I get the image in the wrong encoding? This is my best (but unsuccessfull) attempt:
async function uploadMediaToWordpress() {
var FormData = require("form-data");
var formData = new FormData();
var response = await axios.get(
"https://images.unsplash.com/photo-1610303785445-41db41838e3e?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80"
{ responseType: "arraybuffer" }
);
formData.append("file", response.data);
try {
var uploadedMedia = await axios.post("https://wordpresssite.com/wp-json/wp/v2/media",
formData, {
headers: {
"Content-Disposition": 'form-data; filename="example.jpeg"',
"Content-Type": "image/jpeg",
Authorization: "Bearer <jwt_token>",
},
});
} catch (error) {
console.log(error);
throw new functions.https.HttpsError("failed-precondition", "WP media upload failed");
}
return uploadedMedia.data;
}
I have previously successfully uploaded an image to Wordpress with Javascript in a browser like this:
async function uploadMediaToWordpress() {
let formData = new FormData();
const response = await fetch("https://images.unsplash.com/photo-1610303785445-41db41838e3e?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80");
const blob = await response.blob();
const file = new File([blob], "image.jpeg", { type: blob.type });
formData.append("file", file);
var uploadedMedia = await axios.post("https://wordpresssite.com/wp-json/wp/v2/media",
formData, {
headers: {
"Content-Disposition": 'form-data; filename="example.jpeg"',
"Content-Type": "image/jpeg",
Authorization: "Bearer <jwt_token>",
},
});
return uploadedMedia.data;
},
I have tried the last couple of days to get this to work but cannot for the life of me seem to get it right. Any pointer in the right direction would be greatly appreciated!
The "regular" JavaScript code (used in a browser) works because the image is sent as a file (see the new File in your code), but your Node.js code is not really doing that, e.g. the Content-Type value is wrong which should be multipart/form-data; boundary=----...... Nonetheless, instead of trying (hard) with the arraybuffer response, I suggest you to use stream just as in the axios documentation and form-data documentation.
So in your case, you'd want to:
Set stream as the responseType:
axios.get(
'https://images.unsplash.com/photo-1610303785445-41db41838e3e?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80',
{ responseType: 'stream' }
)
Use formData.getHeaders() in the headers of your file upload request (to the /wp/v2/media endpoint):
axios.post( 'https://wordpresssite.com/wp-json/wp/v2/media', formData, {
headers: {
...formData.getHeaders(),
Authorization: 'Bearer ...'
},
} )
And because the remote image from Unsplash.com does not use a static name (e.g. image-name.jpg), then you'll need to set the name when you call formData.append():
formData.append( 'file', response.data, 'your-custom-image-name.jpeg' );
I hope that helps, which worked fine for me (using the node command for Node.js version 14.15.4, the latest release as of writing).

Issue uploading an image using axios

I'm trying to send an image to my server using axios with react-native.
For doing this, I'm passing the image data (the base 64 encoded image data) directly to an uploadPicture function which uses axios this way:
const uploadPicture = async (data): Promise<AxiosResponse<string>> => {
const response = publicApi.post(
`${API_URL}/upload`,
{
image: data,
},
{
headers: { 'Content-Type': 'multipart/form-data' },
transformRequest: [transformToFormData],
}
);
return response;
};
const transformToFormData: AxiosTransformer = data => {
const formData = new FormData();
for (const key in data) {
formData.append(key, data[key]);
}
return formData;
};
The issue I face :
I get an internal error, like if my image was not correctly transmitted through my request.
If I'm doing the exact same request using Postman, it works fine, setting the body like this :
Which make me think that the issue doesn't come from my server but from my axios request.
Any idea of what I could be doing wrong ? Am I missing any axios option somewhere ?
I managed to find a solution:
I used the fetch function from javascript instead of axios
I send a file object instead of the data directly
I had to disable the react-native network inspect, otherwise the upload won't work
My working solution below, image being the response of react native image picker:
const file = {
uri: image.uri,
name: image.fileName,
type: image.type,
size: image.fileSize,
slice: () => new Blob(),
};
const body = new FormData();
body.append('image', file);
const response = await fetch(`${API_URL}/upload`, {
method: 'POST',
body,
});

Resources