Multer gives unexpetcted end of form error - node.js

The file is being send to the nodejs server, but the upload.single gives an unexpected end of form error. How do i fix this?
const upload = multer({ dest: "../../uploaded_images" });
router.patch("/profile", upload.single("profileImage"), (req, res) => {
console.log(req.files) // This shows that there is a file named profileImage, I can see that when I remove the upload.single("profileImage")
res.send("")
})
the file structure:

It seems to be a bug in Multer itself. I solved by downgrading Multer to 1.4.3.
See https://github.com/expressjs/multer/issues/1144

Related

Why am I NOT able to upload files with the following NodeJS code?

I am trying to design a simple app in NodeJS that uploads a CSV file via an HTML form.
Having carefully followed this tutorial on YouTube on how to upload files using NodeJS, I don't understand why my code isn't able to upload any file. I haven't gotten further than 6:53 mins in the youtube tutorial.
Find below my simple code:
const express = require('express');
const app = express();
const multer = require('multer');
const fileStorageEngine = multer.diskStorage({
destination: (req,file,cd)=> {
cd(null, './uploads')
},
filename: (req,file,cb)=>{
cb(null, Date.now() + '--' + file.originalname);
},
});
const upload = multer({storage: 'fileStorageEngine'});
app.get('/', (req,res)=> {
res.sendFile(__dirname +'/testDir/form.html' );
});
app.post('/uploads', upload.single('file'), (req, res)=> {
console.log(req.file);
res.send('Single File Upload Success!');
});
app.listen('3600', ()=> console.log('App is listening...'));
...and my HTML form code looks like this:
http://localhost:3600/ correctly displays
I am able to browse to whatever file I choose, and clicking on the submit button that gets me directed to:
According to the YouTube at 6:53 mins, the uploads folder should now contain the uploaded file,
however, the folder is empty!
Also, the terminal displays
...suggesting that console.log(req.file); no file was actually read in.
I also tried using postman and this is a screenshot of the result:
I have tried to re-watching the video and carefully followed the instructions but still haven't been able to resolve the issue.
Kindly help me understand why the upload isn't working and how to resolve this issue.
Looking forward to your help.
You have set the storage field as a string instead of a multer.diskStorage object.
Change it to: const upload = multer({storage: fileStorageEngine});
Also make sure that the key value in Postman form-data is set to file, because you are using upload.single('file')
Make sure you have enctype="multipart/form-data" in your html form. Also, make sure you have set name correctly. Can you paste the code for your form as well?

How to move multer upload midddleware to another file

Working with multer and gridFS for an express API I am developing. I am having trouble moving the upload object to another file. I have setup multer so that
export const upload = multer({
storage,
});
The following code works in index.ts where multer is initiated but not in any other routes file.
router.post("/upload", single("image"), (req, res) => {
const file = req.file;
if (!file) {
const error = new Error("Please upload a file");
res.send(error);
}
res.send(file);
});
It's not possible for me to post a whole snippet but I hope this is enough.
Cheers
I was actually able to solve this by adding the following:
app.use(
multer({
storage,
}).single("image")
);
Now that might mean it will run for every route which is another issue to address
you can do like this:
for all path
app.use('*', multer({storage}).single("images"));
just for post request
app.post('*',multer({storage}).single("images"))
For all post routes but a few routes
app.post('*',(req,res,next)=>{
const exceptionPaths = ["singup","login"]//don't upload
if(exceptionPaths.includes(req.path))return next()
next()
},multer({storage}).single("images"))

Upload large file (>2GB) with multer

I'm trying to upload a large file (7GB) to my server. For this I'm using multer:
const express = require('express');
const multer = require('multer');
const {
saveLogFile,
} = require('../controller/log');
const router = express.Router();
const upload = multer();
router.post('/', upload.single('file'), saveLogFile);
In my saveLogFile controller, which is of format saveLogFile = async (req,res) => { ... } I want to get req.file. The multer package should give me the uploaded file with req.file. So when I try to upload small files (<2GB) It goes successfully. But when I try to upload files over 2GB, I get the following error:
buffer.js:364
throw new ERR_INVALID_OPT_VALUE.RangeError('size', size);
^
RangeError [ERR_INVALID_OPT_VALUE]: The value "7229116782" is invalid for option "size"
How can I bypass it? Actually, All I need is access for the uploaded file in my saveLogFile Controller.
The reason for this is probably that node will run out of memory as your using multer without passing any options. From the docs:
In case you omit the options object, the files will be kept in memory
and never written to disk.
Try using the dest or storage option in order to use a temporary file for the upload:
const upload = multer({ dest: './some-upload-folder' });
router.post('/', upload.single('file'), saveLogFile);

How do I get the body of a request from npm's multer if I don't upload a file?

I have a Node server using express.
I was originally using body-parser, but that doesn't allow for file uploads. So, I switched to multer (the easiest integration with express). However, in order to get any of the req (specifically req.body), this is my code:
var multer = require('multer');
var upload = multer({ dest : 'uploads/' });
server.all('/example', function (req, res, next) {
var up = upload.single('photo')
up(req, res, function(err) {
console.log(req.body); // I can finally access req.body
});
}
The problem with this, is that not all of my routes need to upload a file. Do I need to waste the CPU on calling upload.single() for each route in order to get access to the body? upload.single('') ends up not uploading any file, but it's still precious time spent on the main thread.
It appears that upload.single() waits for the callback, so it may not be as big of a deal as I'm making it, but I don't like calling functions when I don't have to.
Is there a way around calling upload.single(), or am I just making a bigger deal out of this than it really is?
For text-only multipart forms, you could use any of the multer methods, which are .single(), .array(), fields()
For instance using .array()
var multer = require('multer');
var upload = multer({ dest : 'uploads/' });
server.all('/example', upload.array(), function (req, res, next) {
console.log(req.body);
});
It doesn't really matter which you use, as long as it's invoked without arguments Multer will only parse the text-fields of the form for you, no files

Having trouble uploading a file with node using multer

This seems like a simple problem, but I've been spending a while trying to solve it and I can't quite figure out what's wrong. This is my frontend form that is making the request:
div#PreGA
p PreGa.json:
form(action="config/set/PreGa", name="pre-ga", method="post", enctype="multipart/form-data")
input(type="file" value="Choose File" accept=".json")#choose-file-pre-ga
input(type="submit" value="Upload")#upload-pre-ga
This is the route that should receive the request:
var upload = multer({ dest: 'uploads/' });
//set the JSON file for the pre-ga reported issues
router.post('/config/set/PreGa',ensureAuthenticated, upload.single('pre-ga'), function(req, res, next) {
console.log(req.body);
console.log(req.file);
});
The issue is that req.file, which should return the file, is undefined when the route is called.
This is one of the simplest use cases, and I can't figure out what's going wrong. It would greatly appreciate some help.
Your file input is missing a name attribute.

Resources