user3248186 user3248186 - 2 months ago 10
Javascript Question

How to post form data in a nodejs application with routes?

I tried to build a simple node application with routes, but it gives a 404 network error as it's unable to post. Can someone please point out my mistake and correct it?

First I created a directory sampProj, then in it, I've a file - appl.js and a directory routes. Inside routes directory, I've a directory routes and a file main.js. Again inside mainCode directory, I've 3 files - main.js, server.js and index.html.

Sorry for the complicated directions, I wanted to test out small and then start building on it. I want to mention that this code with just server.js and index.html worked without the routes, i.e server.js uses app.post and app.get etc. instead of the corresponding router methods which I've shown below.

So here's the code for the application:

appl.js:

var express = require('express');
var bodyParser = require('body-parser');

var app = module.exports.app = express();

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false}));

// parse application/json
app.use(bodyParser.json());

// Adding routes
var server = require(__dirname + '/routes/main');
var mainCode = require(__dirname + '/routes/mainCode/main.js');

app.use('/Service', server);
app.use('/Service/mainCode', mainCode);

// Catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

/* Error Handlers */
// It will print the Stacktrace of error
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.send({
message: err.message,
error: err
});
});
}

app.listen(3000,function(){
console.log("Working on port 3000");
});


routes/main.js:

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
res.send('<code>Welcome to Service</code>');
});

module.exports = router;


mainCode/main.js:

var express = require('express');
var router = express.Router();
var server = require(__dirname + '/server');
router.use('/server', server);
module.exports = router;


mainCode/index.html

<html>
<head>
<title>Form Data</title>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data" action="/" method="post">
<input id = "userPhotos" type="file" name="userPhotos" multiple />
<input type='text' id='random' name='random'><br>
<input type="submit" value="Upload" name="submit">
</form>
</body>
</html>


mainCode/server.js:

var express = require("express");
var router = express.Router();
var multer = require('multer');

var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + file.originalname);
}
});

var upload = multer({ storage : storage }).any();//array('userPhoto',2);

router.get('/',function(req,res){
res.sendFile(__dirname + "/index.html");
});

router.post('/',function(req,res){
console.log("posted");
console.log("posted");
console.log(req.body);
upload(req,res,function(err) {
if(err) {
console.error(err);
return res.end("Error uploading file.");
}
console.log(req.body);
console.log(req.files);
res.end("File is uploaded");
});
});

module.exports = router;


Once I open localhost:3000/Service/mainCode/server in a browser, a form is displayed with one text input, but if I submit data, it's redirecting to localhost:3000 with error 404 displayed on the screen.

If you downvote this, please tell me why you're doing so, and in what way I can improve the question.

Answer

You access the form via the URL:

http://localhost:3000/Service/mainCode/server

right? In your mainCode/server.js you set the get as well as the post handling for the same URL. So why do you call the root directory in mainCode/index.html on form submit:

 <form id="uploadForm" enctype="multipart/form-data" action="/" method="post">

it should be:

<form id="uploadForm" enctype="multipart/form-data" action="/Service/mainCode/server" method="post">

as far as I understand. Usually if you want to send a formular to the same URL you would just leave the action attribute out like:

<form id="uploadForm" enctype="multipart/form-data" method="post">

EDIT: Turned out that it solved the problem for the OP combined with the removing of the attribute enctype, which leads to the default application/x-www-form-urlencoded method.

But as the OP wanted to submit a file in the first place, he had to exchange the body-parser module with multer and set the enctype to multipart/form-data again.

Documentation of multer: https://github.com/expressjs/multer