Input form (mustache) pushed array to last request / response. All responses are placed in their session, pushed to the correct JSON file named session_ID.
Directory structure
- node_modules
- public
- CSS
- stylesheet.css
- JS
- javascript.js
- views
- index.html
- .env
- app.js
- package.json
Nodemon is used for development. The watch files are listed in nodemonConfig section.
package.json
{
"name": "Your app name",
"version": "1.0.0",
"description": "Your app description",
"nodemonConfig": {
"ext": "js,jsx,ts,html,php,mustache"
},
"main": "app.js",
"scripts": {
"dev": "nodemon app.js"
},
"author": "t3b",
"license": "MIT",
"dependencies": {
"body-parser": "^1.20.2",
"dotenv": "^16.3.1",
"express": "^4.19.2",
"express-session": "^1.18.0",
"fs": "^0.0.1-security",
"helmet": "^7.1.0",
"mustache-express": "^1.3.2",
"nodemon": "^3.1.0"
}
}
app.js
const express = require('express'); const helmet = require('helmet') const dotenv = require('dotenv') const path = require('path') const bodyParser = require('body-parser'); const session = require('express-session'); const mustacheExpress = require('mustache-express'); const fs = require('fs') const app = express(); const PORT = 5000; dotenv.config();
/* security policies example for x-frame settings */ app.use(helmet({ contentSecurityPolicy: { directives: { "frame-ancestors": ["'self'", "https://a-domain.com", "https://www.a-domain.com"] } } }));
app.use(bodyParser.urlencoded({ extended: true })); app.use(session({ secret: 'secret', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: true })); /* use mustache as template engine */ app.engine('html', mustacheExpress()); app.set('view engine', 'html'); app.set('views', __dirname + '/views'); /* make static files ( e.g. *.css, *.js) includeable */ app.use(express.static(path.join(__dirname, 'public'))) app.use(bodyParser.urlencoded({ extended: true })); /* routes ... ############################ */ app.get('/', (req, res) => { const inputValue = req.session.inputValue || ''; const requests = req.session.requests || []; res.render('index', { inputValue, requests }); }); app.post('/',async (req, res) => { try { /* date */ let today = new Date(); let day = String(today.getDate()).padStart(2, '0'); let month = String(today.getMonth() + 1).padStart(2, '0'); let year = today.getFullYear(); let nodeDate = `${day}${month}${year}`; /* time */ let now = new Date(); let hours = String(now.getHours()).padStart(2, '0'); let minutes = String(now.getMinutes()).padStart(2, '0'); let seconds = String(now.getSeconds()).padStart(2, '0'); let dateString = `${hours}:${minutes}:${seconds}`; const inputValue = req.body.inputValue; req.session.inputValue = inputValue; if (!req.session.requests) { req.session.requests = []; } req.session.requests.push(inputValue); // #################### Write session data to a file if (!req.session.filedata) { req.session.filedata = []; } let fileDate = nodeDate + '--' + dateString; req.session.filedata.push({ Date: fileDate, Input: inputValue }); fs.writeFile('sessionData_'+nodeDate+'_'+ req.sessionID +'.json', JSON.stringify(req.session.filedata), (err) => { if (err) { console.error(err); // res.send('Error writing session data to file'); console.log("Error writing session data to file") } else { // res.send('Session data has been written to file'); console.log("Session data has been written to file") } }); /* ################### END write session data to file */ res.redirect('/'); } catch (error) { res.status(500).send('An error occurred'); } }); app.listen(PORT, () => { console.log(`Server is running on Port:${PORT}`); });
index.html
Double braces are used to render.
Alternatively, triple braces can also be used to render HTML tags. {{{ . }}}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="robots" content="noindex, nofollow ">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Input Values async using session</title>
<link rel="stylesheet" href="/Css/stylesheet.css" media="all">
</head>
<body>
<form method="post">
<input type="text" name="inputValue">
<button type="submit">Submit</button>
</form>
<h2>Previous Input Values session:</h2>
<ul>
{{#requests}}
<li><strong>YOU:</strong> {{.}}</li>
{{/requests}}
</ul>
<script src="/Js/javascript.js"></script>
</body>
</html>