multer file-upload doesn't work with node-windows - javascript

I am trying to upload picture files, using multer.
This is is my code:
router.post('/', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
conole.log(err);
return;
}
// Everything went fine
var data = Object.assign({picture: req.file && req.file.filename}, req.body);
db.create('devices', data)
.then(function(data){
res.render('msg', {msg: 'Added device '+ data[0]});
})
.catch(function(err){
console.log(err);
});
});
});
However, when I try to run the server from the command-line node app.js, everything is working as expected. But when I'm running it from A windows service, using node-windows, it doesn't seem to work, while I don't get any errors. (Meaning the picture file name is actually recorded in the database, but the file doesn't upload.
is it maybe a destination issue? if so, I will provide my destination code:
var storage = multer.diskStorage({
destination: './public/uploads/',
filename: function (req, file, cb) {
cb(null, file.originalname + "-" + Date.now() + path.extname(file.originalname));
}
});

remove this line from your code
destination: './public/uploads/',
and add this code
destination: __dirname+'../../../uploads',
this will work both mac OS and windows

Related

Multer in Nodejs using Express Router req.file undefined

I am trying to implement File Upload functionality using multer and Express Router. I defined an endpoint /batch_upload using router.use like below
api.js
router.use(
"/batch_upload",
upload.single("emp_csv_data"),
userController.processBatchUserInformation
);
in userController.js
exports.processBatchUserInformation = async (req, res) => {
console.log(req.file);
if (req.method == "POST") {
try {
console.log("Upload route reached - POST");
console.log(req.file);
console.log(req.file.path);
return res.send(req.file);
} catch (err) {
console.log("Error Occurred");
return res.send(err);
}
}
};
In the FileUploader.js, I defined the upload variable and multer options like below
var multer = require("multer");
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads");
},
filename: (req, file, cb) => {
return cb(null, file.fieldname + "-" + Date.now());
}
});
exports.upload = multer({ storage: storage });
Finally, in the app.js I used the route using
app.use('/user',user_routes)
But when I send a file to http://localhost:5000/user/batch_upload, I get an undefined response for req.file
Irony is that I have the exact implementation in a sample test project and everything seems fine. I don't understand what am I missing. If you see something that seems off, please help me fix it.
So, the reason behind the file not being uploaded was that I did not add Content-type:multipart/form-data in the headers. Thank you guys for trying to help. I appreciate it.

How can I wait a Python shell to execute before serving file

I've an express server route which receives a xml file, then parses and return it as json.
When a user sends a file, it saves in a directory './upload', parses it with a Python script then output json in './json-output', which is served.
When I first upload a file, the response comes empty. But when I do the same upload steps (there is a json already created from last upload on './json-output' dir), it serves the json. It seems some asynchronous issue but I couldn't fix it.
app.post('/upload', function(req, res) {
upload(req, res, async function(err) {
if (err) {
res.json({ error_code: 1, err_desc: err });
return;
}
if (!req.file) {
res.json({ error_code: 1, err_desc: 'No file passed' });
return;
}
let fileName = req.file.originalname;
const options = {
args: [ fileName ]
};
const parserPath = path.join(__dirname + '/parser/parser.py');
const readFile = promisify(PythonShell.run);
await readFile(parserPath, options);
fileName = fileName.split('.')[0];
res.sendFile(path.join(__dirname + `/json-output/${fileName}.json`));
});
});
I'm running it inside a docker images
This a quite a "Dirty fix" in my eyes but you could do a while loop EG:
fileName = fileName.split('.')[0];
while (!fs.existsSync(path.join(__dirname + `/json-output/${fileName}.json`)){
console.log('File does not exist!')
}
//Becareful you should delete the file once the res.send is done
res.sendFile(path.join(__dirname + `/json-output/${fileName}.json`));
Decided to read the python-shell docs here an idea:
https://www.npmjs.com/package/python-shell#exchanging-data-between-node-and-python
So, in theory, you can start a new
let pyshell = new PythonShell(path.join(__dirname + '/parser/parser.py'),options);
pyshell.end(function (err,code,signal) {
if (err) throw err;
fileName = fileName.split('.')[0];
res.sendFile(path.join(__dirname + `/json-output/${fileName}.json`));
});

Sending file through HTTP request

I tried to receive the file and store it in the multer storage
Node js code
enter code here
app.post('/createLicence', upload.single('photo'),function(req, res ,next) {
// any logic goes here
console.log("filename" ,req.body.name)
if (!req.file) {
console.log("No file received");
return res.send({
success: false
});
} else {
console.log('file received');
var function_name = 'createLicence'
var arguments_array = [req.file.path,'Raghav','Mumbai','Approved']
invoke = require('/Users/sanjeev.natarajan/fabric-samples/fabcar/invoke.js');
invoke.invokechaincode(function_name,arguments_array)
return res.send({
success: true
})
}
});
but i am receiving no file is receivedi have send the request through postman
-
From : https://www.npmjs.com/package/multer
In order to use the multer package, you have first to define a few parameters so that it can work on your fileDirectory.
In your server.js :
let multer = require('multer');
let storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, '/path/to/storage/')
},
filename: function(req, file, callback) {
callback(null, file.originalname + '-' + Date.now());
}
});
let upload = multer({
storage: storage
});
Now, configure your route
router.route('/your/payload')
.post(authController.isAuthenticated, upload.any(), albumController.postFile)
Note that upload.any() will allow you to upload multiple different formatted files at once. Feel free to use any other kind of upload.method() depending on your needs.
From this point, multer already is doing its job, however you might want to keep track of the files uploaded on your server.
So, in your own module, the logic is pretty much straight forward :
(I'm assuming that you're using mongoose models since you're not giving much information, but that's not the relevant part anyway)
exports.postFile = async (req, res) => {
if (!req || !req.files || !req.files[0]) return res.status(400).send("Bad request.");
for (let i = 0; req.files[i]; i++) {
await File.create({
path: req.files[i],
originalName: req.files[i].originalName,
mimetype: req.files[i].mimetype,
owner: req.user.userId
}, (err, file) => {
if (err) console.log("Something went wrong: " + err); else {
// Do something with file
}
});
}
return res.status(418).send("I'm a teapot.");
}
This configuration and middleware use is ONLY for testing purpose, never ever let anyone upload something to your server without carefully handle that uploading process (file integrity, resource management, ...). An open uploading system can become a very wide backdoor getting straight to your server.
Hope this helps,
regards.

