Reactjs Nodejs file upload ftp via axios - javascript

I am trying to upload file using React Dropzone on ftp with Reactjs + AXIOS at front end, Nodejs + connect-multiparty at back end.
The problem is when I am sending file via front end using AXIOS, I am not getting the file at server in request.
My code to upload file using react-axios is
let data = new FormData()
data.append('file', file)
var setting = {
method: 'post',
url: 'my-server-url',
data:data,
headers: {
'Content-Type': 'multipart/form-data'
},
}
var response = axios(setting).then(response => { return response.data })
.catch(response => response = {
success: 500,
message: "Your submission could not be completed. Please Try Again!",
data: ""
});
while using postman, everything works fine. Server side api is working. only problem with client side request code.
Any help!!!

This is a very rookie mistake you're making probably because of the fact that you don't understand the way multipart works. For your client-side code to work, i.e form-data to be sent back to the backend, you need to:
Either remove the header and let the browser choose the header for you based on your data type
Or when using 'Content-Type': 'multipart/form-data', add a boundary to it
Multipart boundary looks like this,
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryABCDEFGHIJKLMNOPQRSTUVWXYZ'
Simply doing the following will solve the issue for you as the browser will take care of the headers needed.
axios.post('your-server-url', data).then(....)

Related

JavaScript - Axios POST request empty form data (request payload)

