Node.js upload file into Buffer instead of /tmp - node.js

In a Node.js app, is it possible to upload a file (multipart/form-data) directly into a buffer on the server instead of saving the file to the filesystem?
In psuedo code you typically do this with a file upload form
router.post('/upload', function(req, res, next){
// file is saved to /tmp/dk3idkalel4kidkek
// do some processing on the file
// manually save file to /www/myapp/uploads/originafilename.ext
});
Is it possible to skip the part about saving the file to /tmp and just capturing the uploaded file as a Buffer and streaming it directly to the destination directory?
An example would be uploading an image, then optimizing the image, then saving it to it's intended destination. Can you just capture the incoming stream, optimize it then save it, all without the initial saving to the /tmp directory?

Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. The memory storage engine stores the files in memory as Buffer objects. When using memory storage, the file info will contain a field called buffer that contains the entire file.
This should do exactly what you need.
You can read more here

Multer module uses busboy for upload, so an alternative would be to use busboy for express: connect-busboy

Related

How could I save an img in my express server that I receive from my client?

I have a client in React that sends a form data with a file. When that file arrives to the server, the body is parsed by body parser and its result is a buffer. The idea is that the file keep saved in some place of my server, because I want to use it later from my client. So I'd like to know how should I handle this problem.
I tried to write directly this buffer as a file with fs, but the file created has an error of format, so I can't access it.
You can do stuff like this
var fs = require('fs');
fs.writeFile('newImage', req.files.image, function (err) {
if (err) throw err;
console.log("It's saved");
});
correct parameter order of fs.writeFile is the filename first then the content.
If you're using express.bodyParser() you'll have the uploaded files in the req.files field.
And of course you should write the callback:
POV: Your image file should be in req.files not the body.
I think you need a package for storing a file on your backend service. I had used morgan package for that and I was satisfied with using it. I have just searched other packages for storing a file, i found express-fileupload package. Maybe you want to look at how to use those. If you want to store a file, using the third package would be better for you and for your effort.

Image uploading - How to get the right format of image data for server side processing

I'm using sharp to process images on the server side and react dropzone to get the image file. When I post the file to the server from dropzone, I get the blob out of the request.body that looks like:
{ preview: 'blob:http%3A//127.0.0.1%3A3000/1451580a-b24f-478f-a9f7-338c0d790829' }
Optionally, before I send data to the server I can use FileReader (or something else) to do something with the image file instead of turning it into a blob.
Sharp takes:
A Buffer containing JPEG, PNG, WebP, GIF, SVG, TIFF
Raw pixel image data
A String containing the path to an image file, with most major formats supported.
How can I use what I have to provide sharp a supported format?
I recommend trying out a node.js module called Multer to help you access your photo file on your server.
https://github.com/expressjs/multer
First, on the client, you'll want to append your file to a FormData object like this:
// obtain the file from your react dropzone and save it to this file variable
const file = dropzone.file // not sure how you do this with react dropzone
const data = new FormData()
data.append('photo', file)
Then you'll send this FormData object to your server. On the server you'll use Multer on the route you're using for the photo for processing.
Make sure you npm install multer, and require it on your server or routes file. If you're sending a single file you'll use the multer 'single' method. If you want to do anything different check out the API documentation.
app.post('/photos', multer().single('photo'), controller.processPhoto);
In this example route, you're sending a POST request to /photos, multer is looking for a file with a FormData key of 'photo' and appending that to the request object.
Then in this made up 'controller.processPhoto' method you'll have access to the image as a property of the request object, on req.file. With this you can easily access a lot of good information including the image buffer req.file.buffer which it sounds like you need. (also mimetype, original name etc.)
This should be enough to get you started.

Express 4: How to upload file to memory (e.g. as a UTF-8 string) rather than disk?

