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));
Related
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);
});
I am working with an api that requires me to send png files as binary data to my backend. In their docs they show how to do this with a curl example ( I have never used curl ) but they dont show how to do this with axios to a node.js server ( despite examples of node.js on everything else).
How would I convert this following example of a curl to post request to a node.js server?
I am using axios and react for the front end and Node.js for backend.
Here is the curl example, How would I do this in axios?
Also, How do I convert a .png file to binary data in React before sending post request with axios?
curl -u "<account_sid>:<account_secret>" --data-binary #<filename.png> -H "Content-Type: <content-type of upload>" https://mcs.us1.twilio.com/v1/Services/<chat_service_sid>/Media
You can convert your cURL requests with this utility: https://kigiri.github.io/fetch/
Yours in particular will look like this, and fetch and axios are nearly identical:
fetch("https://mcs.us1.twilio.com/v1/Services//Media", {
body: "#<filename.png>",
headers: {
Authorization: "Basic PGFjY291bnRfc2lkPjo8YWNjb3VudF9zZWNyZXQ+",
"Content-Type": "<content-type of upload>"
},
method: "POST"
})
You can read this article here.
By MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs/promises');
// Read image from disk as a Buffer
const image = await fs.readFile('./stickers.jpg');
// Create a form and append image with additional fields
const form = new FormData();
form.append('productName', 'Node.js Stickers');
form.append('productDescription', 'Cool collection of Node.js stickers for your laptop.');
form.append('productImage', image, 'stickers.jpg');
// Send form data with axios
const response = await axios.post('https://example.com', form, {
headers: {
...form.getHeaders(),
Authentication: 'Bearer ...',
},
});
You can convert any curl into httpRequest using
https://curlconverter.com/#javascript
and read about curl information from
https://everything.curl.dev/http/post
for your curl
curl -u "<account_sid>:<account_secret>" --data-binary #<filename.png> -H "Content-Type: " https://mcs.us1.twilio.com/v1/Services/<chat_service_sid>/Media
`fetch('https://mcs.us1.twilio.com/v1/Services/<chat_service_sid>/Media', {
method: 'POST',
headers: {
'Content-Type': '<content-type of upload>',
'Authorization': 'Basic ' + btoa('<account_sid>:<account_secret>')
},
body: '<filename.png>'
});`
You can try to use FileReader to read the given file as binary and send it using fetch/axios.
Second, the curl's -u "<account_sid>:<account_secret>" sends Authorization header. You can simply use btoa(username + ':' + 'password') to achieve that.
Here's an example using fetch and FileReader.
import React, {useState} from 'react';
function FileUploadComponent(){
const [selectedFile, setSelectedFile] = useState();
const changeHandler = (event) => {
setSelectedFile(event.target.files[0]);
};
const handleSubmission = () => {
const reader = new FileReader();
reader.onload = (event) => {
const url = 'https://mcs.us1.twilio.com/v1/Services/<chat_service_sid>/Media';
const headers = {
Authorization: "Basic " + btoa(username + ":" + password),
'Content-Type': selectedFile.type
}
fetch(url, { method: 'POST', body: event.target.result, headers })
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});
};
reader.readAsBinaryString(selectedFile)
};
return (
<div>
<input type="file" name="file" onChange={changeHandler}/>
<div>
<button onClick={handleSubmission}>Submit</button>
</div>
</div>
)
}
Here's some useful links:
https://tr.javascript.info/fetch-basics#submit-an-image
https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString
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.
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));
I am creating a task to send a PUT request and upload a .pot file using axios in node.
I can run
curl -i -u api:<api-key> -F file=#dist/file.pot https://api-link.com/v2/api
and it'll work fine
I have tried doing this in node
var fd = require('form-data');
var axios = require('axios');
var form = new FormData();
form.append('file', 'dist/file.pot');
var header = { headers: Object.assign({}, apiToken(), form.getHeaders()) };
axios.put('https://api-link.com/v2/api/', form, header)
.then(function(res) {
console.log(res);
})
.catch(function(err) {
console.log(err);
})
and this doesn't work like the curl command. apiToken() is a function to handle the -u api:<api-key> part of the curl command, and it returns {'Authorization': 'Basic <api-key>'}. I've checked that the function works because I am able to successfully do a get request.
So what is the equivalent of -F file=#dist/file.pot in ajax or axios?
Try the below solution:
var options = {
headers: Object.assign({'Content-Type': 'multipart/form-data'}, apiToken(),
form.getHeaders())
};
axios.post('https://api-link.com/v2/api/', formData, options)
Also check if the content-type header is being set as multipart/form-data or not.