How to upload file using axios post request - node.js

I am trying to upload a file to url using axios post request. But i am getting 500 internal server error.
If the same request I tried from postman file gets uploaded with 200 status code.
I am not sure what should be the content-Type here.
here is my code.
const axios = require('axios')
var FormData = require('form-data');
var fs = require("fs");
var request = require('request');
const formData = {
file: fs.createReadStream('myfile.txt')
}
const config = {
headers: {
'Content-Type': 'multipart/form-data'
}
};
axios.post('myurl',formData,config)
.then((res) => {
console.log(`statusCode: ${res.status}`)
console.log(res.data)
})
.catch((error) => {
console.log(error)
})

Please check your frontend, when you click submit, do you call event.preventDefault();

const formData = {
file: fs.createReadStream('myfile.txt')
}
It's a plain javascript object, not a ready-to-use formData. You just forget to transform it into a real FormData object. Just check for the document of form-data module.
Also it seems that when you post a real FormData, the "Content-type" header is unnecessary as axios will automaticly handle it for you.

Related

Axios : send image with FormData on Prestashop API

I'm trying to upload on image on the Prestashop API with form-data/axios.
For that, i just need to send a post request with the images joined in an "image" parameter.
I did this simple node.js script (mine is much more complicated but i simplified for here):
const FormData = require("form-data");
const fs = require("fs");
const axios = require("axios");
// Read the image file into a buffer
const imageBuffer = fs.readFileSync("image.jpg");
// Create a FormData object
const form = new FormData();
// Append the image buffer to the form data
form.append("image", imageBuffer);
// Make an HTTP POST request to the PrestaShop API
axios({
method: "POST",
url: "https://XXX/api/images/products/15924",
data: form, // set the request body using the data field
params: {
ws_key: "XXX",
},
headers: {
"Content-Type": "multipart/form-data; boundary=" + form.getBoundary(),
},
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.error(error.response.data);
});
But i get this answer:
<message><![CDATA[Please set an "image" parameter with image data for value]]></message>
I tried a LOT of things. With fs.createReadStream instead of formData, with http instead of axios, with a buffer or a file, etc ... and i alway end with this error.
I would be glad if someone has an idea :-)
Thx !
I finally succeed!
Two changed were needed:
Adding the filename in the append (thanks Dmitriy Mozgovoy for pointing that out in the comment)
Adding the size in the headers with "Content-Length": formData.getLengthSync()
Without these 2 missing elements, it seems that PHP received an empty $_FILES variable.
Final version:
const FormData = require("form-data");
const fs = require("fs");
const axios = require("axios");
// Read the image file into a buffer
const imageBuffer = fs.readFileSync("image.jpg");
// Create a FormData object
const form = new FormData();
// Append the image buffer to the form data
form.append("image", imageBuffer, "image.jpg");
// Make an HTTP POST request to the PrestaShop API
axios
.post("https://example.com/api/images/products/15924", form, {
params: {
ws_key: "EXAMPLE",
},
headers: {
...form.getHeaders(),
"Content-Length": form.getLengthSync(),
},
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.error(error.response.data);
});

"Failed to read the requ est form. Missing content-type boundary.". Axios. React. Node, express