I have an Express 4 application which needs to process data files uploaded by users and return an output. The files are relatively small (1-2 MB), so I'd like to upload them directly to memory (e.g. as a UTF-8 string variable) rather than saving them to disk.
The closest I've gotten so far is the multer module and its onFileUploadData event, but I can't figure out how to take the data and pass it to a route handler in a separate file.
Is this possible with Node.js / Express?
I don't know if this option was available at the time of the question, but it certainly is now.
You can set the inMemory option to true in multer and that will give you a buffer object. Likes this:
app.use(multer({
dest: './uploads/',
inMemory: true
}));
You can find all the available options for multer here: https://github.com/expressjs/multer#options
Update for multer 1.x
Multer version 1.0.0 introduces the concept of storage engines and ships with two default engines: DiskStorage and MemoryStorage.
This is how you can instantiate it to store the files in memory:
multer({ storage: multer.memoryStorage({}) })

Can we configure multer to not store files locally and only for using req.files.image.path?

My application's need is as follows:
I upload the image to Cloudinary and store the url of image in my mongodb database.
To upload the image to cloudinary, I needed to give the file path, and for that, I am using multer.I use the statement:
app.use(multer({ dest: './uploads/'}));
The problem I face is that, everytime I upload an image from my local system to the database on Cloudinary, a local copy gets created in './uploads/'.I want this to not happen, since my images are there on Cloudinary.
I read the documentation of multer where it says:
Multer accepts an options object, the most basic of which is the dest property, which tells Multer where to upload the files. In case you omit the options object, the file will be renamed and uploaded to the temporary directory of the system.
I am unable to make out if that temporary upload space needs cleaning or if it is taken care of.My images are uploaded on Cloudinary.I used multer only for getting :
req.files.photo.path
to work.Is there any other way to do the same or if multer can be configured in a way to not store images to my local system?
July 2018:
So if you want to store an image into some sort of database, you probably want to convert it into a buffer, and then insert buffer into the database. If you are using multer to process the multipart form (in this case the image file you want to upload), you can use multer's memoryStorage to get the buffer of the image directly. In other words:
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
to get the buffer:
When using memory storage, the file info will contain a field called buffer that contains the entire file.
that means you can get the buffer from command like req.files[0].buffer
I updated a simple repo demonstrating upload images to database without making a copy to local in this repo
From Multer info page at
https://www.npmjs.com/package/multer
If the inMemory option is true - no data is written to
disk but data is kept in a buffer accessible in the file object.
Prior to 14-07-2016 you could not configure multer to store files locally.
But multer is just a wrapper of busboy. So, we can try use busboy directly if we want to avoid hitting the disk.
Connect-bubsboy will help us:
app.use(busboy());
// request handler
req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
file.on('end', function() {
// do stuff with req.files[fieldname]
});
});
Update 14-07-2016
Now multer has MemoryStorage to store files in memory as Buffer.
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })
You can also delete the file once it's uploaded to Cloudinary.
// used to delete images from local directory
const fs = require('fs'); // gain access to file system
const util = require('util');
const deleteFile = util.promisify(fs.unlink); // unlink will delete the file
// in your post request
app.post('/images', upload.single('myFile'), async function(req, res) {
const file = req.file; // multer gives access to the file object in the request
// code to upload the file to Cloudinary
await deleteFile(file.path); // remove locally stored image by passing the file's path
});
If you're storing images with Cloudinary then try using multer-storage-cloudinary

access post files to nodejs without saving to disk

I'm using Heroku to store my Express app and I can't use bodyParser, or formidable, because both uses temp files to store the posted file.
The file I'm posting is simply a large text file (csv). I don't really need to store the file anywhere, because the data will go into mongodb.
Is there anyway to parse the csv file as it is being uploaded?
Starting with Connect 2.9.0 (Express 3.4.0), bodyParser uses multiparty instead of formidable.
In multiparty's default configuration, it does not create temporary files. Read the docs to see exactly how to handle the incoming data, but you'll want to listen to the part event, which gives you a readable stream containing the uploaded file.

Resources