Error when uploading files using FilePond and multer (expressjs) - node.js

I've written a react app that makes use of the FilePond file uploader but am having trouble getting multer to accept the request from filepond, it always returns a 500 error.
If I use a standard file upload control the request is accepted by the server and the file uploads fine.
Does anyone have any thoughts on what might be causing this?
Thanks
This is my server.js code:
var express = require('express');
var app = express();
var multer = require('multer')
var cors = require('cors');
app.use(cors())
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public')
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' +file.originalname )
}
})
var upload = multer({ storage: storage }).array('file')
app.get('/',function(req,res){
return res.send('Hello Server')
})
app.post('/upload', function(req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
return res.status(500).json(err)
// A Multer error occurred when uploading.
} else if (err) {
return res.status(500).json(err)
// An unknown error occurred when uploading.
}
res.send([req.files[0].filename]);
return res.status(200).send(req.file)
// Everything went fine.
})
});
app.listen(8000, function() {
console.log('App running on port 8000');
});

Related

In a NodeJS / Express (& multer) attachment upload utility, how to handle API delete requests?

The below is a rudimentary file upload utility. It handles React / Axios API POSTs satisfactorily. Files get uploaded to the ~uploads folder under root on the server. How does one add API DELETE handling capability to it? Envision a use case where a user uploads an attachment to a blog post and then deletes the attachment from the blog post. Have had issues locating an example.
var cors = require('cors');
var express = require('express');
var multer = require('multer')
var app = express();
app.use(cors());
// Parse JSON bodies (as sent by API clients)
app.use(express.json());
var storage = multer.diskStorage(
{
destination: function (req, file, cb)
{
cb(null, 'fileuploads');
},
filename: function (req, file, cb)
{
cb(null, file.originalname );
}
})
var upload = multer({ storage: storage }).array('file')
app.post('/upload',function(req, res)
{
upload(req, res, function (err)
{
if (err instanceof multer.MulterError)
{
return res.status(500).json(err)
}
else if (err)
{
return res.status(500).json(err)
}
return res.status(200).send(req.file)
})
});
app.listen(8001, function() {
console.log('App running on port 8001');
});
EDIT:
Modified app.delete(...) to the below, which successfully deletes the file but after about a minute throws this error in the console: [Error: ENOENT: no such file or directory, unlink '<PATH VALUE>']
app.delete('/writer/:file_to_delete', async (req, res) =>
{
const path = 'assets/uploads/' + req.params.targetFile;
console.log(path);
try
{
fs.unlink(path)
// NOTE: `fs.unlinkSync(path)` does the same thing
console.log('File deleted!');
return res.status(200);
}
catch(err)
{
console.error(err)
return res.status(500).json(err)
}
});
I found a way forward. The code is below but I'm happy to hear about better ways to do it:
// NOTE: `file_name` values are obfuscated and uniquely generated by the client.
// The actual file name is in data storage.
app.post('/delete/:file_name', (req, res) =>
{
const theFile = 'attachments/' + req.params.file_name;
var resultHandler = function(err) {
if(err) {
console.log("file delete failed", err);
return res.status(500).json(err)
}
console.log("file deleted");
return res.status(200).send({data: req.params.file_name + ' deleted'});
}
fs.unlinkSync(theFile, resultHandler);
});

Upload file to MongoDB and to a local server with the same POST request