I have a Vue.js app which uses axios to interact with a Laravel API. I'm trying to make a POST request with an image file in it to upload in the backend.
The issue I'm having is that axios makes the POST request with empty payload.
I've tried sending it both as a plain JS object and with FormData. In both cases the request payload is empty. I've looked on the internet for hours but I was unable to find anything while trying to tackle the issue in the past few days...
This is how I make the request:
let fd = new FormData();
fd.append('file', this.file);
console.log(...fd) //shows the file is there with its data
axios
.post("/api/images", fd)
.then(response => {
//Handle success
})
.catch(errors => {
//Catch errors
});
This is how I get the file from the form:
let selectedImage = this.$refs.fileInput.files[0];
const reader = new FileReader();
reader.addEventListener('load', (event) => {
this.file = event.target.result;
});
reader.readAsDataURL(selectedImage);
I've tried experimenting with the request headers and at the moment they are as follows:
"Accept" : "application/json",
"Content-Type": "multipart/form-data; charset=utf-8; boundary=" + Math.random().toString().substr(2),
"Authorization": "Bearer " + this.user.api_token,
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content
The responses from Laravel are always that the file is required (as expected when it's indeed missing).
I did try encoding the file in Base64 but I have trouble validating that it's an image in the backend.
I found this similar question but it wasn't of any help: FormData sends empty data using axios
I want to send a file + JSON data but I'm ok with just making the file upload work. So... How do I send a file from Vue.js app to Laravel API using Axios? What am I doing wrong?

Send file with form-data and axios

I am trying to send a video to a videosite, I am able to upload the video using the REST api and postman, so I know the api works as intended. Now I want to do exatcly the same request using axios. I have code that looks like the example on how to use form-data and axios:
const form = new FormData();
const stream = fs.createReadStream(PATH_TO_FILE);
form.append('image', stream);
// In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders`
const formHeaders = form.getHeaders();
axios.post('http://example.com', form, {
headers: {
...formHeaders,
},
})
.then(response => response)
.catch(error => error)
I get the error that data: 'Content-Length is required'
Any ideas?
May be I got your questions wrong , you want to add Content-Length in the header.
I can see you are uploading video stream. So first you have to calculate the data chunk length.
('Content-Length', File.getSize(stream))
Reference: Can I stream a file upload to S3 without a content-length header?
You can make the post request as multi-part type : 'Content-Type': 'multipart/form-data'.
It is preferable way to send large data to server.
You can check this link : How do I set multipart in axios with react?
If I got your question wrong , plese comment or reply . Thanks
The solution to my problem was to set Content-Length accordingly:
"Content-Length": fs.statSync(filePath)['size']
I think the best way to handle this is to actually use the FormData's own method:
const headers = { 'content-length': formData.getLengthSync(), ...formData.getHeaders() }
This will be more accurate because it includes any other data you may add.
To expound, if you are using a ReadStream, you must use the async function instead.
const { promisify } = require('util')
const getLength = promisify(formData.getLength.bind(formData))
const contentLength = await getLength()
const headers = { 'content-length': contentLength, ...formData.getHeaders() }

Upload local file with fetch / content-type: octet-stream

I am currently developing a Sketch Plugin, where an image gets sent to the Microsoft Custom Vision API for object detection.
The Sketch Plugin itself is written in Javascript, a fs polyfill and a fetch polyfill is available. An API call with an image url works perfectly fine. However, I have trouble sending a local file from my computer as I am not 100% how I can access it.
var templateUrl = require('../assets/test.png').replace('file://', '');
var file = fs.readFileSync(templateUrl);
var request = postData('https://southcentralus.api.cognitive.microsoft.com/customvision/v2.0/Prediction/XXXXXXX/image');
request.then(data => data.json()).then(data => myFunction(data));
// post request with file
function postData(url, data) {
return fetch(url, {
method: 'POST',
headers: {
'Prediction-Key': 'XXXXXXXXXX',
'Content-Type': 'application/octet-stream',
},
body: file,
})
}
Does anyone have experience with sending local files to the image recognition API? Any help would be very much appreciated!
Thanks in advance!
Best, C

Send data in post method to an api in node js

I want to send some post data to an api
10.11.12.13/new/request/create
this is an API to create a new request in portal. now I am making one application in NodeJs and want to create request from node js application.
now I have to send in this format
{"user":"demo", "last_name":"test","contact":"989898989"}
so how can I send data on above url to create a new request.
I am a beginner in NodeJs and don't have much idea.
any help will be appreciated.
Thanks in advance
I would recommend to use axios or any other request lib :
const axios = require('axios');
axios.post('10.11.12.13/new/request/create', {
user: 'demo',
last_name: 'test',
contact: '989898989',
});
here is an example using request module
var headers = {
'Content-Type': 'application/json'
}
var options = {
url: "10.11.12.13/new/request/create" ,
method: 'POST',
headers: headers,
json: true,
body: {user:"demo", last_name:"test",contact:"989898989"}
}
request(options, function (error, response, body) {
if (error) {
//do something
}
console.log(body)//do something with response
})
You can use postman REST client for GET method using your URL and Body (which you want to post) and click on * Code * and select NodeJS and their you will find code generated for you to work with. Here is the link https://www.getpostman.com/docs/postman/sending_api_requests/generate_code_snippets
With my experience, it is good to start with Request package for node js. Here is the link for your reference: https://www.npmjs.com/package/request

Request.post on already uploaded image file

I am using Angularjs and nodejs in the project and working on file uploads. I want to send the post request to the url endpoint in a secure way as I need to attach accesstoken with the request. So the way I did this was, I added the directive to choose the file from UI and once it gets the file, I append it using FormData() like this in the controller
var fd = new FormData();
fd.append('file',myFile);
and sending this formdata object to the nodejs server like mentioned here http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
expect this request will be going to my nodejs server url from there I will be making another post request to external web service
$http.post('api/collections/upload',fd, {
transformRequest: angular.identity,
headers: {
'Content-type': undefined
}
});
So it will attach the right content-type and boundaries in the request. I am getting the file on server side nodejs when I do
function(req,res){
console.log(req.files); //I am able to see the file content
}
It is uploaded on the nodejs server side.
Now I want to make a post request using the req.files to a different endpoint along with proper accessToken and headers. Tried many things but not able to make the request go thru. Not sure how can I attach the imagedata/ req.files along with the request. I tried these two things mentioned in request npm module https://www.npmjs.org/package/request
1)
request.post({
url: 'https://www.example.com/uploadImage',
headers: {
'Authorization': <accessToken>,
'Content-type': 'multipart/form-data'
},
body: req.files
});
Don't know how can I attach and binary data with this request and how can I put boundary. Is boundary needed when you want to send the uploaded image with this request?
2)
fs.createReadStream(req.files.file.path, {encoding: base64}).pipe(request.post({
url: 'https://www.example.com/uploadImage',
headers: {
'Content-type': 'multipart/form-data'
}
}));
Can someone please suggest some ideas on how can I send this post request using request npm module? Thanks.
Documentation here has lots of examples of doing exactly what you describe:
https://github.com/mikeal/request#streaming
As can be seen in that link, the request library adds a .pipe() method to your http's req object, which you should be able to use like the examples in the link:
function(req, res) {
req.pipe(request.post('https://www.example.com/uploadImage');
}
Or something similar.
You were nearly there with your #2 try, but that would only work if you have previously written the file out to disk and were reading it in with fs.createReadStream()
your suggestion helped me to atleast know what I was trying was right. Another article that solved my problem was this http://aguacatelang.wordpress.com/2013/01/05/post-photo-from-node-js-to-facebook/ .Basically, here is what I did and it worked. Thanks for your suggestion.
var form = new FormData();
form.append('file', fs.createReadStream(__dirname + '/image.jpg'));
var options = {
url: 'https://www.example.com/uploadImage?access_token='+ <accesstoken>,
headers: form.getHeaders()
};
form.pipe(request.post(options,function(err,res){
if(err){
log.debug(err);
}
else {
log.debug(res);
}
}));

Categories

Resources