I am facing issue while file upload in express.js with multer.
I have written below code in my route.js:
var multer = require('multer');
var upload = multer({dest: 'uploads/'});
module.exports = function(router) {
router.post('/route/file', upload.single('file'), function(req, res) {
// this is not called..
console.log('this should be called');
});
}
It's strange in my windows it's working fine. But in my MacBook same code isn't working.
Related
I am trying to test REST API, and I can't figure out how to send a file from client side to express server side.
This is my pug file, with which i simulate client side for specific purposes, in this case just send the picture.
doctype html
html
head
title Test
body
form(action=`${baseRoute}/api/users/${nick}/generate` enctype="multipart/form-data" method='POST')
input(type='file' accept="image/png, image/jpeg" id='profile_picture' name='image')
input(type='submit', value='Load')
baseRoute is created for pug, so it does not add action link to existing link, and changes the whole link.
From what I saw, to get files from form, I have to access req.files in express back end part. Yet, it shows me absolutely nothing
const express = require('express');
const app = express();
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.set('views', 'views');
app.set('view engine', 'pug');
app.get('/', function(req, res, next) {
res.redirect('/test/update_user');
});
app.post('/api/users/:nick/generate', upload.single('image'), async function(req, res, next) {
console.log("GENERATE USER");
console.log(req.files);
res.send("Success");
});
app.get('/test/update_user', function(req, res, next) {
let params = {
baseRoute: "",
nick: 'somenick',
};
res.render('test/update_user', params);
});
app.listen(3000, () => {
console.log("go to localhost:3000/test/update_user");
});
I tried reading all of req, but there was no sight of files property. Using multer it adds a file to upload directory, but in a weird way without any extension and some weird name. And still it logs 'undefined' when I am trying to access req.files
I'm make api to upload files using node js.
i using multer for handle multipart/form-data
but when i console.log(req.file) it appears undefined
Route
const uploadController = require('../controller/upload.server.controller');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
/**
* Routes
*/
module.exports = function (app) {
app
.route('/api/upload')
.post(upload.single('image'), uploadController.upload);
};
Controller
exports.upload = async function (req, res) {
console.log(req.file);
};
my request with postman
Try using req.file as per the docs source: multer
// init
const multer = require('multer');
const path = require('path');
// "images" are the folder name
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'images');
},
});
// put this to config the multer
app.use(multer({ storage: fileStorage }).single('image'));
// this is for serving file staticly with "path" module
app.use('/images', express.static(path.join(__dirname, 'images')));
Also make sure you write enctype=multipart/form-data in the form tag not in the input tag AND
add type=file attribute in the input tag
Try this:
app.post('/api/upload', upload.single('image'), function (req, res, next) {
console.log(req.file);
})
I have also encountered similar problem. Everytime I restart my server postman provided req.file gives undefined. I thought maybe I habe made a bug but I couldn't figure out what was wrong.
Then I tried creating a new request in postman and when I requested req.file works perfectly. I am trying to figure out what is wrong with Postman or am I making a mistake while sending a request.
The normal get method works fine on my main server.js file. I also use server.get('/favicon.ico', (req, res) => res.status(204)); to tackle the issue of the favicon request. It works well, again only on my main server.js file.
When I try to separate the code, by creating a user.js file that handles the api calls, I get:
::ffff:127.0.0.1 - GET /favicon.ico HTTP/1.1 404 150 - 1.669 ms
::ffff:127.0.0.1 - GET /users HTTP/1.1 404 144 - 0.454 ms
This is my main file - server.js:
const express = require('express');
const morgan = require('morgan');
const server = express();
const router = require('../routes/user');
const mysql = require('mysql');
server.use(morgan('short'));
//server.use(express.static('../public'));
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
router.use(router);
server.get('/', (req, res) => {
console.log("Test!");
res.send("This works!");
});
//server.get('/favicon.ico', (req, res) => res.status(204));
server.listen(3003, () => console.log('Program is running! Port: 3003'));
This is my user.js file:
const express = require('express');
const mysql = require('mysql');
const router = express.Router();
router.get('/users', (req, res) => {
res.send('Hello');
});
router.get('/favicon.ico', (req, res) => res.status(204));
module.exports = router;
I'm not sure if this is related but I also experience the same problem when trying to server.use(express.static('../public')). It doesn't work. I cannot serve my html file. I've tried using the csp headers when requesting but that doesn't work. Setting up a CSP policy in the html header meta tag is not working either.
These are the versions of certain modules and technologies if you see a problem in any of their versions:
Apache 2.4.39
Node 6.9.0
Windows 7 - Yeah I know but bear with me
If anyone can help with eigther the router issue or the static file server issue it would much appreciated.
Thank you.
A simple way to do this is, in your server.js file add
server.use("/user", require("./routes/routes"));
note: routes is a folder here and routes.js is a file inside that folder.
then in your route.js file add
const express = require('express');
const router = express.Router();
const user = require('../controllers/user.controller');
// register controllers
const userController = new user();
userController.register(router);
module.exports = router;
pass your router in the user register(router) method. and it will be easily accessible in your user.js file.
I am posting a large number of files that can take potentially minutes to upload. I using a multi-part form to post the files and then waiting for a response from the POST, but this can take several minutes.
How do I make Node/Express wait for this response? As of now, it seems like the request is "timing out" and Node or the browser is re-POSTing the files because it is taking so long. I can see this because my middleware functions are being called multiple times for requests that take too long.
Is there a library to make Node not timeout? Should I be attempting to POST these files in a different fashion? Thanks
var mid = function(req,res,next) {
console.log('Called');
next();
};
app.post('/api/GROBID', mid, authenticate, PDFupload.return_GROBID, PDFupload.post_doc, function(req, res) {
if (res.locals.body == 400) res.send(400);
/*if (process.env.TEST_ENV == 'unit-testing') {
res.send(res.locals.body);
}*/
res.render('uploads', {files : res.locals.body});
});
Edit: This mid middleware (used as an example) is being called twice. This means the route is being posted to twice. How do I make sure this does not happen?
Is there a library to make Node not timeout?
Express sits on top of Node.js' built-in HTTP server. By default, the timeout is 2 minutes. You can modify its default timeout as below:
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
app.get('/', function(req, res) {
res.send('<html><head></head><body><h1>Hello world!</h1></body></html>');
});
var server = app.listen(port);
server.timeout = 1000 * 60 * 10; // 10 minutes
Should I be attempting to POST these files in a different fashion?
Yes, you can use Multer, a node.js middleware for handling multipart/form-data, which is primarily used for uploading files.
And with Multer, you don't have to worry about the timeout anymore. Event the upload time is longer than the timeout, say 2 minutes by default, Express just won't timeout.
Here is the sample code:
app.js
var express = require('express');
var app = express();
var path = require('path');
var multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/your/path/to/store/uploaded/files/')
},
filename: function (req, file, cb) {
// Keep original file names
cb(null, file.originalname)
}
})
var upload = multer({ storage: storage })
// files is the name of the input html element
// 12 is the maximum number of files to upload
app.post('/upload', upload.array('files', 12), async (req, res) => {
res.send('File uploaded!');
})
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(3000);
index.html
<html>
<body>
<form ref='uploadForm' id='uploadForm'
action='http://localhost:3000/upload'
method='post'
encType="multipart/form-data">
<input type='file' name='files' multiple/>
<input type='submit' value='Upload!' />
</form>
</body>
</html>
Now try starting the web server:
node app.js
Then open your browser and go to http://localhost:3000
You can now upload a number of big files, which you can find later on in folder /your/path/to/store/uploaded/files/
I am building an app on Glitch with express js which requires the user to upload multiple files. Here is my code:
var express = require('express');
var cors= require('cors');
var bodyParser= require('body-parser');
var contexts= require('./contexts');
var path= require('path');
var fileUpload= require('express-fileupload');
var multer= require('multer');
var upload = multer();
var app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(fileUpload());
app.set('view engine', 'ejs');
app.set('views', 'views');
app.use(express.static('views/'));
//here express-fileuploads works fine
app.post('/getcontexts', function (req,res) {
var context=contexts.get(req.files.file.data.toString());
res.render('rast', {length: context.length, content : context});
});
//this is when I get an empty array
app.post('/getrast', upload.array('rastfiles'), function (req, res) {
res.json({data: req.files});
});
var listener = app.listen(process.env.PORT, function () {
console.log('SERVER STARTED ON PORT ' + listener.address().port);
});
and here is the ejs form I use:
<form action="/getrast" method="POST" enctype="multipart/form-data">
<label for="rastfiles">Please select your Rast genome files with .txt extension</label>
<br>
<input type="file" id="file" name="rastfiles" class="inputFile" multiple>
<br>
<input type="submit" value="Run" id="sub">
</form>
I already used express-fileupload to upload a single file and it worked just fine. However, when I use multer to upload multiple files I get and empty array when logging req,files into the console. Any idea why this might be happening?
I'd really appreciate any help. Thanks!
The reason why multer was not working is because express-fileupload was already being used as middleware for file uploading, so commenting out this line:
app.use(fileUpload())
fixed the problem for me.
This is from multer doc:
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 files will be kept in memory and never
written to disk.
that's mean you need to define at least dest option:
var upload = multer({ dest: 'uploads/' });