I would like to upload a remote image to my own server using Node and the request module. I've figure out how to upload local images using the following code:
var options = {
url: 'https://myownserver.com/images'
};
var req = request.post(options , function optionalCallback(err, httpResponse, body) {
console.log('Upload successful! Server responded with:', body);
});
var form = req.form();
form.append('file', fs.createReadStream(__dirname + '/testimg.png'));
What modifications would I need to make to this code to be able to upload a remote image? This is the image I have been working with: https://www.filepicker.io/api/file/egqDUkbMQlmz7lqKYTZO
I've tried using fs.createReadStream on the remote URL, but was unsuccessful. If possible, I would prefer not having to save the image locally before uploading it to my own server.
This is a piece of code I'm using with a scraper. I'm using the callback here so I can use this as the location when saving to my model. I'm putting the location of your image below, but in my code I use req.body.image.
var downloadURI = function(url, filename, callback) {
request(url)
.pipe(fs.createWriteStream(filename))
.on('close', function() {
callback(filename);
});
};
downloadURI('https://myownserver.com/images', __dirname + '/testimg.png', function(filename) {
console.log(done);
}
Related
How do I create a file in express and node on my server and then download it to my client. I am using NextJS for my frontend and backend. I am confused on how I would download the file on the front end after the file is created on the root of the server folder. Since I am using React for my frontend whenever I try to visit that filepath it tries to take me to a page instead of the file
Here is what I have in my express route in node
var xls = json2xls(json, {
fields
});
// If there isn't a folder called /temp in the
// root folder it creates one
if (!fs.existsSync('./temp')) {
fs.mkdirSync('./temp');
}
const fileName = `temp/${req.user.first_name}${req.body._id + Date.now()}.xlsx`
// fs.writeFileSync(fileName, xls, 'binary');
fs.writeFile(fileName, xls, 'binary', function (err, result) {
if (err) {
return console.log(err);
}
console.log(result, 'this is result')
});
Here is what I have on my frontend
axios.post('api/download',payload)
.then(res => {
const link = document.createElement('a');
link.href = res.data.url;
link.download
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(err => {
throw err
})
Can you make request with GET on api, and.
Make request with GET.
Make temp directory to be static resources directory:
app.use(express.static('temp')); // app is your express instance.
// Maybe you have to correct temp's path
Response the post request with file url data
fs.writeFile(fileName, xls, 'binary', function (err, result) {
if (err) {
return console.log(err);
res.status(500).json({err});
}
console.log(result, 'this is result');
res.json({url: 'http://localhost:8080/temp/' + fileName}); // res is response object of you router handler.
// Maybe you have correct the server address
});
On other way, you can send the xls binary direct to client, in the client you create a BLOB object from the response, then create download link for the blob object.
I am working on nodeJs and React, I have data in mysql storage.
ultimately i need to let the user to download the data in excel format.
Either we can do in nodeJs or React.
I tried to create a file in Node using excel4node package, The file gets created successfully, but when i send the file, it is not in excel format(some xml files and folders), i used downloadJs in frontend to trigger autoDownload.
router.get('/:year/:month', async (req, res, next) => {
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
res.setHeader('Content-Disposition', 'attachment; filename=' + 'Report.xlsx');
res.sendFile(path.resolve('downloads/excel.xlsx'));
});
import downloadjs from 'downloadjs';
export const getReport = async (year, month) => {
let res = await fetch(`${url}/get-report/${year}/${month}`, {
method: 'GET',
mode: 'cors',
})
let blob = await res.blob();
await downloadjs(blob);
};
This downloads a zip folder which has list of xml files.
I tried to create in React (client side) by sending json from the backend,
for this i used react-excel-workbook package, but it needs a predefined data, when we click, it suddenly gets downloaded with dummy data and it doesn't wait for async action to resolve.
Any help will be appreciated.
Or should i send the json from backend and on client side (convert it into csv and trigger download.??
Write the file directly to the Response object, instead of going through an intermediate file
var xl = require('excel4node');
var wb = new xl.Workbook();
// sends Excel file to web client requesting the / route
// server will respond with 500 error if excel workbook cannot be generated
var express = require('express');
var app = express();
app.get('/', function(req, res) {
wb.write('ExcelFile.xlsx', res);
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
Late answer but you should specify content type when you are creating the blob in your frontend, then create a link in your DOM and specify to browser that the file must be downloaded :
axios.get(`${your backend url goes here}/path/to/export`, {
responseType: 'blob',
headers: {
'Authorization': `Bearer ${token}` //Or any auth method
}
}).then(res => {
const url = window.URL.createObjectURL(new Blob([res.data]), {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}); //specify CT
const link = document.createElement('a'); // attach link to DOM
link.href = url;
link.setAttribute('download', 'File.xlsx');
document.body.appendChild(link);
link.click(); // Auto dl the file
link.remove(); // Remove the link
}).catch(err => {
console.log(err);
})
I'm trying to download an image from my server using request.
I've managed to download something but i get more data than the image.
function _download(uri, save_as, destination) {
let options = {
uri: uri,
timeout: 100000,
followAllRedirects: true
};
return new Promise(( _resolve,_reject) => {
let ext, filename, bar, total, downloaded, req;
req = request(options).on('response', (resp) => {
if (resp.statusCode === 200){
ext = _getFileType(resp.headers['content-type']);
filename = destination+'/'+save_as+ext;
var stream = fs.createWriteStream(filename)
resp.pipe(stream).on('error',function(err){
_reject(err);
}).on('finish',function(){
_resolve(filename);
});
} else {
_reject("unable to download image %s",uri);
}
}).on('error', function(err) {
console.log(err)
_reject(err);
})
});
}
My original url is in form of https://www.test.com/image/original/12345, my server than redirects with a 301 status to my s3 bucket where image is stored.
Unfortunately due to the url of the image i have to wait that for the response header content type to determinate what kind of image it's and use it to pipe the image.
Everything works quite as expected... but i get more data than what is stored in s3.
Does anyone have any suggestion ?
please refer to the link below
var fs = require('fs'),
request = require('request');
var download = function(uri, filename, callback){
request.head(uri, function(err, res, body){
console.log('content-type:', res.headers['content-type']);
console.log('content-length:', res.headers['content-length']);
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
download('https://www.google.com/images/srpr/logo3w.png', 'google.png', function(){
console.log('done');
});
please visit this link
And this link also
On my node express server, I am receiving a pdf file. I am using the below code to get the pdf contents from the request
var data = new Buffer('');
request.on('data', function (chunk) {
data = Buffer.concat([data, chunk]);
});
request.on('end', function() {
console.log('PDF data is '+JSON.stringify(data));
});
Now that PDF content is available on node, I need to send it as it is to a J2EE server. In order to do that, I am first saving the PDF file in the node server, reading it from the node server and then piping it to request.post (https://github.com/request/request)
var req = require('request');
fs.writeFile('abc.pdf', data, 'binary', function(err) {
if (err) {
console.log('Error ' + JSON.stringify(err) );
throw err;
}
var source = fs.createReadStream('abc.pdf');
//send our data via POST request
source.pipe(req.post('http://'+j2ee_host+':'+j2ee_port+'/myjavaapp/Upload')
});
This works fine. However, I feel the part of saving the PDF file on the node server and then reading it is (before posting to the J2EE server using request module) is completely unnecessary, as I am not making any changes to the file.
Once I have the PDF contents in 'data' variable, I would like to directly post them to the J2EE server. However, I have not been able to find a way to use the request module to directly post file contents. I have seen some examples related to POST using request module but they refer to formData. In my case, I don't have formData but instead reading the file from request and directly posting it to the J2EE server.
Is there a way to achieve this and avoid the file write and read?
EDIT
Below is my complete code
function upload(request, response) {
var data = new Buffer('');
request.on('data', function (chunk) {
data = Buffer.concat([data, chunk]);
});
request.on('end', function () {
fs.writeFile('abc.pdf', data, 'binary', function(err){
if (err) {
console.log('Error ' + JSON.stringify(err) );
throw err;
}
var source = fs.createReadStream('abc.pdf');
source.pipe(req.post('http://'+j2ee_host+':'+j2ee_port+'/myj2eeapp/Upload'));
})
})
}
You can pipe directly from the data request to the servlet
var req = require('request');
function upload(request, response) {
var target = req.post('http://'+j2ee_host+':'+j2ee_port+'/myjavaapp/Upload');
request.pipe(target);
target.on('finish', function () {
console.log('All done!');
//send the response or make a completed callback here...
});
}
I have an express based server side script to upload images and it works fine if I use a html form for uploading. Now, I don't want to use this form and I want to upload files that are stored in filesystem via fs library. I want to do it with another different nodejs script.
Is this possible?
I'll suggest to check request module or specifically this part of the documentation https://github.com/mikeal/request#forms
Here is an example:
var r = request.post('http://service.com/upload', function optionalCallback (err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
})
var form = r.form()
form.append('my_field', 'my_value')
form.append('my_buffer', new Buffer([1, 2, 3]))
form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png')))
form.append('remote_file', request('http://google.com/doodle.png'))