I'm trying to make my own upload service, and I want to be able to upload a file in a local folder on my server but also on my mongoDB cloud service (Atlas).
So far, I've done both services separately and they work fine (I made a Node app for uploading files to mongo Atlas and another Node app for uploading files to the server). But now, I would like to unifiy these two into a single node app, where after each POST request, the file gets sent to both Atlas as well as the local folder. I'm using multer and gridfs.
The first attempt was to make two "file-input" fields on my index.html file, and each of those with two different POST requests: one to '/upload' which sends the file to Atlas and the second one to '/uploaddisk' which sends the file to disk. However, the second post request doesn't work (it throws me the error every time I want to submit my file). Uploading the file to mongoDB seems to work just fine every time.
Any ideas how can I do this on a single POST ? Thank you in advance!
Here is the code that I wrote for my server.js app:
//mongo DATA
const dbURI =
"myc-atlas-credentials";
mongoose.Promise = global.Promise;
// mongoose.connect(bdURI, { useNewUrlParser: true, useUnifiedTopology: true });
const conn = mongoose.createConnection(dbURI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
//init gfs
let gfs;
conn.once("open", () => {
//initialize the stream
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection("uploads");
});
//creating the storage engine for MONGO
const storage = new GridFsStorage({
url: dbURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
const filename = file.fieldname + '-' + Date.now() + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: "uploads"
};
resolve(fileInfo);
});
}
});
const upload = multer({ storage: storage });
//set storage engine with multer for disk
const diskstorage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, path.join(__dirname + '/uploads/'));
},
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
const diskupload = multer({ storage: diskstorage });
//route for POST - upload data to mongo
app.post('/upload', upload.single('file'), (req, res) => {
console.log({ file: req.file });
// res.json({ file: req.file });
res.redirect('/');
});
//route for POST - upload data to disk
app.post('/uploaddisk', diskupload.single('file'), (req, res, next) => {
const file = { file: req.file };
if (!file) {
const error = new Error('Please upload a file');
error.httpStatusCode = 400;
return next(error);
}
res.redirect('/');
});
You can try it like this:
function fileUpload(req, res, next) {
upload.single('file')(req, res, next);
diskupload.single('file')(req, res, next);
next();
}
//route for POST - upload data to mongo
app.post('/upload', fileUpload, (req, res) => {
console.log({ file: req.file });
// res.json({ file: req.file });
res.redirect('/');
});

Posting file upload to ec2

I am trying to upload files from my website to an amazon ec2 instance, i am using the IP Address; however, the connection is timing out. I have the private key, but am not using it in any way, so far.
what do I need to do to keep this from timing out, and successfully upload my items/overwrite old items (with the same name), and where should the code be added, i am assuming for the private key...?
I have attempted specifying the folder, using http instead of https, updating my server
onclick handler
onClickHandler = () => {
const data = new FormData();
data.append('file', this.state.selectedFile);
axios.post("https://xx.xxx.xxx.xx/upload", data, {
// receive two parameter endpoint url ,form data
}).then(res => { // then print response status
console.log(res.statusText)
})
};
Server
var express = require('express');
var app = express();
var multer = require('multer');
var cors = require('cors');
app.use(cors());
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/upload')
},
filename: function (req, file, cb) {
cb(null, file.originalname )
}
});
var upload = multer({ storage: storage }).single('file');
app.post('/upload',function(req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
return res.status(500).json(err)
} else if (err) {
return res.status(500).json(err)
}
return res.status(200).send(req.file)
})
});
app.listen(8000, function() {
console.log('App running on port 8000');
});
i need help figuring out what i am missing, and where to put it, Thank you to anyone who is able to help me out!

How to get FormData in Express js?

I'm trying to upload a file to my express server. The client code looks like this:
axios.post('localhost:3030/upload/audio/', formData)
And in my express server:
App.use(bodyParser.urlencoded({ extended: true }));
App.use(bodyParser.json());
App.post('/upload/audio/', function uploadAudio(req, res) {
let quality = ['320', '128'];
let file = req.body;
console.log(file)
res.send('Frick')
}
However, even though the mp3 file is sent:
The req.body is empty when logged (note the empty object):
How can I get the formData (and file) in Express.js?
As #Tomalak said body-parser does not handle multipart bodies.
So you need to use some third party module I suggest use awesome module multer
I tried to do your code, hope it can help you
App.post('/upload/audio/', function uploadAudio(req, res) {
var storage = multer.diskStorage({
destination: tmpUploadsPath
});
var upload = multer({
storage: storage
}).any();
upload(req, res, function(err) {
if (err) {
console.log(err);
return res.end('Error');
} else {
console.log(req.body);
req.files.forEach(function(item) {
console.log(item);
// move your file to destination
});
res.end('File uploaded');
}
});
});

node.js multer module can't handle errors

I have created a node.js server and i use the multer module for upload some files.
my problem is : how can i handle errors? like if the client close untile the upload is finished? sorry for bad english, i'm italian.
this is my actual don't working code :
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/root/appsistMe/public/AppMeFile/Utenti/'+req.session.nome);
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname);
}
})
var upload = multer({ storage: storage,
onError : function(err, next) {
console.log('error');
next(err);
}});
app.post('/uploadFile', upload.single('file'), function (req, res, next){
console.log("CI SIAMO AL DOWNLOADDDDDD");
mongo.aggiungiNuovoFile(req, res);
res.status(204).end();
});
onError was removed in version 1.0.0 .
var upload = multer().single('avatar')
app.post('/profile', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
return
}
// Everything went fine
})
})
Please check this link for more details

Resources