In the tutorial, we show how to upload multipart/form-data
with text fields and attached file in NodeJS/Express web-application using Multer, JQuery Ajax, Bootstrap 4.
Related posts:
– NodeJS/Express – Upload/Download MultipartFiles/Images – Multer + JQuery Ajax + Bootstrap
Contents
Goal
In the tutorial, we build a NodeJS/Express web-application that uses Multer middleware to upload/download multipart/form-data with text-fields & attached file using JQuery Ajax & Bootstrap view.
Technologies:
- NodeJS
- Express
- Multer
- JQuery Ajax
- Bootstrap 4
Project structure:
/NodeJS-Express-Upload-Text-Fields-File /app /config multer.config.js /node_modules /resources /static /js postrequest.js /uploads /*contain uploaded files*/ /views index.html 404.html package.json server.js |
-> results:
-> Server’s Logs:
NodeJS-Express-Upload-Text-Fields-File>node server.js App listening at http://:::8081 /GET { "firstname": "Jack", "lastname": "Davis", "file": { "fieldname": "resume", "originalname": "Jack-Resume.txt", "encoding": "7bit", "mimetype": "text/plain", "destination": "C:\\nodejs\\NodeJS-Express-Upload-Text-Fields-File/uploads/", "filename": "Jack-Resume.txt", "path": "C:\\nodejs\\NodeJS-Express-Upload-Text-Fields-File\\uploads\\Jack-Resume.txt", "size": 12 } } |
Prerequisites
NodeJS/Express – Upload/Download MultipartFiles/Images – Multer + JQuery Ajax + Bootstrap
Practice
Setting up NodeJS/Express project
Create a folder NodeJS-Express-UploadForm-Fields-Files:
mkdir NodeJS-Express-UploadForm-Fields-Files cd NodeJS-Express-UploadForm-Fields-Files |
Then init NodeJS project:
NodeJS-Express-Upload-Text-Fields-File>npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (nodejs-express-upload-text-fields-file) version: (1.0.0) description: Building a NodeJS/Express to upload Form with Text-Fields & MultipartFile using Multer middleware + Bootstrap view + JQuery Ajax entry point: (index.js) server.js test command: git repository: keywords: NodeJS, Express, Bootstrap, Multer, JQuery-Ajax, MultipartFile-TextFields-Form author: grokonez.com license: (ISC) About to write to C:\nodejs\NodeJS-Express-Upload-Text-Fields-File\package.json: { "name": "nodejs-express-upload-text-fields-file", "version": "1.0.0", "description": "Building a NodeJS/Express to upload Form with Text-Fields & MultipartFile using Multer middleware + Bootstrap view + JQuery Ajax", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "NodeJS", "Express", "Bootstrap", "Multer", "JQuery-Ajax", "MultipartFile-TextFields-Form" ], "author": "grokonez.com", "license": "ISC" } Is this ok? (yes) yes |
-> Install Express, Multer:
npm install express multer --save |
-> See package.json file:
{ "name": "nodejs-express-upload-text-fields-file", "version": "1.0.0", "description": "Building a NodeJS/Express to upload Form with Text-Fields & MultipartFile using Multer middleware + Bootstrap view + JQuery Ajax", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "NodeJS", "Express", "Bootstrap", "Multer", "JQuery-Ajax", "MultipartFile-TextFields-Form" ], "author": "grokonez.com", "license": "ISC", "dependencies": { "express": "^4.16.3", "multer": "^1.3.0" } } |
Frontend
Bootstrap view
– Create ./app/views/index.html file:
<!DOCTYPE html> <html lang="en"> <head> <title>Application Form</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script src="/static/js/postrequest.js"></script> </head> <body> <div class="container"> <h1 >Application Form</h1> <div class="col-sm-5"> <form method="POST" enctype="multipart/form-data" id="applicationForm"> <div class="form-group"> <label for="firstname">First Name:</label> <input type="text" class="form-control" id="firstname" name="firstname"> </div> <div class="form-group"> <label for="lastname">Last Name:</label> <input type="text" class="form-control" id="lastname" name="lastname"> </div> <div class="form-group"> <label for="resume">Resume:</label> <input type="file" class="form-control" id="resume" placeholder="Upload File" name="resume"></input> </div> <div class="form-group"> <div> <button type="submit" class="btn btn-primary" id="btnSubmit">Submit Application</button> <button type="reset" class="btn btn-default" id="btnSubmit">Reset</button> </div> </div> </form> <hr/> <div id="confirmMsg"> </div> </div> </div> </body> </html> |
– Create ./views/404.html file:
<!DOCTYPE html> <html lang="en"> <head> <title>404 Error!</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> </head> <body> <div class="jumbotron text-center"> <h1>404 Error!</h1> <p>PAGE NOT FOUND</p> </div> </body> </html> |
Jquery Ajax
– Create a JQuery Ajax POST multipart/form-data
form, see ./resources/static/js/postrequest.js file:
$(document).ready( () => { $("#btnSubmit").click((event) => { //stop submit the form, we will post it manually. event.preventDefault(); doAjax(); }); }); function doAjax() { var form = $('#applicationForm')[0]; var data = new FormData(form); $.ajax({ type: "POST", enctype: 'multipart/form-data', url: "/api/upload/application", data: data, processData: false, //prevent jQuery from automatically transforming the data into a query string contentType: false, cache: false, success: (data) => { $("#confirmMsg").text(data); //reset form }, error: (e) => { $("#confirmMsg").text(e.responseText); } }); } |
Backend
Config Multer Upload
– Create ./app/config/multer.config.js file:
const multer = require('multer'); var storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, __basedir + '/uploads/') }, filename: (req, file, cb) => { cb(null, file.originalname) } }); var upload = multer({storage: storage}); module.exports = upload; |
Express Routers
– Create ./app/routers/application.router.js file:
module.exports = (app, router, upload) => { const controllers = require('../controllers/application.controller.js'); var path = __basedir + '/views/'; router.use((req,res,next) => { console.log("/" + req.method); next(); }); app.get('/', (req,res) => { res.sendFile(path + "index.html"); }); app.post('/api/upload/application', upload.single("resume"), controllers.uploadForm); app.use('/',router); app.use('*', (req,res) => { res.sendFile(path + "404.html"); }); } |
Application Controller
– Create ./app/controllers/application.controller.js file:
exports.uploadForm = (req, res) => { var applicationform = { firstname: req.body.firstname, lastname: req.body.lastname, email: req.body.email, phone: req.body.phone, file: req.file }; // log applicationForm console.log(JSON.stringify(applicationform, null, 4)); res.send('Uploaded Successfully!'); } |
Server.js
– Create ./server.js file:
var express = require('express'); var app = express(); var router = express.Router(); var upload = require('./app/config/multer.config.js'); global.__basedir = __dirname; app.use(express.static('resources')); require('./app/routers/application.router.js')(app, router, upload); // Create a Server var server = app.listen(8081, () => { var host = server.address().address var port = server.address().port console.log("App listening at http://%s:%s", host, port); }) |
Run & check results
Start NodeJS server. Make a submit application form:
-> Bootstrap view:
-> Browser Network Log:
-> Server’s Log:
NodeJS-Express-Upload-Text-Fields-File>node server.js App listening at http://:::8081 /GET { "firstname": "Jack", "lastname": "Davis", "file": { "fieldname": "resume", "originalname": "Jack-Resume.txt", "encoding": "7bit", "mimetype": "text/plain", "destination": "C:\\nodejs\\NodeJS-Express-Upload-Text-Fields-File/uploads/", "filename": "Jack-Resume.txt", "path": "C:\\nodejs\\NodeJS-Express-Upload-Text-Fields-File\\uploads\\Jack-Resume.txt", "size": 12 } } |
-> Uploaded File:
Sourcecode
To run below sourcecode, follow the guides:
step 0: download & extract zip file -> we have a folder ‘NodeJS-Express-Upload-Text-Fields-File’
step 1: cd NodeJS-Express-Upload-Text-Fields-File
step 2: npm install express multer –save
step 3: node server.js
step 4: makes a POST request: http://localhost:8081
-> Sourcecode:
this approch always gives me always defined for textfiled values .I only recieve Image or text not both
always undefined *