I have 2 nodeJS services and I would want to upload file in a dir, from one NodeJS (backend) to another NodeJS(backend). The receiver nodeJS is an express app.
Looking for some working code sample.
PS: Couldn't find any code samples in search, since everywhere it was Multer from client to server uploads that receives multipart/form-data.
Uploading file using POST request in Node.js
Receive the file first as you correctly said using Multer. Then, you may either save the file to a temporary directory before uploading it again or just send the file as-is.
You need to setup a server running with Multer on the 2nd server that wishes to receive the file.
const express = require('express');
const app = express();
const upload = multer({ dest: 'files/' });
app.post('/upload', upload.single('file'), (req, res) => {
res.sendStatus(200);
});
app.listen(3001);
Then on the server you wish to send the file from, do something like this:
const request = require('request');
const req = request.post('localhost:3001/upload', (err, res, body) => {
if (err) throw new Error(err);
if (res && res.statusCode == 200) {
console.log('Success');
} else {
console.log('Error');
};
});
const form = req.form();
form.append('file', fs.createReadStream('./location/to/file'));
Related
for storage space issues i cannot save images in server so i had to store it in cloudinary
and for seo purposes I had to serve it from my domain not cloudinary's
so i thought to get img files from cloudinary and send it directly to browser (to be served from my domain name )
what i am missing is converting the img file i got from cloudinary api into the right form so i can send it using response object in nodejs
here is the code
app.get('/uploads/img/:imgName', (req, res) => {
axios.get('https://res.cloudinary.com/dkhccaa25/image/upload/blog_img/${req.params.imgName}')
.then(response => {
console.log(response);
/* how to convert response into the right format so it can be sent */
//
//
//
})
.then (response => {
/*converted response */
res.sendFile(response)
})
.catch(error => {
console.log(error);
});
how I can be able to send the file from node server to browser so it can be displayed using
<img src="img url...">
You do not have to use res.sendFile, this will require saving it to the filesystem. Basically - accept the response and pass it directly with the correct content-type header send by the upstream response to the client.
Minimal example:
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/', (req, res) => {
axios.get('https://static.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg').then((axiosResp) => {
res.header('content-type', axiosResp.headers['content-type']).send(axiosResp.data);
});
});
app.listen(3000);
finally the problem solved by editing on #madflow answer (thanks for him )
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/', (req, res) => {
axios.get('https://static.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg', {responseType: 'stream'})
.then((axiosResp) => {
res.set({
'Content-Type': axiosResp.headers['content-type']
})
axiosResp.data.pipe(res)
});
});
app.listen(3000);
I'm having a headache trying to upload files to a Node server from an Angular 6 app. I have the following route handler in the Node app:
var express = require('express');
var router = express.Router();
// Route for /fileupload
//****************************************************************
// Multer module for uploading files
var multer = require('multer');
// set the directory for the uploads to the uploaded to
var DIR = './uploads/';
var upload = multer({ dest: DIR }).single('cloudImg');
router.post('/', (req, res, next) => {
var path = '';
upload(req, res, function(err) {
console.log('REQ HEADER', req.headers);
if (err) {
// An error occurred when uploading
console.log(err);
return res.status(422).send("an Error occured")
}
// No error occured.
path = req.file.path;
return res.send("Upload Completed for " + path);
});
});
module.exports = router;
I use the multer module for uploading the file. If I call the API from Postman, everything works fine:
But if I send the file from the Angular app, the Node server crashes giving this error: TypeError: Cannot read property 'path' of undefined.
I've realised that Postman sets this content-type header:
'content-type': 'multipart/form-data; boundary=--------------------------719034023986440712074389'
I'm pretty sure that the error happens because the Node server is expecting another type of data and it can't create the req.file object. I know how to set the content-type header, but how could I generate the boundary field? Or, is there any way to tell Angular httpClient methods to autogenerate the header for this case?
Thanks,
I want to make user able to download a youtube video using node-ytdl.
For example when client side make a GET request for certain route the video should be downloaded in response.
var ytdl = require('ytdl-core');
var express= require('express');
//Init App Instance
var app=express();
app.get('/video',function(req,res){
var ytstream=ytdl("https://www.youtube.com/watch?v=hgvuvdyzYFc");
ytstream.on('data',function(data){
res.write(data);
})
ytstream.on('end',function(data){
res.send();
})
})
Above is my nodejs code. Even though in network it seems to download the response it does not make user download as a file.I don't want to store any file on server.It would be great if someone could help me how to solve the issue.
res object is a writable stream so you can directly pipe the output of ytdl to res object like this -
ytdl("http://www.youtube.com/watch?v=xzjxhskd")
.on("response", response => {
// If you want to set size of file in header
res.setHeader("content-length", response.headers["content-length"]);
})
.pipe(res);
You have to also pass the headers. Try it:
app.get('/video', (req, res) => {
var url = "https://www.youtube.com/watch?v=hgvuvdyzYFc";
res.header("Content-Disposition", 'attachment; filename="Video.mp4');
ytdl(url, {format: 'mp4'}).pipe(res);
});
If someone is still getting an error just update the package to latest version by running:
npm i ytdl-core#latest
Ok, so make a string var, then add data to it on the data event. On end, send everything. Here is an example:
const ytdl = require("ytdl-core"),
app = require("express")();
app.get("/video", (req, res) => {
let data = "", vid = ytdl("https://www.youtube.com/watch?v=hgvuvdyzYFc");
vid.on("data", d => data += d);
vid.on("end", () => res.send(data));
res.header("Content-Disposition", 'attachment; filename="Video.mp4');
});
I have an express nodeJS application that uploads and XLSX file and displays it content. The code in app.js is as following :
var express = require('express')
var multer = require('multer')
var app = express()
var upload = multer({ dest: 'uploads/' })
//Upload XLSX file
app.post('/upload', upload.single('xlsx_file'), function (req, res, next) {
if (req.file === undefined) {
console.log("Error");
} else {
var mimetype = req.file["mimetype"];
if (mimetype === "application/vnd.ms-excel.12" || mimetype === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
var path = req.file["path"];
readXLSX(path, function (response) {
console.log(response);
});
} else {
console.log("Only Excel (2007) xslx files are allowed!</strong></p>");
}
}
});
I'm using PM2 advanced process manager to run my application for ever, when I do pm2 start all and try to upload a file I get :
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request POST /upload.
Reason: Error reading from remote server
Additionally, a 502 Bad Gateway error was encountered while trying to use an ErrorDocument to handle the request.
when I run the app in debug mode with DEBUG=myapp:* npm start the upload works fine.
Any idea why this is happening?
Thanks
is it possible for the client to directly push a file onto our servers via API? How about pushing a file from our server to another again via API?
Right now my servers go out and grab files from locations via 'get'. This isn't the most efficient potentiality and there are reasons to believe I won't be able to access all files directly via get.
For sending you can use the request module's form feature to upload files.
var formData = {
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
};
request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
For receiving files in node you can use something like express with multer:
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})