upload files to remote server using multer sftp in express Node js?

I'm trying to upload the files to remote server using multer-sftp in node js. since i'm following the official docs npm multer-sftp. Previously i've uploading the files to Amazon S3 instead of remote server. now i want to upload the files to remote server.
API:
exports.newFileUpload = function(req , res , next){
var storage = sftpStorage({
sftp: {
host: 'http://www.port*****es.in/',
port: 22,
username: 'username',
password: 'password'
},
destination: function (req, file, cb) {
cb(null, 'images/')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage }).array('file');
upload(req,res,function(err){
logger.debug(JSON.stringify(req.body));
logger.debug(JSON.stringify(req.files));
if(err){
logger.debug("Error Occured", JSON.stringify(err));
res.json({error_code:1,err_desc:err});
return;
} else{
res.json({error_code:0,err_desc:null});
}
});
}
While uploading the file, returning the error
2017-11-10T02:39:48.297Z - debug: Error Occured {"code":"ENOTFOUND","errno":"ENOTFOUND",
"syscall":"getaddrinfo","hostname":"http://www.port****es.in/","host":"http://www.port****es.in/",
"port":22,"level":"client-socket","storageErrors":[]}
And also port no 22 is open in my domain. Awaiting Suggestions,
Thanks in Advance.
For Your Error, there are two possibilities
port no 22 is not open state, also not able to access that folder
Check your folder directory in domain
Uploading Files to remote server using multer-sftp is easy and flexible way.
also we can upload the files to remote server with scp, ssh techniques in node js.
Working Code:
exports.newFileUpload = function(req , res , next){
var storage = sftpStorage({
sftp: {
host: 'hostname',
port: 22,
username: 'username',
password: 'password'
},
destination: function (req, file, cb) {
cb(null, 'images/')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage }).array('file');
upload(req,res,function(err){
logger.debug(JSON.stringify(req.body));
logger.debug(JSON.stringify(req.files));
if(err){
logger.debug("Error Occured", JSON.stringify(err));
res.json({error_code:1,err_desc:err});
} else{
logger.debug("Files uploaded successfully");
res.json({error_code:0,err_desc:null});
}
});
}
Note: When using 'multer-sftp' port no 22 is open in remote server.
Hope it helps !

Combining angular-file-upload and multer

I have big headache to combine angular file upload plugin with multer to make it fully SPA. I stucked on uploading multiple files through multer.
This is how my multer options looks like: (node route.js file)
var upload = multer({
storage: storage,
limits: {
//fileSize: 819200
}
}).array('myFile');
this is my POST: (node route.js file)
router.post('/add/file', function(req, res, next) {
upload(req,res,function(err) {
console.log(req.files);
if(err) {
console.log("Error uploading file.");
}
});
});
this is inside my angular controller:
var uploader = $scope.uploader = new FileUploader({
url: 'http://localhost:3000/add/file',
alias: 'myFile'
});
uploader.filters.push({
name: 'imageFilter',
fn: function(item /*{File|FileLikeObject}*/, options) {
var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|';
return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
}
});
It adds only 1st file and stucks - I don't get any error it just stucks - whole page works and I can send files again, but again only 1st file will be uploaded. Console shows that req.files have only 1 file (that first one)
I couldn't find any tutorial or anything on the Internet with angular-file-upload plugin, that's why I ask you guys
Not sure if you figured this out yet or not, but with sending multiple files over, the 'uploadAll' function will not send the next file until it receives a response back from the server. So the route should look like this. I also saw somewhere in the documentation that the response needs to be json...haven't tested whether or not this is true though
router.post('/add/file', function(req, res, next) {
upload(req,res,function(err) {
console.log(req.files);
if(err) {
console.log("Error uploading file.");
} else {
res.status(200).json({response: 'some response...'})
}
});
});

Categories