I am sending a request from the react to my backend. And from my backend I am already sending a request to another backend(asp .net). I get this error: {"":["Failed to read the requ
est form. Missing content-type boundary."]}. All data must be form data
const express = require('express');
const router = express.Router();
const axios = require("axios");
let FormData = require("form-data");
router.post('/proctoring', async (req, res) => {
let form = new FormData();
form.append("TestId", 120521);
const result = await axios("https://dashboard.curs.kz:8023/api/Tests/ProctoringFiles", {
method: "POST",
headers: { 'Authorization': req.headers['authorization'], 'Content-Type': 'multipart/form-data' },
data: JSON.stringify(form)
}).catch(e => console.log(JSON.stringify(e.response.data), "error"));
console.log(result);
});
module.exports = router;
if i remove JSON.stringify it's also will not working
Content-Type': 'multipart/form-data'
data: JSON.stringify(form)
To send multipart data:
Pass a FormData object to data. Do not pass a string.
Do not specify a content type. The browser will generate from the FormData object (and it will include the mandatory boundary parameter.
To send JSON data:
Set the correct content-type (application/json)
Generate the JSON from a plain object and not a FormData object (which won't stringify)

send formData POST request with nodejs

I want to send a post request that contain a form data, i want to do that from nodejs to another external api, i don't have the front-end to send the formData, so all i have a javascript object that has keys and values, so how can i do that?, when i tried sending a normal object, i didn't get the right api response, but when i sent it with a POSTMAN client, i got the correct response.
If you have a correct result in Postman, it's interesting to use the code generator in the same tools to have the desired code :). The button "</>" is on the right bar of the screen.
Here is the code generated from the tool :
var axios = require('axios');
var FormData = require('form-data');
var data = new FormData();
data.append('data', 'asldkfjalsdkjf');
var config = {
method: 'post',
url: 'https://some-domain.com/formdata',
headers: {
...data.getHeaders()
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
It's cool, isn't it?
One more thing, you have many options from NodeJS to C#, PHP.. :)
So you want to make a post request with nodejs? In order to do so, you can use the axios library and send the data in the following way.
const axios = require('axios');
let formData = new FormData();
formData.append('x': 'some test data');
axios({
method: 'post',
url: 'https://stackoverflow.com/posts/67709177',
data: formData,
headers: { 'Content-Type': 'multipart/form-data' },
})
.then(res => {
console.log(`statusCode: ${res.statusCode}`)
console.log(res)
})
.catch(error => {
console.error(error)
})
You can install axios using this command.
npm i axios

Required request part 'config' is not present node-fetch

I'm trying to convert this curl command to a node fetch request.
curl -X POST http://localhost:7200/test -H 'Content-Type: multipart/form-data' -F "config=#test.ttl"
What I have so far sends the file as formdata via a POST request, just like the curl request. However, I am not sure how to include the config=#test.ttl in the request. I tried adding it to a headers object and I got back invalid characters errors so I am not sure where to put it. When I run the request the way it is below. I get back 'Required request part 'config' is not present' so it is definitely required to put the config somewhere.
const fetch = require("node-fetch");
const FormData = require('form-data');
const form = new FormData();
form.append('test.ttl', 1);
fetch('http://localhost:7200/test', {
method: 'POST',
body: form
})
.then(res => res.json())
.then(json => console.log(json));
Thanks
Thanks #bato3!
Creating a readStream for the data in the file worked. Posting the working code below if anyone wants to reference it in the future.
const fetch = require("node-fetch");
const fs = require('fs');
const FormData = require('form-data');
const form = new FormData();
form.append('config', fs.createReadStream('test.ttl'));
fetch('http://localhost:7200/test', {
method: 'POST',
body: form
})
.then(res => res.text())
.then(body => console.log(body));

How to post form data using Axios in node

EDIT Changing the title so that it might be helpful to others
I am trying to upload an image to imgbb using their api using Axios, but keep getting an error response Empty upload source.
The API docs for imgbb shows the following example:
curl --location --request POST "https://api.imgbb.com/1/upload?key=YOUR_CLIENT_API_KEY" --form "image=R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
My node code to replicate this is:
const fs = require('fs')
const FormData = require('form-data')
const Axios = require('axios').default
let file = '/tmp/the-test.png'
let url = 'https://api.imgbb.com/1/upload?key=myapikey'
var bodyData = new FormData();
let b = fs.readFileSync(file, {encoding: 'base64'})
bodyData.append('image', b)
Axios({
method: 'post',
url: 'url',
headers: {'Content-Type': 'multipart/form-data' },
data: {
image: bodyData
}
}).then((resolve) => {
console.log(resolve.data);
}).catch(error => console.log(error.response.data));
But I keep getting the following error response..
{
status_code: 400,
error: { message: 'Empty upload source.', code: 130, context: 'Exception' },
status_txt: 'Bad Request'
}
Not sure exactly where I am failing.
For the sake of completion and for others, how does the --location flag translate to an axios request?
The issue was in the headers. When using form-data, you have to make sure to pass the headers generated by it to Axios. Answer was found here
headers: bodyData.getHeaders()
Working code is:
const fs = require('fs');
const FormData = require('form-data');
const Axios = require('axios').default;
let file = '/tmp/the-test.png';
var bodyData = new FormData();
let b = fs.readFileSync(file, { encoding: 'base64' });
bodyData.append('image', b);
Axios({
method : 'post',
url : 'https://api.imgbb.com/1/upload?key=myapikey',
headers : bodyData.getHeaders(),
data : bodyData
})
.then((resolve) => {
console.log(resolve.data);
})
.catch((error) => console.log(error.response.data));

Resources